Changeset 385

Show
Ignore:
Timestamp:
02/01/07 15:02:24 (17 years ago)
Author:
pieterpalmers
Message:

- fixed issues with SYT timestamp processing
- SYT based sync works if syncing to the received stream

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/streaming-rework/src/debugmodule/debugmodule.cpp

    r384 r385  
    276276        /* called WITHOUT the mb_write_lock */ 
    277277        while (mb_outbuffer != mb_inbuffer) { 
    278                 fputs(mb_buffers[mb_outbuffer], stdout); 
     278                fputs(mb_buffers[mb_outbuffer], stderr); 
    279279                mb_outbuffer = MB_NEXT(mb_outbuffer); 
    280280        } 
  • branches/streaming-rework/src/libstreaming/AmdtpStreamProcessor.cpp

    r384 r385  
    3838#define RECEIVE_DLL_INTEGRATION_COEFFICIENT 0.015 
    3939 
    40 #define RECEIVE_PROCESSING_DELAY 51200 
     40#define RECEIVE_PROCESSING_DELAY (10000) 
    4141 
    4242// in ticks 
    43 #define TRANSMIT_TRANSFER_DELAY 1000 
    44 #define TRANSMIT_ADVANCE_CYCLES 10 
    45  
    46 //#define DO_SYT_SYNC 
     43#define TRANSMIT_TRANSFER_DELAY 9000U 
     44// the number of cycles to send a packet in advance of it's timestamp 
     45#define TRANSMIT_ADVANCE_CYCLES 1U 
    4746 
    4847namespace FreebobStreaming { 
     
    117116    packet->fmt = IEC61883_FMT_AMDTP; 
    118117 
    119     // signal that we are running (a transmit stream is always 'runnable') 
    120     m_running=true; 
    121      
    122     // we calculate the timestamp of the next sample in the buffer, which will  
    123     // allow us to check if we are to send this sample now, or later 
    124      
    125     // FIXME: maybe we should use the buffer head timestamp for this? 
    126      
     118    // recalculate the buffer head timestamp 
    127119    float ticks_per_frame=m_SyncSource->getTicksPerFrame(); 
    128120     
    129121    // the base timestamp is the one of the last sample in the buffer 
    130     int64_t timestamp = m_buffer_tail_timestamp; 
    131      
     122    uint64_t ts_tail; 
     123    uint64_t fc; 
     124     
     125    getBufferTailTimestamp(&ts_tail, &fc); // thread safe 
     126     
     127    int64_t timestamp = ts_tail; 
    132128     
    133129    // meaning that the first sample in the buffer lies m_framecounter * rate 
    134     // earlier. This would give the next equation: 
     130    // earlier. This gives the next equation: 
    135131    //   timestamp = m_last_timestamp - m_framecounter * rate 
    136     // but to preserve causality, we have to make sure that this timestamp is  
    137     // always bigger than m_last_timestamp. this can be done by adding 
    138     // m_ringbuffersize_frames * rate. 
    139     timestamp += (int64_t)((((int64_t)m_ringbuffer_size_frames)  
    140                                    - ((int64_t)m_framecounter))  
    141                           * ticks_per_frame); 
     132    timestamp -= (int64_t)((float)fc * ticks_per_frame); 
     133     
     134    // FIXME: test 
     135    // substract the receive transfer delay 
     136    timestamp -= RECEIVE_PROCESSING_DELAY; 
    142137     
    143138    // this happens if m_buffer_tail_timestamp wraps around while there are  
     
    158153     
    159154    // determine if we want to send a packet or not 
    160     uint64_t cycle_timer=m_handler->getCycleTimerTicks(); 
    161      
    162     int64_t until_next=timestamp-cycle_timer; 
     155    // note that we can't use getCycleTimer directly here, 
     156    // because packets are queued in advance. This means that 
     157    // we the packet we are constructing will be sent out  
     158    // on 'cycle', not 'now'. 
     159    unsigned int ctr=m_handler->getCycleTimer(); 
     160    int now_cycles = (int)CYCLE_TIMER_GET_CYCLES(ctr); 
     161     
     162    // the difference between 'now' and the cycle this 
     163    // packet is intended for 
     164    int cycle_diff = cycle - now_cycles; 
     165     
     166    // detect wraparounds 
     167    if(cycle_diff < -(int)(CYCLES_PER_SECOND/2)) { 
     168        cycle_diff += CYCLES_PER_SECOND; 
     169    } else if(cycle_diff > (int)(CYCLES_PER_SECOND/2)) { 
     170        cycle_diff -= CYCLES_PER_SECOND; 
     171    } 
     172 
     173    // as long as the cycle parameter is not in sync with 
     174    // the current time, the stream is considered not 
     175    // to be 'running' 
     176    if(cycle_diff < 0 || cycle == -1) { 
     177        m_running=false; 
     178    } else { 
     179        m_running=true; 
     180    } 
     181     
     182#ifdef DEBUG 
     183    if(cycle_diff < 0) { 
     184        debugWarning("Requesting packet for cycle %04d which is in the past (now=%04dcy)\n", 
     185            cycle, now_cycles); 
     186    } 
     187#endif 
     188    // if cycle lies cycle_diff cycles in the future, we should 
     189    // queue this packet cycle_diff * TICKS_PER_CYCLE earlier than 
     190    // we would if it were to be sent immediately. 
     191     
     192    // determine the 'now' time in ticks 
     193    uint64_t cycle_timer=CYCLE_TIMER_TO_TICKS(ctr); 
     194     
     195    // time until the packet is to be sent (if > 0: send packet) 
     196    int64_t until_next=timestamp-(int64_t)cycle_timer; 
     197     
     198    int64_t utn2=until_next; // debug!! 
    163199     
    164200    // we send a packet some cycles in advance, to avoid the 
    165201    // following situation: 
    166202    // suppose we are only a few ticks away from  
    167     // the moment to send this packet. This means that in 
    168     // order to keep causality, we have to make sure that 
    169     // the TRANSFER_DELAY is bigger than one cycle, which 
    170     // might be a little much. 
    171     // this means that we need one cycle of extra buffering. 
     203    // the moment to send this packet. therefore we decide 
     204    // not to send the packet, but send it in the next cycle. 
     205    // This means that the next time point will be 3072 ticks 
     206    // later, making that the timestamp will be expired when the  
     207    // packet is sent, unless TRANSFER_DELAY > 3072. 
     208    // this means that we need at least one cycle of extra buffering. 
    172209    until_next -= TICKS_PER_CYCLE * TRANSMIT_ADVANCE_CYCLES; 
    173210     
     211    // we have to queue it cycle_diff * TICKS_PER_CYCLE earlier 
     212    until_next -= cycle_diff * TICKS_PER_CYCLE; 
     213 
    174214    // the maximal difference we can allow (64secs) 
    175215    const int64_t max=TICKS_PER_SECOND*64L; 
    176      
     216 
     217#ifdef DEBUG 
    177218    if(!m_disabled) { 
    178         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "=> TS=%11llu, CTR=%11llu, FC=%5d, TPS=%10.6f, UTN=%11lld\n", 
    179             timestamp, cycle_timer, m_framecounter, ticks_per_frame, until_next 
     219        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "=> TS=%11llu, CTR=%11llu, FC=%5d\n", 
     220            timestamp, cycle_timer, fc 
    180221            ); 
    181     } 
     222        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "    UTN=%11lld, UTN2=%11lld\n", 
     223            until_next, utn2 
     224            ); 
     225        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "    CY_NOW=%04d, CY_TARGET=%04d, CY_DIFF=%04lld\n", 
     226            now_cycles, cycle, cycle_diff 
     227            ); 
     228    } 
     229#endif 
    182230 
    183231    if(until_next > max) { 
     
    194242        until_next += TICKS_PER_SECOND*128L; 
    195243    } 
    196      
     244 
     245#ifdef DEBUG 
    197246    if(!m_disabled) { 
    198         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "   TS=%11llu, CTR=%11llu, FC=%5d, TPS=%10.6f, UTN=%11lld\n", 
    199             timestamp, cycle_timer, m_framecounter, ticks_per_frame, until_next 
     247        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " > TS=%11llu, CTR=%11llu, FC=%5d\n", 
     248            timestamp, cycle_timer, fc 
    200249            ); 
    201     } 
    202      
    203     // don't process the stream when it is not enabled, 
     250        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "    UTN=%11lld, UTN2=%11lld\n", 
     251            until_next, utn2 
     252            ); 
     253    } 
     254#endif 
     255 
     256    // don't process the stream when it is not enabled, not running 
    204257    // or when the next sample is not due yet. 
    205258     
     
    207260    // that means that we'll send NODATA packets. 
    208261    // we don't add payload because DICE devices don't like that. 
    209     if((until_next>0) || m_disabled) { 
     262    if((until_next>0) || m_disabled || !m_running) { 
    210263        // no-data packets have syt=0xFFFF 
    211264        // and have the usual amount of events as dummy data (?) 
     
    224277        *tag = IEC61883_TAG_WITH_CIP; 
    225278        *sy = 0; 
    226  
     279         
     280        if(m_disabled) { 
     281            // indicate that we are now in a disabled state. 
     282            m_is_disabled=true; 
     283        } else { 
     284            // indicate that we are now in an enabled state. 
     285            m_is_disabled=false; 
     286        } 
     287         
    227288        return RAW1394_ISO_DEFER; 
    228289    } 
    229290     
     291    // indicate that we are now in an enabled state. 
     292    m_is_disabled=false; 
     293             
    230294    // construct the packet 
    231295    nevents = m_syt_interval; 
     
    245309 
    246310        debugWarning("Transmit buffer underrun (cycle %d, FC=%d, PC=%d)\n",  
    247                  cycle, m_framecounter, m_handler->getPacketCount()); 
     311                 cycle, getFrameCounter(), m_handler->getPacketCount()); 
     312 
     313        nevents=0; 
    248314 
    249315        // TODO: we have to be a little smarter here 
     
    257323        packet->fdf = IEC61883_FDF_NODATA; 
    258324        packet->syt = 0xffff; 
    259          
     325 
    260326        // this means no-data packets with payload (DICE doesn't like that) 
    261327        *length = 2*sizeof(quadlet_t) + m_syt_interval * m_dimension * sizeof(quadlet_t); 
     
    277343 
    278344        // convert the timestamp to SYT format 
    279         unsigned int timestamp_SYT = TICKS_TO_SYT(timestamp); 
     345        uint64_t ts=timestamp + TRANSMIT_TRANSFER_DELAY; 
     346         
     347        // check if it wrapped 
     348        if (ts >= TICKS_PER_SECOND * 128L) { 
     349            ts -= TICKS_PER_SECOND * 128L; 
     350        } 
     351         
     352        unsigned int timestamp_SYT = TICKS_TO_SYT(ts); 
    280353        packet->syt = ntohs(timestamp_SYT); 
    281354 
     
    284357     
    285358    // calculate the new buffer head timestamp. this is 
    286     // the timestamp of the current packet plus 
    287     // SYT_INTERVAL * rate 
    288       
    289     timestamp += (int64_t)((float)m_syt_interval * ticks_per_frame ); 
     359    // the previous buffer head timestamp plus 
     360    // the number of frames sent * ticks_per_frame 
     361    timestamp += (int64_t)((float)nevents * ticks_per_frame ); 
    290362     
    291363    // check if it wrapped 
     
    336408    uint64_t ts; 
    337409    uint64_t fc; 
    338     m_SyncSource->getBufferHeadTimestamp(&ts, &fc); 
     410    m_SyncSource->getBufferHeadTimestamp(&ts, &fc); // thread safe 
    339411 
    340412    // update the frame counter such that it reflects the buffer content, 
     
    440512     
    441513    // add the receive processing delay 
    442     m_ringbuffer_size_frames+=(uint)(RECEIVE_PROCESSING_DELAY/m_ticks_per_frame); 
     514//     m_ringbuffer_size_frames+=(uint)(RECEIVE_PROCESSING_DELAY/m_ticks_per_frame); 
    443515     
    444516    if( !(m_event_buffer=freebob_ringbuffer_create( 
     
    583655    uint64_t fc; 
    584656     
    585     m_SyncSource->getBufferHeadTimestamp(&ts, &fc); 
    586  
    587     setBufferTailTimestamp(ts); 
    588      
     657    debugOutput(DEBUG_LEVEL_VERBOSE,"Preparing to enable...\n"); 
     658     
     659    m_SyncSource->getBufferHeadTimestamp(&ts, &fc); // thread safe 
     660     
     661    // recalculate the buffer head timestamp 
     662    float ticks_per_frame=m_SyncSource->getTicksPerFrame(); 
     663     
     664    // set buffer head timestamp 
     665    // this makes that the next sample to be sent out 
     666    // has the same timestamp as the last one received 
     667    // plus one frame 
     668    ts += (uint64_t)ticks_per_frame; 
     669    setBufferHeadTimestamp(ts); 
     670    int64_t timestamp = ts; 
     671 
     672    // since we have a full buffer, we know that the buffer tail lies 
     673    // m_ringbuffer_size_frames * rate earlier 
     674    timestamp += (int64_t)((float)m_ringbuffer_size_frames * ticks_per_frame); 
     675     
     676    // this happens when the last timestamp is near wrapping, and  
     677    // m_framecounter is low. 
     678    // this means: m_last_timestamp is near wrapping and have just had 
     679    // a getPackets() from the client side. the projected next_period 
     680    // boundary lies beyond the wrap value. 
     681    // the action is to wrap the value. 
     682    if (timestamp >= TICKS_PER_SECOND * 128L) { 
     683        timestamp -= TICKS_PER_SECOND * 128L; 
     684    } 
     685 
     686    StreamProcessor::setBufferTailTimestamp(timestamp); 
     687     
     688    debugOutput(DEBUG_LEVEL_VERBOSE,"TS=%10lld, TSTMP=%10llu, %f\n", 
     689                    ts, timestamp, ticks_per_frame); 
     690     
     691    if (!StreamProcessor::prepareForEnable()) { 
     692        debugError("StreamProcessor::prepareForEnable failed\n"); 
     693        return false; 
     694    } 
     695 
    589696    return true; 
    590697} 
     
    617724    int xrun; 
    618725    unsigned int offset=0; 
     726     
     727    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "AmdtpTransmitStreamProcessor::putFrames(%d, %llu)\n",nbframes, ts); 
    619728     
    620729    freebob_ringbuffer_data_t vec[2]; 
     
    700809 
    701810    } 
     811     
     812    // recalculate the buffer tail timestamp 
     813    float ticks_per_frame=m_SyncSource->getTicksPerFrame(); 
     814     
     815    // this makes that the last sample to be sent out on ISO 
     816    // has the same timestamp as the last one transfered 
     817    // to the client 
     818    // plus one frame 
     819    ts += (uint64_t)ticks_per_frame; 
     820    int64_t timestamp = ts; 
     821     
     822    // however we have to preserve causality, meaning that we have to make 
     823    // sure that the worst-case buffer head timestamp still lies in the future. 
     824    // this worst case timestamp occurs when the xmit buffer is completely full. 
     825    // therefore we add m_ringbuffer_size_frames * ticks_per_frame to the timestamp. 
     826    // this will make sure that the buffer head timestamp lies in the future. 
     827    // the netto effect of this is that the system works as if the buffer processing 
     828    // by the client doesn't take time. 
     829     
     830    timestamp += (int64_t)((float)m_ringbuffer_size_frames * ticks_per_frame); 
     831     
     832    // wrap the timestamp if nescessary 
     833    if (timestamp >= TICKS_PER_SECOND * 128L) { 
     834        timestamp -= TICKS_PER_SECOND * 128L; 
     835    } 
     836 
     837    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "StreamProcessor::putFrames(%d, %llu)\n",nbframes, timestamp); 
    702838 
    703839    // update the frame counter such that it reflects the new value, 
    704840    // and also update the buffer tail timestamp 
    705841    // done in the SP base class 
    706     debugOutput(DEBUG_LEVEL_VERBOSE, "StreamProcessor::putFrames(%d, %llu)\n",nbframes, ts); 
    707      
    708     if (!StreamProcessor::putFrames(nbframes, ts)) { 
    709         debugError("Could not do StreamProcessor::putFrames(%d, %llu)\n",nbframes, ts); 
     842    if (!StreamProcessor::putFrames(nbframes, timestamp)) { 
     843        debugError("Could not do StreamProcessor::putFrames(%d, %llu)\n",nbframes, timestamp); 
    710844        return false; 
    711845    } 
     
    10291163        m_last_timestamp += CYCLE_TIMER_GET_OFFSET(syt_timestamp); 
    10301164        m_last_timestamp += cc_seconds * TICKS_PER_SECOND; 
     1165         
     1166        // the receive processing delay indicates how much 
     1167        // extra time we need as slack 
     1168        m_last_timestamp += RECEIVE_PROCESSING_DELAY; 
    10311169 
    10321170        //=> now estimate the device frame rate 
     
    10831221        //=> don't process the stream samples when it is not enabled. 
    10841222        if(m_disabled) { 
     1223 
    10851224            // we keep track of the timestamp here 
    10861225            // this makes sure that we will have a somewhat accurate 
     
    10911230            // SYT_INTERVAL * rate later 
    10921231            uint64_t ts=m_last_timestamp+(uint64_t)((float)m_syt_interval * m_ticks_per_frame); 
     1232             
     1233            // wrap if nescessary 
     1234            if (ts >= TICKS_PER_SECOND * 128L) { 
     1235                ts -= TICKS_PER_SECOND * 128L; 
     1236            } 
     1237            // set the timestamps 
    10931238            StreamProcessor::setBufferTimestamps(ts,ts); 
     1239             
     1240            // indicate that we are now in a disabled state. 
     1241            m_is_disabled=true; 
    10941242             
    10951243            return RAW1394_ISO_DEFER; 
    10961244        } 
     1245         
     1246        // indicate that we are now in an enabled state. 
     1247        m_is_disabled=false; 
    10971248         
    10981249        //=> process the packet 
     
    11031254        { 
    11041255            debugWarning("Receive buffer overrun (cycle %d, FC=%d, PC=%d)\n",  
    1105                  cycle, m_framecounter, m_handler->getPacketCount()); 
     1256                 cycle, getFrameCounter(), m_handler->getPacketCount()); 
    11061257             
    11071258            m_xruns++; 
     
    12241375    // currently this is in ticks 
    12251376     
     1377    int64_t fc=getFrameCounter(); 
     1378     
    12261379    int64_t next_period_boundary =  m_last_timestamp; 
    1227     next_period_boundary     += (int64_t)(((int64_t)m_period-(int64_t)m_framecounter) * m_ticks_per_frame); 
    1228     next_period_boundary     += RECEIVE_PROCESSING_DELAY; 
     1380    next_period_boundary     += (int64_t)(((int64_t)m_period 
     1381                                          - fc) * m_ticks_per_frame); 
     1382//     next_period_boundary     += RECEIVE_PROCESSING_DELAY; 
    12291383     
    12301384    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "=> NPD=%11lld, LTS=%11llu, FC=%5d, TPF=%f\n", 
    1231         next_period_boundary, m_last_timestamp, m_framecounter, m_ticks_per_frame 
     1385        next_period_boundary, m_last_timestamp, fc, m_ticks_per_frame 
    12321386        ); 
    12331387     
     
    12491403     
    12501404    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "   NPD=%11lld, LTS=%11llu, FC=%5d, TPF=%f\n", 
    1251         next_period_boundary, m_last_timestamp, m_framecounter, m_ticks_per_frame 
     1405        next_period_boundary, m_last_timestamp, fc, m_ticks_per_frame 
    12521406        ); 
    12531407 
     
    12831437    m_WakeupStat.reset(); 
    12841438     
    1285     m_ticks_per_frame = (TICKS_PER_SECOND*1.0) / ((float)m_framerate); 
     1439//     m_ticks_per_frame = (TICKS_PER_SECOND*1.0) / ((float)m_framerate); 
    12861440 
    12871441    // reset all non-device specific stuff 
     
    15541708     
    15551709    if (!StreamProcessor::getFrames(nbframes, ts)) { 
    1556         debugError("Could not do StreamProcessor::getFrames(%d, %llu)\n",nbframes, ts); 
     1710        debugError("Could not do StreamProcessor::getFrames(%d, %llu)\n", nbframes, ts); 
    15571711        return false; 
    15581712    } 
  • branches/streaming-rework/src/libstreaming/cycletimer.h

    r384 r385  
    3838#define TICKS_PER_CYCLE     3072U 
    3939#define TICKS_PER_SECOND    24576000UL 
    40 #define TICKS_PER_USEC     (TICKS_PER_SECOND/1000000.0) 
     40#define TICKS_PER_USEC     (24.576000) 
    4141 
    4242#define USECS_PER_TICK     (1.0/TICKS_PER_USEC) 
     43#define USECS_PER_CYCLE    (125U) 
    4344 
    4445#define CYCLE_TIMER_GET_SECS(x)   ((((x) & 0xFE000000U) >> 25)) 
  • branches/streaming-rework/src/libstreaming/freebob_streaming.cpp

    r384 r385  
    119119        // discover the devices on the bus 
    120120        if(!dev->m_deviceManager->discover(DEBUG_LEVEL_NORMAL)) { 
    121                 debugOutput(DEBUG_LEVEL_VERBOSE, "Could not discover devices\n"); 
     121                debugFatal("Could not discover devices\n"); 
    122122                delete dev->processorManager; 
    123123                delete dev->m_deviceManager; 
     
    132132            assert(device); 
    133133 
     134            debugOutput(DEBUG_LEVEL_VERBOSE, "Setting samplerate to %d for (%p)\n",  
     135                        dev->options.sample_rate, device); 
    134136            // Set the device's sampling rate to that requested 
    135137            // FIXME: does this really belong here?  If so we need to handle errors. 
    136138            if (!device->setSamplingFrequency(parseSampleRate(dev->options.sample_rate))) { 
     139                debugOutput(DEBUG_LEVEL_VERBOSE, " => Retry setting samplerate to %d for (%p)\n",  
     140                            dev->options.sample_rate, device); 
     141             
    137142                // try again: 
    138143                if (!device->setSamplingFrequency(parseSampleRate(dev->options.sample_rate))) { 
     
    252257        periods++; 
    253258        if(periods>periods_print) { 
    254                 debugOutput(DEBUG_LEVEL_VERBOSE, "\n"); 
    255                 debugOutput(DEBUG_LEVEL_VERBOSE, "============================================\n"); 
    256                 debugOutput(DEBUG_LEVEL_VERBOSE, "Xruns: %d\n",xruns); 
    257                 debugOutput(DEBUG_LEVEL_VERBOSE, "============================================\n"); 
     259                debugOutputShort(DEBUG_LEVEL_VERBOSE, "\nfreebob_streaming_wait\n"); 
     260                debugOutputShort(DEBUG_LEVEL_VERBOSE, "============================================\n"); 
     261                debugOutputShort(DEBUG_LEVEL_VERBOSE, "Xruns: %d\n",xruns); 
     262                debugOutputShort(DEBUG_LEVEL_VERBOSE, "============================================\n"); 
    258263                dev->processorManager->dumpInfo(); 
    259                 debugOutput(DEBUG_LEVEL_VERBOSE, "\n"); 
     264                debugOutputShort(DEBUG_LEVEL_VERBOSE, "\n"); 
    260265                periods_print+=100; 
    261266        } 
  • branches/streaming-rework/src/libstreaming/IsoHandler.cpp

    r384 r385  
    877877    debugOutput( DEBUG_LEVEL_VERBOSE, " Irq interval    : %d \n",m_irq_interval); 
    878878 
    879     if(raw1394_iso_recv_init(m_handle,    
    880                              iso_receive_handler, 
    881                              m_buf_packets, 
    882                              m_max_packet_size, 
    883                              m_Client->getChannel(), 
    884                              RAW1394_DMA_BUFFERFILL, 
    885                              m_irq_interval)) { 
    886         debugFatal("Could not do receive initialisation!\n" ); 
    887         debugFatal("  %s\n",strerror(errno)); 
    888  
    889         return false; 
     879    if(m_irq_interval > 1) { 
     880        if(raw1394_iso_recv_init(m_handle,    
     881                                iso_receive_handler, 
     882                                m_buf_packets, 
     883                                m_max_packet_size, 
     884                                m_Client->getChannel(), 
     885                                RAW1394_DMA_BUFFERFILL, 
     886                                m_irq_interval)) { 
     887            debugFatal("Could not do receive initialisation!\n" ); 
     888            debugFatal("  %s\n",strerror(errno)); 
     889     
     890            return false; 
     891        } 
     892    } else { 
     893        if(raw1394_iso_recv_init(m_handle,    
     894                                iso_receive_handler, 
     895                                m_buf_packets, 
     896                                m_max_packet_size, 
     897                                m_Client->getChannel(), 
     898                                RAW1394_DMA_PACKET_PER_BUFFER, 
     899                                m_irq_interval)) { 
     900            debugFatal("Could not do receive initialisation!\n" ); 
     901            debugFatal("  %s\n",strerror(errno)); 
     902     
     903            return false; 
     904        }     
    890905    } 
    891906    return true; 
  • branches/streaming-rework/src/libstreaming/IsoHandlerManager.cpp

    r384 r385  
    3131#include "IsoStream.h" 
    3232#include <assert.h> 
     33 
     34#define MINIMUM_INTERRUPTS_PER_PERIOD  4U 
     35#define PACKETS_PER_INTERRUPT          4U 
    3336 
    3437namespace FreebobStreaming 
     
    285288                unsigned int packets_per_period=stream->getPacketsPerPeriod(); 
    286289                 
     290#if 0 
    287291                // hardware interrupts occur when one DMA block is full, and the size of one DMA 
    288292                // block = PAGE_SIZE. Setting the max_packet_size makes sure that the HW irq is  
    289293                // occurs at a period boundary (optimal CPU use) 
    290294                 
    291                 // NOTE: try and use 4 hardware interrupts per period for better latency. 
    292                 unsigned int max_packet_size=4 * getpagesize() / packets_per_period; 
     295                // NOTE: try and use MINIMUM_INTERRUPTS_PER_PERIOD hardware interrupts 
     296                //       per period for better latency. 
     297                unsigned int max_packet_size=MINIMUM_INTERRUPTS_PER_PERIOD * getpagesize() / packets_per_period; 
    293298                if (max_packet_size < stream->getMaxPacketSize()) { 
    294299                        max_packet_size=stream->getMaxPacketSize(); 
     
    300305                        max_packet_size = getpagesize(); 
    301306 
    302                 int irq_interval=packets_per_period / 4; 
    303         if(irq_interval <= 0) irq_interval=1; 
    304  
    305                 /* the receive buffer size doesn't matter for the latency, 
    306                    but it has a minimal value in order for libraw to operate correctly (300) */ 
    307                 int buffers=400; 
    308                  
    309                 // create the actual handler 
    310                 IsoRecvHandler *h = new IsoRecvHandler(stream->getPort(), buffers, 
    311                                                        max_packet_size, irq_interval); 
    312  
    313                 debugOutput( DEBUG_LEVEL_VERBOSE, " registering IsoRecvHandler\n"); 
    314  
    315                 if(!h) { 
    316                         debugFatal("Could not create IsoRecvHandler\n"); 
    317                         return false; 
    318                 } 
    319  
    320                 h->setVerboseLevel(getDebugLevel()); 
    321  
    322                 // init the handler 
    323                 if(!h->init()) { 
    324                         debugFatal("Could not initialize receive handler\n"); 
    325                         return false; 
    326                 } 
    327  
    328                 // register the stream with the handler 
    329                 if(!h->registerStream(stream)) { 
    330                         debugFatal("Could not register receive stream with handler\n"); 
    331                         return false; 
    332                 } 
    333  
    334                 // register the handler with the manager 
    335                 if(!registerHandler(h)) { 
    336                         debugFatal("Could not register receive handler with manager\n"); 
    337                         return false; 
    338                 } 
    339                 debugOutput( DEBUG_LEVEL_VERBOSE, " registered stream (%p) with handler (%p)\n",stream,h); 
    340         } 
    341          
    342         if (stream->getType()==IsoStream::EST_Transmit) { 
    343          
    344                 // setup the optimal parameters for the raw1394 ISO buffering 
    345                 unsigned int packets_per_period=stream->getPacketsPerPeriod(); 
     307                unsigned int irq_interval=packets_per_period / MINIMUM_INTERRUPTS_PER_PERIOD; 
     308                if(irq_interval <= 0) irq_interval=1; 
     309#else 
    346310                // hardware interrupts occur when one DMA block is full, and the size of one DMA 
    347                 // block = PAGE_SIZE. Setting the max_packet_size makes sure that the HW irq   
    348                 // occurs at a period boundary (optimal CPU use) 
    349                 // NOTE: try and use 4 interrupts per period for better latency. 
    350                 unsigned int max_packet_size=4 * getpagesize() / packets_per_period; 
     311                // block = PAGE_SIZE. Setting the max_packet_size enables control over the IRQ 
     312                // frequency, as the controller uses max_packet_size, and not the effective size 
     313                // when writing to the DMA buffer. 
     314                 
     315                // configure it such that we have an irq for every PACKETS_PER_INTERRUPT packets 
     316                unsigned int irq_interval=PACKETS_PER_INTERRUPT; 
     317                 
     318                // unless the period size doesn't allow this 
     319                if ((packets_per_period/MINIMUM_INTERRUPTS_PER_PERIOD) < irq_interval) { 
     320                        irq_interval=1; 
     321                } 
     322                 
     323                // FIXME: test 
     324                irq_interval=1; 
     325                 
     326                unsigned int max_packet_size=getpagesize() / irq_interval; 
     327 
    351328                if (max_packet_size < stream->getMaxPacketSize()) { 
    352329                        max_packet_size=stream->getMaxPacketSize(); 
     
    358335                        max_packet_size = getpagesize(); 
    359336 
    360                 int irq_interval=packets_per_period / 4; 
     337#endif 
     338                /* the receive buffer size doesn't matter for the latency, 
     339                   but it has a minimal value in order for libraw to operate correctly (300) */ 
     340                int buffers=400; 
     341                 
     342                // create the actual handler 
     343                IsoRecvHandler *h = new IsoRecvHandler(stream->getPort(), buffers, 
     344                                                       max_packet_size, irq_interval); 
     345 
     346                debugOutput( DEBUG_LEVEL_VERBOSE, " registering IsoRecvHandler\n"); 
     347 
     348                if(!h) { 
     349                        debugFatal("Could not create IsoRecvHandler\n"); 
     350                        return false; 
     351                } 
     352 
     353                h->setVerboseLevel(getDebugLevel()); 
     354 
     355                // init the handler 
     356                if(!h->init()) { 
     357                        debugFatal("Could not initialize receive handler\n"); 
     358                        return false; 
     359                } 
     360 
     361                // register the stream with the handler 
     362                if(!h->registerStream(stream)) { 
     363                        debugFatal("Could not register receive stream with handler\n"); 
     364                        return false; 
     365                } 
     366 
     367                // register the handler with the manager 
     368                if(!registerHandler(h)) { 
     369                        debugFatal("Could not register receive handler with manager\n"); 
     370                        return false; 
     371                } 
     372                debugOutput( DEBUG_LEVEL_VERBOSE, " registered stream (%p) with handler (%p)\n",stream,h); 
     373        } 
     374         
     375        if (stream->getType()==IsoStream::EST_Transmit) { 
     376                // setup the optimal parameters for the raw1394 ISO buffering 
     377                unsigned int packets_per_period=stream->getPacketsPerPeriod(); 
     378 
     379#if 0 
     380                // hardware interrupts occur when one DMA block is full, and the size of one DMA 
     381                // block = PAGE_SIZE. Setting the max_packet_size makes sure that the HW irq   
     382                // occurs at a period boundary (optimal CPU use) 
     383                // NOTE: try and use MINIMUM_INTERRUPTS_PER_PERIOD interrupts per period 
     384                //       for better latency. 
     385                unsigned int max_packet_size=MINIMUM_INTERRUPTS_PER_PERIOD * getpagesize() / packets_per_period; 
     386                if (max_packet_size < stream->getMaxPacketSize()) { 
     387                        max_packet_size=stream->getMaxPacketSize(); 
     388                } 
     389 
     390                // Ensure we don't request a packet size bigger than the 
     391                // kernel-enforced maximum which is currently 1 page. 
     392                if (max_packet_size > (unsigned int)getpagesize()) 
     393                        max_packet_size = getpagesize(); 
     394 
     395                unsigned int irq_interval=packets_per_period / MINIMUM_INTERRUPTS_PER_PERIOD; 
    361396                if(irq_interval <= 0) irq_interval=1; 
    362          
     397#else 
     398                // hardware interrupts occur when one DMA block is full, and the size of one DMA 
     399                // block = PAGE_SIZE. Setting the max_packet_size enables control over the IRQ 
     400                // frequency, as the controller uses max_packet_size, and not the effective size 
     401                // when writing to the DMA buffer. 
     402                 
     403                // configure it such that we have an irq for every PACKETS_PER_INTERRUPT packets 
     404                unsigned int irq_interval=PACKETS_PER_INTERRUPT; 
     405                 
     406                // unless the period size doesn't allow this 
     407                if ((packets_per_period/MINIMUM_INTERRUPTS_PER_PERIOD) < irq_interval) { 
     408                        irq_interval=1; 
     409                } 
     410                 
     411                // FIXME: test 
     412                irq_interval=1; 
     413 
     414                unsigned int max_packet_size=getpagesize() / irq_interval; 
     415 
     416                if (max_packet_size < stream->getMaxPacketSize()) { 
     417                        max_packet_size=stream->getMaxPacketSize(); 
     418                } 
     419 
     420                // Ensure we don't request a packet size bigger than the 
     421                // kernel-enforced maximum which is currently 1 page. 
     422                if (max_packet_size > (unsigned int)getpagesize()) 
     423                        max_packet_size = getpagesize(); 
     424#endif 
    363425                // the transmit buffer size should be as low as possible for latency.  
    364426                // note however that the raw1394 subsystem tries to keep this buffer 
    365427                // full, so we have to make sure that we have enough events in our 
    366428                // event buffers 
    367                 int buffers=packets_per_period; 
     429                 
     430                // every irq_interval packets an interrupt will occur. that is when 
     431                // buffers get transfered, meaning that we should have at least some 
     432                // margin here 
     433//              int buffers=irq_interval * 2; 
     434 
     435                // half a period. the xmit handler will take care of this 
     436                int buffers=packets_per_period/2; 
    368437                 
    369438                // NOTE: this is dangerous: what if there is not enough prefill? 
  • branches/streaming-rework/src/libstreaming/StreamProcessor.cpp

    r384 r385  
    3535namespace FreebobStreaming { 
    3636 
    37 IMPL_DEBUG_MODULE( StreamProcessor, StreamProcessor, DEBUG_LEVEL_NORMAL ); 
    38 IMPL_DEBUG_MODULE( ReceiveStreamProcessor, ReceiveStreamProcessor, DEBUG_LEVEL_NORMAL ); 
    39 IMPL_DEBUG_MODULE( TransmitStreamProcessor, TransmitStreamProcessor, DEBUG_LEVEL_NORMAL ); 
     37IMPL_DEBUG_MODULE( StreamProcessor, StreamProcessor, DEBUG_LEVEL_VERBOSE ); 
     38IMPL_DEBUG_MODULE( ReceiveStreamProcessor, ReceiveStreamProcessor, DEBUG_LEVEL_VERBOSE ); 
     39IMPL_DEBUG_MODULE( TransmitStreamProcessor, TransmitStreamProcessor, DEBUG_LEVEL_VERBOSE ); 
    4040 
    4141StreamProcessor::StreamProcessor(enum IsoStream::EStreamType type, int port, int framerate)  
     
    5151        , m_running(false) 
    5252        , m_disabled(true) 
     53        , m_is_disabled(true) 
    5354{ 
    5455 
     
    6162void StreamProcessor::dumpInfo() 
    6263{ 
     64    int64_t diff=(int64_t)m_buffer_head_timestamp - (int64_t)m_buffer_tail_timestamp; 
    6365 
    6466    debugOutputShort( DEBUG_LEVEL_NORMAL, " StreamProcessor information\n"); 
     
    6668     
    6769    IsoStream::dumpInfo(); 
    68     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Frame counter  : %d\n", m_framecounter); 
    69     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Xruns          : %d\n", m_xruns); 
    70     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Running        : %d\n", m_running); 
    71     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Enabled        : %d\n", !m_disabled); 
     70    debugOutputShort( DEBUG_LEVEL_NORMAL, "  StreamProcessor info:\n"); 
     71    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Frame counter         : %d\n", m_framecounter); 
     72    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Buffer head timestamp : %011llu\n",m_buffer_head_timestamp); 
     73    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Buffer tail timestamp : %011llu\n",m_buffer_tail_timestamp); 
     74    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Head - Tail           : %011lld\n",diff); 
     75    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Now                   : %011u\n",m_handler->getCycleTimerTicks()); 
     76    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Xruns                 : %d\n", m_xruns); 
     77    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Running               : %d\n", m_running); 
     78    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Enabled               : %s\n", m_disabled ? "No" : "Yes"); 
     79    debugOutputShort( DEBUG_LEVEL_NORMAL, "   enable status        : %s\n", m_is_disabled ? "No" : "Yes"); 
    7280     
    7381//     m_PeriodStat.dumpInfo(); 
     
    111119    return true; 
    112120         
     121} 
     122     
     123bool StreamProcessor::prepareForEnable() { 
     124    int64_t diff=(int64_t)m_buffer_head_timestamp - (int64_t)m_buffer_tail_timestamp; 
     125     
     126    debugOutput(DEBUG_LEVEL_VERBOSE," StreamProcessor::prepareForEnable for (%p)\n",this); 
     127    debugOutput(DEBUG_LEVEL_VERBOSE," Frame Counter         : %05d\n",m_framecounter); 
     128    debugOutput(DEBUG_LEVEL_VERBOSE," Buffer head timestamp : %011llu\n",m_buffer_head_timestamp); 
     129    debugOutput(DEBUG_LEVEL_VERBOSE," Buffer tail timestamp : %011llu\n",m_buffer_tail_timestamp); 
     130    debugOutput(DEBUG_LEVEL_VERBOSE," Head - Tail           : %011lld\n",diff); 
     131    debugOutput(DEBUG_LEVEL_VERBOSE," Now                   : %011u\n",m_handler->getCycleTimerTicks()); 
     132    return true; 
     133} 
     134 
     135bool StreamProcessor::prepareForDisable() { 
     136    int64_t diff=(int64_t)m_buffer_head_timestamp - (int64_t)m_buffer_tail_timestamp; 
     137     
     138    debugOutput(DEBUG_LEVEL_VERBOSE," StreamProcessor::prepareForDisable for (%p)\n",this); 
     139    debugOutput(DEBUG_LEVEL_VERBOSE," Frame Counter         : %05d\n",m_framecounter); 
     140    debugOutput(DEBUG_LEVEL_VERBOSE," Buffer head timestamp : %011llu\n",m_buffer_head_timestamp); 
     141    debugOutput(DEBUG_LEVEL_VERBOSE," Buffer tail timestamp : %011llu\n",m_buffer_tail_timestamp); 
     142    debugOutput(DEBUG_LEVEL_VERBOSE," Head - Tail           : %011lld\n",diff); 
     143    debugOutput(DEBUG_LEVEL_VERBOSE," Now                   : %011u\n",m_handler->getCycleTimerTicks()); 
     144    return true; 
     145 
    113146} 
    114147 
     
    172205bool StreamProcessor::getFrames(unsigned int nbframes, int64_t ts) { 
    173206 
    174         debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Getting %d frames from frame buffer...\n", nbframes); 
     207        debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Getting %d frames from frame buffer at (%011lld)...\n", nbframes, ts); 
    175208        decrementFrameCounter(nbframes, ts); 
    176209        return true; 
     
    181214} 
    182215 
    183 void StreamProcessor::enable()  { 
    184         if(!m_running) { 
    185                 debugWarning("The StreamProcessor is not running yet, enable() might not be a good idea.\n"); 
    186         } 
    187         m_disabled=false; 
     216bool StreamProcessor::enable()  { 
     217    int cnt=0; 
     218     
     219    if(!m_running) { 
     220            debugWarning("The StreamProcessor is not running yet, enable() might not be a good idea.\n"); 
     221    } 
     222     
     223    m_disabled=false; 
     224     
     225    // now wait until it is effectively enabled 
     226    // time-out at 100ms 
     227    while(m_is_disabled && cnt++ < 1000) { 
     228        usleep(100); 
     229    } 
     230     
     231    // check if the operation timed out 
     232    if(cnt==1000) { 
     233        debugWarning("Timeout when enabling StreamProcessor (%p)\n",this); 
     234        return false; 
     235    } 
     236     
     237    return true; 
     238
     239 
     240bool StreamProcessor::disable()  { 
     241    int cnt=0; 
     242     
     243    m_disabled=true; 
     244     
     245    // now wait until it is effectively disabled 
     246    // time-out at  
     247    while(!m_is_disabled && cnt++ < 1000) { 
     248        usleep(100); 
     249    } 
     250     
     251    // check if the operation timed out (100ms) 
     252    if(cnt==1000) { 
     253        debugWarning("Timeout when disabling StreamProcessor (%p)\n",this); 
     254        return false; 
     255    } 
     256     
     257    return true; 
     258 
    188259} 
    189260 
     
    195266/** 
    196267 * Decrements the frame counter, in a atomic way. This 
    197  * also sets the buffer tail timestamp 
     268 * also sets the buffer head timestamp 
    198269 * is thread safe. 
    199270 */ 
    200271void StreamProcessor::decrementFrameCounter(int nbframes, uint64_t new_timestamp) { 
     272    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Setting buffer head timestamp for (%p) to %11llu\n", 
     273                this, new_timestamp); 
     274                 
    201275    pthread_mutex_lock(&m_framecounter_lock); 
    202276    m_framecounter -= nbframes; 
     
    207281/** 
    208282 * Increments the frame counter, in a atomic way. 
    209  * also sets the buffer head timestamp 
     283 * also sets the buffer tail timestamp 
    210284 * This is thread safe. 
    211285 */ 
    212286void StreamProcessor::incrementFrameCounter(int nbframes, uint64_t new_timestamp) { 
     287    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Setting buffer tail timestamp for (%p) to %11llu\n", 
     288                this, new_timestamp); 
     289     
    213290    pthread_mutex_lock(&m_framecounter_lock); 
    214291    m_framecounter += nbframes; 
     
    219296 
    220297/** 
    221  * Sets the frame counter, in a atomic way.  
    222  * also sets the buffer head timestamp 
    223  * This is thread safe. 
    224  */ 
    225 void StreamProcessor::setFrameCounter(int new_framecounter, uint64_t new_timestamp) { 
    226     pthread_mutex_lock(&m_framecounter_lock); 
    227     m_framecounter = new_framecounter; 
    228     m_buffer_tail_timestamp = new_timestamp; 
    229     pthread_mutex_unlock(&m_framecounter_lock); 
    230 } 
    231  
    232 /** 
    233298 * Sets the buffer tail timestamp (in usecs) 
    234299 * This is thread safe. 
    235300 */ 
    236301void StreamProcessor::setBufferTailTimestamp(uint64_t new_timestamp) { 
     302    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Setting buffer tail timestamp for (%p) to %11llu\n", 
     303                this, new_timestamp); 
     304     
    237305    pthread_mutex_lock(&m_framecounter_lock); 
    238306    m_buffer_tail_timestamp = new_timestamp; 
     
    245313 */ 
    246314void StreamProcessor::setBufferHeadTimestamp(uint64_t new_timestamp) { 
     315    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Setting buffer head timestamp for (%p) to %11llu\n", 
     316                this, new_timestamp); 
     317 
    247318    pthread_mutex_lock(&m_framecounter_lock); 
    248319    m_buffer_head_timestamp = new_timestamp; 
     
    256327 */ 
    257328void StreamProcessor::setBufferTimestamps(uint64_t new_head, uint64_t new_tail) { 
     329    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Setting buffer head timestamp for (%p) to %11llu\n", 
     330                this, new_head); 
     331    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "    and buffer tail timestamp for (%p) to %11llu\n", 
     332                this, new_tail); 
     333    
    258334    pthread_mutex_lock(&m_framecounter_lock); 
    259335    m_buffer_head_timestamp = new_head; 
  • branches/streaming-rework/src/libstreaming/StreamProcessor.h

    r384 r385  
    8080 
    8181    bool isRunning(); ///< returns true if there is some stream data processed 
    82     void enable(); ///< enable the stream processing  
    83     void disable() {m_disabled=true;}; ///< disable the stream processing  
    84     bool isEnabled() {return !m_disabled;}; 
     82    bool enable(); ///< enable the stream processing  
     83    bool disable(); ///< disable the stream processing  
     84    bool isEnabled() {return !m_is_disabled;}; 
    8585 
    8686    virtual bool putFrames(unsigned int nbframes, int64_t ts); ///< transfer the buffer contents from client 
     
    100100    virtual bool prepareForStart() {return true;}; 
    101101     
    102     virtual bool prepareForEnable() {return true;}
    103     virtual bool prepareForDisable() {return true;}
     102    virtual bool prepareForEnable()
     103    virtual bool prepareForDisable()
    104104 
    105105protected: 
     
    120120    bool m_running; 
    121121    bool m_disabled; 
    122  
     122    bool m_is_disabled; 
     123     
    123124    StreamStatistics m_PacketStat; 
    124125    StreamStatistics m_PeriodStat; 
     
    147148        void decrementFrameCounter(int nbframes, uint64_t new_timestamp); 
    148149        void incrementFrameCounter(int nbframes, uint64_t new_timestamp); 
    149         void setFrameCounter(int new_framecounter, uint64_t new_timestamp); 
    150150        void resetFrameCounter(); 
    151151         
     
    193193        float getTicksPerFrame() {return m_ticks_per_frame;}; 
    194194     
    195     protected
     195    private
    196196        // the framecounter gives the number of frames in the buffer 
    197197        signed int m_framecounter; 
     
    205205        uint64_t   m_buffer_head_timestamp; 
    206206         
    207          
     207    protected: 
    208208        StreamProcessor *m_SyncSource; 
    209209         
  • branches/streaming-rework/src/libstreaming/StreamProcessorManager.cpp

    r384 r385  
    3333#include <assert.h> 
    3434 
     35#include "libstreaming/cycletimer.h" 
     36 
     37#define CYCLES_TO_SLEEP_AFTER_RUN_SIGNAL 50 
    3538 
    3639namespace FreebobStreaming { 
     
    403406        } 
    404407 
     408        // we want to make sure that everything is running well,  
     409        // so wait for a while 
     410        usleep(USECS_PER_CYCLE * CYCLES_TO_SLEEP_AFTER_RUN_SIGNAL); 
     411 
    405412        debugOutput( DEBUG_LEVEL_VERBOSE, "StreamProcessors running...\n"); 
    406         debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting frame counters...\n"); 
     413        debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting counters...\n"); 
    407414         
    408415        // now we reset the frame counters 
     
    411418                ++it ) { 
    412419                 
     420                debugOutput( DEBUG_LEVEL_VERBOSE, "Before:\n"); 
     421                 
    413422                if(getDebugLevel()>=DEBUG_LEVEL_VERBOSE) { 
    414423                        (*it)->dumpInfo(); 
    415424                } 
    416425 
    417                 (*it)->reset(); 
     426                (*it)->reset(); 
     427                 
     428                debugOutput( DEBUG_LEVEL_VERBOSE, "After:\n"); 
    418429 
    419430                if(getDebugLevel()>=DEBUG_LEVEL_VERBOSE) { 
     
    427438                ++it ) { 
    428439                 
     440                debugOutput( DEBUG_LEVEL_VERBOSE, "Before:\n"); 
     441                 
    429442                if(getDebugLevel()>=DEBUG_LEVEL_VERBOSE) { 
    430443                        (*it)->dumpInfo(); 
     
    432445                 
    433446                (*it)->reset(); 
     447                 
     448                debugOutput( DEBUG_LEVEL_VERBOSE, "After:\n"); 
    434449                 
    435450                if(getDebugLevel()>=DEBUG_LEVEL_VERBOSE) { 
     
    666681bool StreamProcessorManager::waitForPeriod() { 
    667682    int time_till_next_period; 
    668      
     683    bool xrun_occurred=false; 
     684        
    669685    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "enter...\n"); 
    670686 
     
    679695        usleep(time_till_next_period); 
    680696         
    681         // check if it is still true 
     697        // check for underruns on the ISO side, 
     698        // those should make us bail out of the wait loop 
     699        for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     700            it != m_ReceiveProcessors.end(); 
     701            ++it ) { 
     702            // a xrun has occurred on the Iso side 
     703            xrun_occurred |= (*it)->xrunOccurred(); 
     704        } 
     705        for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
     706            it != m_TransmitProcessors.end(); 
     707            ++it ) { 
     708            // a xrun has occurred on the Iso side 
     709            xrun_occurred |= (*it)->xrunOccurred(); 
     710        } 
     711 
     712        // check if we were waked up too soon 
    682713        time_till_next_period=m_SyncSource->getTimeUntilNextPeriodUsecs(); 
    683714    } 
    684715     
    685     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "delayed for %d usecs...\n", time_till_next_period); 
     716    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "delayed for %d usecs...\n", -time_till_next_period); 
    686717     
    687718    // this is to notify the client of the delay  
     
    696727    //       and the receive processors should have done their transfer. 
    697728    m_time_of_transfer=m_SyncSource->getTimeAtPeriod(); 
    698     debugOutput( DEBUG_LEVEL_VERBOSE, "transfer at %llu ticks...\n",  
     729    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "transfer at %llu ticks...\n",  
    699730        m_time_of_transfer); 
     731     
     732    xrun_occurred=false; 
    700733     
    701734    // check if xruns occurred on the Iso side. 
    702735    // also check if xruns will occur should we transfer() now 
    703     bool xrun_occurred=false; 
    704736     
    705737    for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     
    741773    } 
    742774     
     775    m_nbperiods++; 
     776     
    743777    // now we can signal the client that we are (should be) ready 
    744778    return !xrun_occurred; 
     
    772806 
    773807bool StreamProcessorManager::transfer(enum StreamProcessor::EProcessorType t) { 
    774     int64_t time_of_transfer; 
    775808    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Transferring period...\n"); 
    776      
    777     // first we should find out on what time this transfer is 
    778     // supposed to be happening. this time will become the time 
    779     // stamp for the transmitted buffer. 
    780     // NOTE: maybe we should include the transfer delay here, that 
    781     //       would make it equal for all types of SP's 
    782     time_of_transfer=m_time_of_transfer; 
    783809     
    784810    // a static cast could make sure that there is no performance 
     
    788814                it != m_ReceiveProcessors.end(); 
    789815                ++it ) { 
    790             uint64_t buffer_tail_ts; 
    791             uint64_t fc; 
    792             int64_t ts; 
    793          
    794             (*it)->getBufferTailTimestamp(&buffer_tail_ts,&fc); 
    795             ts =  buffer_tail_ts; 
    796             ts += (int64_t)((-(int64_t)fc) * m_SyncSource->getTicksPerFrame()); 
    797             // NOTE: ts can be negative due to wraparound, it is the responsability of the  
    798             //       SP to deal with that. 
    799816             
    800             float tmp=m_SyncSource->getTicksPerFrame(); 
    801              
    802             debugOutput(DEBUG_LEVEL_VERBOSE, "=> TS=%11lld, BLT=%11llu, FC=%5d, TPF=%f\n", 
    803                 ts, buffer_tail_ts, fc, tmp 
    804                 ); 
    805             debugOutput(DEBUG_LEVEL_VERBOSE, "   TPF=%f\n", tmp); 
    806               
    807             #ifdef DEBUG 
     817            //#ifdef DEBUG 
     818            #if 0 
    808819            { 
    809820                uint64_t ts_tail=0; 
     
    823834                } 
    824835                 
    825                 debugOutput(DEBUG_LEVEL_VERBOSE,"R *  HEAD: TS=%llu, FC=%llu | TAIL: TS=%llu, FC=%llu, %d\n", 
    826                     ts_tail, fc_tail, ts_head, fc_head, cnt); 
     836                debugOutput(DEBUG_LEVEL_VERBOSE,"R => HEAD: TS=%11llu, FC=%5llu | TAIL: TS=%11llu, FC=%5llu, %d\n", 
     837                    ts_head, fc_head, ts_tail, fc_tail, cnt); 
    827838            } 
    828839            #endif 
    829840     
    830             if(!(*it)->getFrames(m_period, ts)) { 
    831                     debugOutput(DEBUG_LEVEL_VERBOSE,"could not getFrames(%u) from stream processor (%p)", 
    832                             m_period,*it); 
     841            if(!(*it)->getFrames(m_period, (int64_t)m_time_of_transfer)) { 
     842                    debugOutput(DEBUG_LEVEL_VERBOSE,"could not getFrames(%u, %11llu) from stream processor (%p)", 
     843                            m_period, m_time_of_transfer,*it); 
    833844                    return false; // buffer underrun 
    834845            } 
    835846             
    836             #ifdef DEBUG 
     847            //#ifdef DEBUG 
     848            #if 0 
    837849            { 
    838850                uint64_t ts_tail=0; 
     
    852864                } 
    853865                 
    854                 debugOutput(DEBUG_LEVEL_VERBOSE,"R > HEAD: TS=%llu, FC=%llu | TAIL: TS=%llu, FC=%llu, %d\n", 
    855                     ts_tail, fc_tail, ts_head, fc_head, cnt);             
     866                debugOutput(DEBUG_LEVEL_VERBOSE,"R > HEAD: TS=%11llu, FC=%5llu | TAIL: TS=%11llu, FC=%5llu, %d\n", 
     867                    ts_head, fc_head, ts_tail, fc_tail, cnt); 
    856868            } 
    857869            #endif 
     
    863875                ++it ) { 
    864876                 
    865             #ifdef DEBUG 
     877            //#ifdef DEBUG 
     878            #if 0 
    866879            { 
    867880                uint64_t ts_tail=0; 
     
    881894                } 
    882895                 
    883                 debugOutput(DEBUG_LEVEL_VERBOSE,"T *  HEAD: TS=%llu, FC=%llu | TAIL: TS=%llu, FC=%llu, %d\n", 
    884                     ts_tail, fc_tail, ts_head, fc_head, cnt); 
     896                debugOutput(DEBUG_LEVEL_VERBOSE,"T => HEAD: TS=%11llu, FC=%5llu | TAIL: TS=%11llu, FC=%5llu, %d\n", 
     897                    ts_head, fc_head, ts_tail, fc_tail, cnt); 
    885898            } 
    886899            #endif 
    887900                 
    888             if(!(*it)->putFrames(m_period,time_of_transfer)) { 
     901            if(!(*it)->putFrames(m_period, (int64_t)m_time_of_transfer)) { 
    889902                debugOutput(DEBUG_LEVEL_VERBOSE, "could not putFrames(%u,%llu) to stream processor (%p)", 
    890                         m_period, time_of_transfer, *it); 
     903                        m_period, m_time_of_transfer, *it); 
    891904                return false; // buffer overrun 
    892905            } 
    893906             
    894             #ifdef DEBUG 
     907            //#ifdef DEBUG 
     908            #if 0 
    895909            { 
    896910                uint64_t ts_tail=0; 
     
    910924                } 
    911925                 
    912                 debugOutput(DEBUG_LEVEL_VERBOSE,"T > HEAD: TS=%llu, FC=%llu | TAIL: TS=%llu, FC=%llu, %d\n", 
    913                     ts_tail, fc_tail, ts_head, fc_head, cnt);             
     926                debugOutput(DEBUG_LEVEL_VERBOSE,"T > HEAD: TS=%11llu, FC=%5llu | TAIL: TS=%11llu, FC=%5llu, %d\n", 
     927                    ts_head, fc_head, ts_tail, fc_tail, cnt); 
    914928            } 
    915929            #endif 
     
    923937        debugOutputShort( DEBUG_LEVEL_NORMAL, "----------------------------------------------------\n"); 
    924938        debugOutputShort( DEBUG_LEVEL_NORMAL, "Dumping StreamProcessorManager information...\n"); 
    925         debugOutputShort( DEBUG_LEVEL_NORMAL, "Period count: %d\n", m_nbperiods); 
     939        debugOutputShort( DEBUG_LEVEL_NORMAL, "Period count: %6d\n", m_nbperiods); 
    926940 
    927941        debugOutputShort( DEBUG_LEVEL_NORMAL, " Receive processors...\n");