Changeset 703

Show
Ignore:
Timestamp:
11/04/07 03:33:35 (16 years ago)
Author:
ppalmers
Message:

- rework of streaming startup
- started moving files around to enhance structure

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/ppalmers-streaming/src/libstreaming/AmdtpStreamProcessor.cpp

    r554 r703  
    3838namespace Streaming { 
    3939 
    40 IMPL_DEBUG_MODULE( AmdtpTransmitStreamProcessor, AmdtpTransmitStreamProcessor, DEBUG_LEVEL_NORMAL ); 
    41 IMPL_DEBUG_MODULE( AmdtpReceiveStreamProcessor, AmdtpReceiveStreamProcessor, DEBUG_LEVEL_NORMAL ); 
     40IMPL_DEBUG_MODULE( AmdtpTransmitStreamProcessor, AmdtpTransmitStreamProcessor, DEBUG_LEVEL_VERBOSE ); 
     41IMPL_DEBUG_MODULE( AmdtpReceiveStreamProcessor, AmdtpReceiveStreamProcessor, DEBUG_LEVEL_VERBOSE ); 
    4242 
    4343 
     
    8484     
    8585    if (cycle<0) { 
    86         debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Xmit handler for cycle %d, (running=%d, enabled=%d,%d)\n", 
    87             cycle, m_running, m_disabled, m_is_disabled); 
     86        debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE,"Xmit handler for cycle %d, (running=%d)\n", 
     87            cycle, m_running); 
    8888         
    8989        *tag = 0; 
     
    9494    } 
    9595     
    96     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"Xmit handler for cycle %d, (running=%d, enabled=%d,%d)\n", 
    97         cycle, m_running, m_disabled, m_is_disabled); 
     96    debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE,"Xmit handler for cycle %d, (running=%d)\n", 
     97        cycle, m_running); 
    9898     
    9999    m_last_cycle=cycle; 
     
    153153    uint64_t ts_head; 
    154154    signed int fc; 
    155     if (!m_disabled && m_is_disabled) { // this means that we are trying to enable 
    156         // check if we are on or past the enable point 
    157         int cycles_past_enable=diffCycles(cycle, m_cycle_to_enable_at); 
    158  
    159         if (cycles_past_enable >= 0) { 
    160             m_is_disabled=false; 
    161  
    162             debugOutput(DEBUG_LEVEL_VERBOSE,"Enabling StreamProcessor %p at %u\n", this, cycle); 
    163  
    164             // initialize the buffer head & tail 
    165             ffado_timestamp_t ts_head_tmp; 
    166             m_SyncSource->m_data_buffer->getBufferHeadTimestamp(&ts_head_tmp, &fc); // thread safe 
    167             ts_head=(uint64_t)ts_head_tmp; 
    168              
    169             // the number of cycles the sync source lags (> 0) 
    170             // or leads (< 0) 
    171             int sync_lag_cycles=diffCycles(cycle, m_SyncSource->getLastCycle()); 
    172  
    173             // account for the cycle lag between sync SP and this SP 
    174             // the last update of the sync source's timestamps was sync_lag_cycles 
    175             // cycles before the cycle we are calculating the timestamp for. 
    176             // if we were to use one-frame buffers, you would expect the 
    177             // frame that is sent on cycle CT to have a timestamp T1. 
    178             // ts_head however is for cycle CT-sync_lag_cycles, and lies 
    179             // therefore sync_lag_cycles * TICKS_PER_CYCLE earlier than 
    180             // T1. 
    181             ts_head = addTicks(ts_head, (sync_lag_cycles) * TICKS_PER_CYCLE); 
    182  
    183             ts_head = substractTicks(ts_head, TICKS_PER_CYCLE); 
    184  
    185             // account for the number of cycles we are too late to enable 
    186             ts_head = addTicks(ts_head, cycles_past_enable * TICKS_PER_CYCLE); 
    187  
    188             // account for one extra packet of frames 
    189             ts_head = substractTicks(ts_head, 
    190                         (uint32_t)((float)m_syt_interval * m_SyncSource->m_data_buffer->getRate())); 
    191  
    192             m_data_buffer->setBufferHeadTimestamp(ts_head); 
    193  
    194             #ifdef DEBUG 
    195             if ((unsigned int)m_data_buffer->getFrameCounter() != m_data_buffer->getBufferSize()) { 
    196                 debugWarning("m_data_buffer->getFrameCounter() != m_data_buffer->getBufferSize()\n"); 
    197             } 
    198             #endif 
    199             debugOutput(DEBUG_LEVEL_VERBOSE,"XMIT TS SET: TS=%10llu, LAG=%03d, FC=%4d\n", 
    200                             ts_head, sync_lag_cycles, m_data_buffer->getFrameCounter()); 
    201         } else { 
    202             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, 
    203                         "will enable StreamProcessor %p at %u, now is %d\n", 
    204                         this, m_cycle_to_enable_at, cycle); 
    205         } 
    206     } else if (m_disabled && !m_is_disabled) { 
    207         // trying to disable 
    208         debugOutput(DEBUG_LEVEL_VERBOSE,"disabling StreamProcessor %p at %u\n", 
    209                     this, cycle); 
    210         m_is_disabled=true; 
    211     } 
    212  
     155    uint64_t presentation_time; 
     156    unsigned int presentation_cycle; 
     157    int cycles_until_presentation; 
     158 
     159    const int min_cycles_beforehand = 2;  // FIXME: should become a define 
     160    const int max_cycles_beforehand = 15; // FIXME: should become a define 
     161 
     162    if( !m_running || !m_data_buffer->isEnabled() ) { 
     163        debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, 
     164                    "Not running (%d) or buffer not enabled (enabled=%d)\n", 
     165                    m_running, m_data_buffer->isEnabled()); 
     166 
     167        // not running or not enabled 
     168        goto send_empty_packet; 
     169    } 
     170 
     171try_block_of_frames: 
     172    debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "Try for cycle %d\n", cycle); 
     173    // check whether the packet buffer has packets for us to send. 
    213174    // the base timestamp is the one of the next sample in the buffer 
    214175    ffado_timestamp_t ts_head_tmp; 
     
    216177    ts_head=(uint64_t)ts_head_tmp; 
    217178 
    218     // we send a packet some cycles in advance, to avoid the 
    219     // following situation: 
    220     // suppose we are only a few ticks away from 
    221     // the moment to send this packet. therefore we decide 
    222     // not to send the packet, but send it in the next cycle. 
    223     // This means that the next time point will be 3072 ticks 
    224     // later, making that the timestamp will be expired when the 
    225     // packet is sent, unless TRANSFER_DELAY > 3072. 
    226     // this means that we need at least one cycle of extra buffering. 
    227     uint32_t ticks_to_advance = TICKS_PER_CYCLE * TRANSMIT_ADVANCE_CYCLES; 
    228  
    229     // if cycle lies cycle_diff cycles in the future, we should 
    230     // queue this packet cycle_diff * TICKS_PER_CYCLE earlier than 
    231     // we would if it were to be sent immediately. 
    232     ticks_to_advance += cycle_diff * TICKS_PER_CYCLE; 
    233  
    234     // determine the 'now' time in ticks 
    235     uint32_t cycle_timer=CYCLE_TIMER_TO_TICKS(ctr); 
    236  
    237     cycle_timer = addTicks(cycle_timer, ticks_to_advance); 
    238  
    239     // time until the packet is to be sent (if > 0: send packet) 
    240     int32_t until_next=diffTicks(ts_head, cycle_timer); 
    241  
    242     // if until_next < 0 we should send a filled packet 
    243     // otherwise we should send a NO-DATA packet 
    244     if((until_next<0) && (m_running)) { 
    245         // add the transmit transfer delay to construct the playout time (=SYT timestamp) 
    246         uint32_t ts_packet=addTicks(ts_head, TRANSMIT_TRANSFER_DELAY); 
    247  
    248         // if we are disabled, send a silent packet 
    249         // and advance the buffer head timestamp 
    250         if(m_is_disabled) { 
    251  
    252 //             transmitSilenceBlock((char *)(data+8), m_syt_interval, 0); 
    253 //             m_dbc += fillDataPacketHeader(packet, length, ts_packet); 
    254 // 
    255 //             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "XMIT SYNC: CY=%04u TSH=%011llu TSP=%011lu\n", 
    256 //                 cycle, ts_head, ts_packet); 
    257 // 
    258 //             // update the base timestamp 
    259 //             uint32_t ts_step=(uint32_t)((float)(m_syt_interval) 
    260 //                              *m_SyncSource->m_data_buffer->getRate()); 
    261 // 
    262 //             // the next buffer head timestamp 
    263 //             ts_head=addTicks(ts_head,ts_step); 
    264 //             m_data_buffer->setBufferHeadTimestamp(ts_head); 
    265 // 
    266             // no-data 
    267             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "XMIT SYNC: CY=%04u NONE\n", cycle); 
    268             m_dbc += fillNoDataPacketHeader(packet, length); 
    269             // defer to make sure we get to be enabled asap 
    270             return RAW1394_ISO_DEFER; 
    271  
    272         } else { // enabled & packet due, read from the buffer 
    273             if (m_data_buffer->readFrames(m_syt_interval, (char *)(data + 8))) { 
    274                 m_dbc += fillDataPacketHeader(packet, length, ts_packet); 
    275  
    276                 // process all ports that should be handled on a per-packet base 
    277                 // this is MIDI for AMDTP (due to the need of DBC) 
    278                 if (!encodePacketPorts((quadlet_t *)(data+8), m_syt_interval, packet->dbc)) { 
    279                     debugWarning("Problem encoding Packet Ports\n"); 
    280                 } 
    281  
    282                 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "XMIT DATA: CY=%04u TSH=%011llu TSP=%011lu\n", 
    283                     cycle, ts_head, ts_packet); 
    284  
    285                 return RAW1394_ISO_OK; 
    286  
    287             } else if (now_cycles<cycle) { 
    288                 // we can still postpone the queueing of the packets 
    289                 // because the ISO transmit packet buffer is not empty yet 
    290                 return RAW1394_ISO_AGAIN; 
    291  
    292             } else { // there is no more data in the ringbuffer 
    293                 // compose a silent packet, we should always 
    294                 // send a valid packet 
    295                 transmitSilenceBlock((char *)(data+8), m_syt_interval, 0); 
    296                 m_dbc += fillDataPacketHeader(packet, length, ts_packet); 
    297  
    298                 debugWarning("Transmit buffer underrun (now %d, queue %d, target %d)\n", 
    299                         now_cycles, cycle, TICKS_TO_CYCLES(ts_packet)); 
    300                 // signal underrun 
    301                 m_xruns++; 
    302                 // disable the processing, will be re-enabled when 
    303                 // the xrun is handled 
    304                 m_disabled=true; 
    305                 m_is_disabled=true; 
    306  
    307                 return RAW1394_ISO_DEFER; 
    308             } 
    309         } 
    310  
    311     } else { // no packet due, send no-data packet 
    312         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "XMIT NONE: CY=%04u TSH=%011llu\n", 
    313                 cycle, ts_head); 
    314  
    315         m_dbc += fillNoDataPacketHeader(packet, length); 
    316         return RAW1394_ISO_DEFER; 
    317     } 
    318  
    319     // we shouldn't get here 
     179    // first calculate the presentation time of the samples 
     180    presentation_time = addTicks(ts_head, TRANSMIT_TRANSFER_DELAY); 
     181 
     182    // calculate the cycle this block should be presented in 
     183    // (this is just a virtual calculation since at that time it should 
     184    //  already be in the device's buffer) 
     185    presentation_cycle = (unsigned int)(TICKS_TO_CYCLES( presentation_time )); 
     186 
     187    // we can check whether this cycle is within the 'window' we have 
     188    // to send this packet. 
     189    // first calculate the number of cycles left before presentation time 
     190    cycles_until_presentation = diffCycles( presentation_cycle, cycle ); 
     191 
     192    // two different options: 
     193    // 1) there are not enough frames for one packet  
     194    //      => determine wether this is a problem, since we might still 
     195    //         have some time to send it 
     196    // 2) there are enough packets 
     197    //      => determine whether we have to send them in this packet 
     198    if (fc < (signed int)m_syt_interval) { 
     199        // not enough frames in the buffer, 
     200        debugOutput(DEBUG_LEVEL_VERBOSE,  
     201                    "Insufficient frames: CY=%04u, PTC=%04u, CUP=%04d\n", 
     202                    cycle, presentation_cycle, cycles_until_presentation); 
     203        // we can still postpone the queueing of the packets 
     204        // if we are far enough ahead of the presentation time 
     205        if( cycles_until_presentation <= min_cycles_beforehand ) { 
     206            // we have an invalid timestamp or we are too late 
     207            // meaning that we in some sort of xrun state 
     208            // signal xrun situation ??HERE?? 
     209            m_xruns++; 
     210        } else { 
     211            // there is still time left to send the packet 
     212        } 
     213        // in any case we send an empty packet on this cycle 
     214        goto send_empty_packet; // UGLY but effective 
     215    } else { 
     216        // there are enough frames, so check the time they are intended for 
     217        // all frames have a certain 'time window' in which they can be sent 
     218        // this corresponds to the range of the timestamp mechanism: 
     219        // we can send a packet 15 cycles in advance of the 'presentation time' 
     220        // in theory we can send the packet up till one cycle before the presentation time, 
     221        // however this is not very smart. 
     222         
     223        // There are 3 options: 
     224        // 1) the frame block is too early 
     225        //      => send an empty packet 
     226        // 2) the frame block is within the window 
     227        //      => send it 
     228        // 3) the frame block is too late 
     229        //      => discard (and raise xrun?) 
     230        //         get next block of frames and repeat 
     231         
     232        if (cycles_until_presentation <= min_cycles_beforehand) { 
     233            // we are too late 
     234            debugOutput(DEBUG_LEVEL_VERBOSE,  
     235                        "Too late: CY=%04u, PTC=%04u, CUP=%04d, TSP=%011llu (%04u)\n", 
     236                        cycle, 
     237                        presentation_cycle, cycles_until_presentation, 
     238                        presentation_time, (unsigned int)TICKS_TO_CYCLES(presentation_time)); 
     239            // remove the samples 
     240            m_data_buffer->dropFrames(m_syt_interval); 
     241             
     242            // signal some xrun situation ??HERE?? 
     243            m_xruns++; 
     244             
     245            // try a new block of frames 
     246            goto try_block_of_frames; // UGLY but effective 
     247        } else if (cycles_until_presentation >= max_cycles_beforehand) { 
     248            debugOutput(DEBUG_LEVEL_VERY_VERBOSE,  
     249                        "Too early: CY=%04u, PTC=%04u, CUP=%04d, TSP=%011llu (%04u)\n", 
     250                        cycle, 
     251                        presentation_cycle, cycles_until_presentation, 
     252                        presentation_time, (unsigned int)TICKS_TO_CYCLES(presentation_time)); 
     253            // we are too early, send only an empty packet 
     254            goto send_empty_packet; // UGLY but effective 
     255        } else { 
     256            // send the packet 
     257            goto send_packet; // UGLY but effective 
     258        } 
     259    } 
     260     
     261    debugError("Should never reach this code!\n"); 
    320262    return RAW1394_ISO_ERROR; 
    321  
     263     
     264send_empty_packet: 
     265    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "XMIT NONE: CY=%04u, TSP=%011llu (%04u)\n", 
     266            cycle, 
     267            presentation_time, (unsigned int)TICKS_TO_CYCLES(presentation_time)); 
     268 
     269    m_dbc += fillNoDataPacketHeader(packet, length); 
     270    return RAW1394_ISO_DEFER; 
     271 
     272send_packet: 
     273    if (m_data_buffer->readFrames(m_syt_interval, (char *)(data + 8))) { 
     274        m_dbc += fillDataPacketHeader(packet, length, presentation_time); 
     275 
     276        // process all ports that should be handled on a per-packet base 
     277        // this is MIDI for AMDTP (due to the need of DBC) 
     278        if (!encodePacketPorts((quadlet_t *)(data+8), m_syt_interval, packet->dbc)) { 
     279            debugWarning("Problem encoding Packet Ports\n"); 
     280        } 
     281 
     282        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "XMIT DATA: CY=%04u, TSH=%011llu (%04u), TSP=%011llu (%04u)\n", 
     283            cycle, 
     284            ts_head, (unsigned int)TICKS_TO_CYCLES(ts_head), 
     285            presentation_time, (unsigned int)TICKS_TO_CYCLES(presentation_time)); 
     286 
     287        return RAW1394_ISO_OK; 
     288    } 
     289    // else: 
     290    debugError("This is impossible, since we checked the buffer size before!\n"); 
     291    return RAW1394_ISO_ERROR; 
    322292} 
    323293 
     
    384354    m_WakeupStat.reset(); 
    385355 
    386     // we have to make sure that the buffer HEAD timestamp 
    387     // lies in the future for every possible buffer fill case. 
    388     int offset=(int)(m_ringbuffer_size_frames*getTicksPerFrame()); 
    389  
    390     m_data_buffer->setTickOffset(offset); 
     356    m_data_buffer->setTickOffset(0); 
    391357 
    392358    // reset all non-device specific stuff 
     
    589555 
    590556bool AmdtpTransmitStreamProcessor::prepareForStop() { 
    591     disable(); 
    592557    return true; 
    593558} 
    594559 
    595560bool AmdtpTransmitStreamProcessor::prepareForEnable(uint64_t time_to_enable_at) { 
    596  
    597     debugOutput(DEBUG_LEVEL_VERBOSE,"Preparing to enable...\n"); 
    598  
    599     // for the transmit SP, we have to initialize the 
    600     // buffer timestamp to something sane, because this timestamp 
    601     // is used when it is SyncSource 
    602  
    603     // the time we initialize to will determine the time at which 
    604     // the first sample in the buffer will be sent, so we should 
    605     // make it at least 'time_to_enable_at' 
    606  
    607     uint64_t now=m_handler->getCycleTimer(); 
    608     unsigned int now_secs=CYCLE_TIMER_GET_SECS(now); 
    609  
    610     // check if a wraparound on the secs will happen between 
    611     // now and the time we start 
    612     int until_enable=(int)time_to_enable_at - (int)CYCLE_TIMER_GET_CYCLES(now); 
    613  
    614     if(until_enable>4000) { 
    615         // wraparound on CYCLE_TIMER_GET_CYCLES(now) 
    616         // this means that we are late starting up, 
    617         // and that the start lies in the previous second 
    618         if (now_secs==0) now_secs=127; 
    619         else now_secs--; 
    620     } else if (until_enable<-4000) { 
    621         // wraparound on time_to_enable_at 
    622         // this means that we are early and that the start 
    623         // point lies in the next second 
    624         now_secs++; 
    625         if (now_secs>=128) now_secs=0; 
    626     } 
    627  
    628     uint64_t ts_head= now_secs*TICKS_PER_SECOND; 
    629     ts_head+=time_to_enable_at*TICKS_PER_CYCLE; 
    630  
    631     // we also add the nb of cycles we transmit in advance 
    632     ts_head=addTicks(ts_head, TRANSMIT_ADVANCE_CYCLES*TICKS_PER_CYCLE); 
    633  
    634     m_data_buffer->setBufferTailTimestamp(ts_head); 
    635  
    636561 
    637562    if (!StreamProcessor::prepareForEnable(time_to_enable_at)) { 
     
    666591    m_PeriodStat.mark(m_data_buffer->getBufferFill()); 
    667592 
    668     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "AmdtpTransmitStreamProcessor::putFrames(%d, %llu)\n", nbframes, ts); 
     593    debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "AmdtpTransmitStreamProcessor::putFrames(%d, %llu)\n", nbframes, ts); 
    669594 
    670595    // transfer the data 
    671596    m_data_buffer->blockProcessWriteFrames(nbframes, ts); 
    672597 
    673     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " New timestamp: %llu\n", ts); 
    674  
    675     return true; 
    676 
     598    debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, " New timestamp: %llu\n", ts); 
     599 
     600    return true; // FIXME: what about failure? 
     601
     602 
     603bool AmdtpTransmitStreamProcessor::putFramesDry(unsigned int nbframes, int64_t ts) { 
     604    debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "AmdtpTransmitStreamProcessor::putFramesDry(%d, %llu)\n", nbframes, ts); 
     605 
     606    bool retval; 
     607    char dummybuffer[sizeof(quadlet_t)*nbframes*m_dimension]; 
     608 
     609    transmitSilenceBlock(dummybuffer, nbframes, 0); 
     610    // add the silence data to the ringbuffer 
     611    if(m_data_buffer->writeFrames(nbframes, dummybuffer, ts)) { 
     612        retval=true; 
     613    } else { 
     614        debugWarning("Could not write to event buffer\n"); 
     615        retval=false; 
     616    } 
     617 
     618    debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, " New timestamp: %llu\n", ts); 
     619    return retval; 
     620
     621 
    677622/* 
    678623 * write received events to the stream ringbuffers. 
     
    800745                                             IEC61883_AM824_LABEL_MIDI_1X)); 
    801746 
    802                 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "MIDI port %s, pos=%d, loc=%d, dbc=%d, nevents=%d, dim=%d\n", 
     747                debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "MIDI port %s, pos=%d, loc=%d, dbc=%d, nevents=%d, dim=%d\n", 
    803748                    mp->getName().c_str(), mp->getPosition(), mp->getLocation(), dbc, nevents, m_dimension); 
    804                 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "base=%p, target=%p, value=%08X\n", 
     749                debugOutput(DEBUG_LEVEL_ULTRA_VERBOSE, "base=%p, target=%p, value=%08X\n", 
    805750                    data, target_event, tmpval); 
    806751                     
     
    937882    } 
    938883 
    939     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"ch%2u: CY=%4u, SYT=%08X (%4ucy + %04uticks) (running=%d, disabled=%d,%d)\n", 
     884    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"ch%2u: CY=%4u, SYT=%08X (%4ucy + %04uticks) (running=%d)\n", 
    940885        channel, cycle,ntohs(packet->syt), 
    941886        CYCLE_TIMER_GET_CYCLES(ntohs(packet->syt)), CYCLE_TIMER_GET_OFFSET(ntohs(packet->syt)), 
    942         m_running,m_disabled,m_is_disabled); 
     887        m_running); 
    943888 
    944889    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, 
     
    952897 
    953898#endif 
    954     if (!m_disabled && m_is_disabled) { // this means that we are trying to enable 
    955         // check if we are on or past the enable point 
    956         int cycles_past_enable=diffCycles(cycle, m_cycle_to_enable_at); 
    957  
    958         if (cycles_past_enable >= 0) { 
    959             m_is_disabled=false; 
    960             debugOutput(DEBUG_LEVEL_VERBOSE,"Enabling StreamProcessor %p at %d (SYT=%04X)\n", 
    961                 this, cycle, ntohs(packet->syt)); 
    962             // the previous timestamp is the one we need to start with 
    963             // because we're going to update the buffer again this loop 
    964             // using writeframes 
    965             m_data_buffer->setBufferTailTimestamp(m_last_timestamp); 
    966  
    967         } else { 
    968             debugOutput(DEBUG_LEVEL_VERY_VERBOSE, 
    969                 "will enable StreamProcessor %p at %u, now is %d\n", 
    970                     this, m_cycle_to_enable_at, cycle); 
    971         } 
    972     } else if (m_disabled && !m_is_disabled) { 
    973         // trying to disable 
    974         debugOutput(DEBUG_LEVEL_VERBOSE,"disabling StreamProcessor %p at %u\n", this, cycle); 
    975         m_is_disabled=true; 
    976     } 
    977899 
    978900    // check if this is a valid packet 
     
    1011933        } 
    1012934 
    1013         //=> don't process the stream samples when it is not enabled. 
    1014         if(m_is_disabled) { 
    1015  
    1016             // we keep track of the timestamp here 
    1017             // this makes sure that we will have a somewhat accurate 
    1018             // estimate as to when a period might be ready. i.e. it will not 
    1019             // be ready earlier than this timestamp + period time 
    1020  
    1021             // the next (possible) sample is not this one, but lies 
    1022             // SYT_INTERVAL * rate later 
    1023             uint64_t ts=addTicks(m_last_timestamp, 
    1024                                  (uint64_t)((float)m_syt_interval * getTicksPerFrame())); 
    1025  
    1026             // set the timestamp as if there will be a sample put into 
    1027             // the buffer by the next packet. 
    1028             m_data_buffer->setBufferTailTimestamp(ts); 
    1029  
    1030             return RAW1394_ISO_DEFER; 
    1031         } 
    1032  
    1033935        #ifdef DEBUG_OFF 
    1034936        if((cycle % 1000) == 0) { 
     
    1065967        } else { 
    1066968 
    1067             debugWarning("Receive buffer overrun (cycle %d, FC=%d, PC=%d)\n", 
    1068                  cycle, m_data_buffer->getFrameCounter(), m_handler->getPacketCount()); 
     969//             debugWarning("Receive buffer overrun (cycle %d, FC=%d, PC=%d)\n", 
     970//                  cycle, m_data_buffer->getFrameCounter(), m_handler->getPacketCount()); 
    1069971 
    1070972            m_xruns++; 
    1071  
    1072             // disable the processing, will be re-enabled when 
    1073             // the xrun is handled 
    1074             m_disabled=true; 
    1075             m_is_disabled=true; 
    1076973 
    1077974            retval=RAW1394_ISO_DEFER; 
     
    12751172bool AmdtpReceiveStreamProcessor::getFrames(unsigned int nbframes, int64_t ts) { 
    12761173 
    1277     m_PeriodStat.mark(m_data_buffer->getBufferFill()); 
    1278     uint64_t ts_head; 
    1279     signed int fc; 
    1280     int32_t lag_ticks; 
    1281     float lag_frames; 
    1282  
    1283     // in order to sync up multiple received streams, we should  
    1284     // use the ts parameter. It specifies the time of the block's  
    1285     // first sample. 
    1286      
    1287     ffado_timestamp_t ts_head_tmp; 
    1288     m_data_buffer->getBufferHeadTimestamp(&ts_head_tmp, &fc); 
    1289     ts_head=(uint64_t)ts_head_tmp; 
    1290     lag_ticks=diffTicks(ts, ts_head); 
    1291     float rate=m_data_buffer->getRate(); 
    1292      
    1293     assert(rate!=0.0); 
    1294      
    1295     lag_frames=(((float)lag_ticks)/rate); 
    1296      
    1297     if (lag_frames>=1.0) { 
    1298         // the stream leads 
    1299         debugOutput( DEBUG_LEVEL_VERBOSE, "stream (%p): lags  with %6d ticks = %10.5f frames (rate=%10.5f)\n",this,lag_ticks,lag_frames,rate); 
    1300          
    1301         if (lag_frames>=10.0) { 
    1302             debugOutput( DEBUG_LEVEL_VERBOSE, "  %lld, %llu, %d\n", ts, ts_head, fc); 
    1303         } 
    1304          
    1305         // ditch the excess frames 
    1306         char dummy[m_data_buffer->getBytesPerFrame()]; // one frame of garbage 
    1307         int frames_to_ditch=(int)(lag_frames); 
    1308         debugOutput( DEBUG_LEVEL_VERBOSE, "stream (%p): ditching %d frames (@ ts=%lld)\n",this,frames_to_ditch,ts); 
    1309          
    1310         while (frames_to_ditch--) { 
    1311 //             m_data_buffer->readFrames(1, dummy); 
    1312         } 
    1313          
    1314     } else if (lag_frames<=-1.0) { 
    1315         // the stream leads 
    1316         debugOutput( DEBUG_LEVEL_VERBOSE, "stream (%p): leads with %6d ticks = %10.5f frames (rate=%10.5f)\n",this,lag_ticks,lag_frames,rate); 
    1317          
    1318         if (lag_frames<=-10.0) { 
    1319             debugOutput( DEBUG_LEVEL_VERBOSE, "  %lld, %llu, %d\n", ts, ts_head, fc); 
    1320         } 
    1321          
    1322         // add some padding frames 
    1323         int frames_to_add=(int)lag_frames; 
    1324         debugOutput( DEBUG_LEVEL_VERBOSE, "stream (%p): adding %d frames (@ ts=%lld)\n",this,-frames_to_add,ts); 
    1325          
    1326         while (frames_to_add++) { 
    1327 //             m_data_buffer->writeDummyFrame(); 
    1328         } 
    1329     } 
    1330      
    13311174    // ask the buffer to process nbframes of frames 
    13321175    // using it's registered client's processReadBlock(), 
     
    13341177    m_data_buffer->blockProcessReadFrames(nbframes); 
    13351178 
     1179    return true; 
     1180} 
     1181 
     1182bool AmdtpReceiveStreamProcessor::getFramesDry(unsigned int nbframes, int64_t ts) { 
     1183    int frames_to_ditch=(int)(nbframes); 
     1184    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "stream (%p): dry run %d frames (@ ts=%lld)\n", 
     1185                 this, frames_to_ditch, ts); 
     1186    char dummy[m_data_buffer->getBytesPerFrame()]; // one frame of garbage 
     1187 
     1188    while (frames_to_ditch--) { 
     1189        m_data_buffer->readFrames(1, dummy); 
     1190    } 
    13361191    return true; 
    13371192} 
  • branches/ppalmers-streaming/src/libstreaming/AmdtpStreamProcessor.h

    r494 r703  
    9696 
    9797    bool putFrames(unsigned int nbframes, int64_t ts); ///< transfer the buffer contents from the client 
     98    bool putFramesDry(unsigned int nbframes, int64_t ts); 
    9899 
    99100    // We have 1 period of samples = m_period 
     
    188189 
    189190    bool getFrames(unsigned int nbframes, int64_t ts); ///< transfer the buffer contents to the client 
     191    bool getFramesDry(unsigned int nbframes, int64_t ts); 
    190192 
    191193    // We have 1 period of samples = m_period 
  • branches/ppalmers-streaming/src/libstreaming/cycletimer.h

    r498 r703  
    6666                                      ) 
    6767#define CYCLE_TIMER_WRAP_TICKS(x) ((x % TICKS_PER_SECOND)) 
     68 
     69#define INVALID_TIMESTAMP_TICKS     0xFFFFFFFFFFFFFFFFULL 
    6870 
    6971DECLARE_GLOBAL_DEBUG_MODULE; 
     
    247249    uint64_t timestamp; 
    248250 
    249     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"SYT=%08X CY=%04X CTR=%08X\n", 
    250         syt_timestamp,rcv_cycle,ctr_now); 
     251    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"SYT=%04llX CY=%u CTR=%08llX\n", 
     252        syt_timestamp, rcv_cycle, ctr_now); 
    251253 
    252254    // reconstruct the full cycle 
     
    309311        if(( TICKS_TO_CYCLE_TIMER(timestamp) & 0xFFFF) != syt_timestamp) { 
    310312            debugWarning("back-converted timestamp not equal to SYT\n"); 
    311             debugWarning("TS=%011llu TSC=%08X SYT=%04X\n", 
     313            debugWarning("TS=%011llu TSC=%08lX SYT=%04X\n", 
    312314                  timestamp, TICKS_TO_CYCLE_TIMER(timestamp), syt_timestamp); 
    313315        } 
     
    333335    uint64_t timestamp; 
    334336 
    335     debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"SYT=%08X CY=%04X CTR=%08X\n", 
     337    debugOutput(DEBUG_LEVEL_VERY_VERBOSE,"SYT=%08llX CY=%04X CTR=%08llX\n", 
    336338        syt_timestamp,xmt_cycle,ctr_now); 
    337339 
     
    395397        if(( TICKS_TO_CYCLE_TIMER(timestamp) & 0xFFFF) != syt_timestamp) { 
    396398            debugWarning("back-converted timestamp not equal to SYT\n"); 
    397             debugWarning("TS=%011llu TSC=%08X SYT=%04X\n", 
     399            debugWarning("TS=%011llu TSC=%08lX SYT=%04X\n", 
    398400                  timestamp, TICKS_TO_CYCLE_TIMER(timestamp), syt_timestamp); 
    399401        } 
  • branches/ppalmers-streaming/src/libstreaming/IsoHandlerManager.cpp

    r494 r703  
    8686{ 
    8787    debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); 
     88    pthread_mutex_init(&m_debug_lock, NULL); 
    8889 
    8990    return true; 
     
    107108//     updateCycleTimers(); 
    108109 
     110    pthread_mutex_lock(&m_debug_lock); 
     111 
    109112    if(!iterate()) { 
    110113        debugFatal("Could not iterate the isoManager\n"); 
     114        pthread_mutex_unlock(&m_debug_lock); 
    111115        return false; 
    112116    } 
     117 
     118    pthread_mutex_unlock(&m_debug_lock); 
    113119 
    114120    return true; 
  • branches/ppalmers-streaming/src/libstreaming/IsoHandlerManager.h

    r445 r703  
    102102        bool Execute(); // note that this is called in we while(running) loop 
    103103        bool Init(); 
     104        pthread_mutex_t m_debug_lock; 
    104105 
    105106    // the state machine 
     
    149150        Util::PosixThread *m_isoManagerThread; 
    150151 
    151  
    152152        // debug stuff 
    153153        DECLARE_DEBUG_MODULE; 
  • branches/ppalmers-streaming/src/libstreaming/StreamProcessor.cpp

    r494 r703  
    211211    } 
    212212#endif 
     213    m_data_buffer->enable(); 
    213214 
    214215    m_disabled=false; 
     
    217218 
    218219bool StreamProcessor::disable()  { 
     220    m_data_buffer->disable(); 
    219221    m_disabled=true; 
    220222    return true; 
     
    261263    int32_t until_next=diffTicks(time_at_period,cycle_timer); 
    262264 
    263     debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "=> TAP=%11llu, CTR=%11llu, UTN=%11lld\n", 
     265    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "=> TAP=%11llu, CTR=%11llu, UTN=%11ld\n", 
    264266        time_at_period, cycle_timer, until_next 
    265267        ); 
     
    274276uint64_t StreamProcessor::getTimeAtPeriodUsecs() { 
    275277    return (uint64_t)((float)getTimeAtPeriod() * TICKS_PER_USEC); 
     278} 
     279 
     280bool StreamProcessor::dropFrames(unsigned int nbframes) { 
     281    debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "StreamProcessor::dropFrames(%d)\n", nbframes); 
     282    return m_data_buffer->dropFrames(nbframes); 
    276283} 
    277284 
  • branches/ppalmers-streaming/src/libstreaming/StreamProcessor.h

    r494 r703  
    9191    virtual bool putFrames(unsigned int nbframes, int64_t ts) = 0; ///< transfer the buffer contents from client 
    9292    virtual bool getFrames(unsigned int nbframes, int64_t ts) = 0; ///< transfer the buffer contents to the client 
     93    virtual bool putFramesDry(unsigned int nbframes, int64_t ts) = 0; ///< dry-process the buffer contents 
     94    virtual bool getFramesDry(unsigned int nbframes, int64_t ts) = 0; ///< dry-process the buffer contents 
    9395 
    9496    virtual bool reset(); ///< reset the streams & buffers (e.g. after xrun) 
     
    149151         */ 
    150152        virtual bool canClientTransferFrames(unsigned int nframes) = 0; 
     153 
     154        /** 
     155         * @brief drop nframes from the internal buffer 
     156         * 
     157         * this function drops nframes from the internal buffers, without any 
     158         * specification on what frames are dropped. Timestamps are not updated. 
     159         * 
     160         * @param nframes number of frames 
     161         * @return true if the operation was successful 
     162         */ 
     163        virtual bool dropFrames(unsigned int nframes); 
    151164 
    152165        /** 
     
    242255                  {return RAW1394_ISO_STOP;}; 
    243256        virtual bool putFrames(unsigned int nbframes, int64_t ts) {return false;}; 
     257        virtual bool putFramesDry(unsigned int nbframes, int64_t ts) {return false;}; 
    244258 
    245259        virtual enum raw1394_iso_disposition putPacket(unsigned char *data, unsigned int length, 
     
    276290                  unsigned int cycle, unsigned int dropped) {return RAW1394_ISO_STOP;}; 
    277291        virtual bool getFrames(unsigned int nbframes, int64_t ts) {return false;}; 
    278  
    279     virtual enum raw1394_iso_disposition 
    280         getPacket(unsigned char *data, unsigned int *length, 
    281                   unsigned char *tag, unsigned char *sy, 
    282                   int cycle, unsigned int dropped, unsigned int max_length) = 0; 
     292        virtual bool getFramesDry(unsigned int nbframes, int64_t ts) {return false;}; 
     293 
    283294     virtual void setVerboseLevel(int l); 
    284295 
  • branches/ppalmers-streaming/src/libstreaming/StreamProcessorManager.cpp

    r512 r703  
    173173    debugOutput( DEBUG_LEVEL_VERBOSE, "enter...\n"); 
    174174 
    175     m_isoManager=new IsoHandlerManager(m_thread_realtime, m_thread_priority); 
     175    m_isoManager=new IsoHandlerManager(m_thread_realtime, m_thread_priority + 1); 
    176176 
    177177    if(!m_isoManager) { 
     
    296296        } 
    297297 
    298         // EXPERIMENT: 
    299         // the only stream that should be running is the sync 
    300         // source stream, as this is the one that defines 
    301         // when to signal buffers. Maybe we get an xrun at startup, 
    302         // but that should be handled. 
    303  
    304         // the problem is that otherwise a setup with a device 
    305         // that waits for decent input before sending output 
    306         // will not start up (e.g. the bounce device), because 
    307         // all streams are required to be running. 
    308  
    309         // other streams still have at least ENABLE_DELAY_CYCLES cycles 
    310         // to start up 
    311 //         if(!m_SyncSource->isRunning()) notRunning=true; 
    312  
    313298        usleep(1000); 
    314         debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Running check: %d\n",notRunning); 
     299        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Running check: %d\n", notRunning); 
    315300    } 
    316301 
     
    342327    // we want to make sure that everything is running well, 
    343328    // so wait for a while 
    344     usleep(USECS_PER_CYCLE * CYCLES_TO_SLEEP_AFTER_RUN_SIGNAL); 
     329//     usleep(USECS_PER_CYCLE * CYCLES_TO_SLEEP_AFTER_RUN_SIGNAL); 
    345330 
    346331    debugOutput( DEBUG_LEVEL_VERBOSE, " StreamProcessor streams running...\n"); 
     
    373358            it != m_ReceiveProcessors.end(); 
    374359            ++it ) { 
     360        // get the receive SP's going at receiving data 
     361        (*it)->m_data_buffer->setTransparent(false); 
    375362        (*it)->reset(); 
    376363    } 
     
    379366            it != m_TransmitProcessors.end(); 
    380367            ++it ) { 
     368        // make sure the SP retains it's prefilled data 
     369        (*it)->m_data_buffer->setTransparent(false); 
    381370        (*it)->reset(); 
    382371    } 
    383  
     372     
     373    dumpInfo(); 
     374    // All buffers are prefilled and set-up, the only thing  
     375    // that remains a mistery is the timestamp information. 
     376//     m_SyncSource->m_data_buffer->setTransparent(false); 
     377//     debugShowBackLog(); 
     378     
     379    debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for sync...\n"); 
     380    // in order to obtain that, we wait for the first periods to be 
     381    // received. 
     382    int nb_sync_runs=10; 
     383    while(nb_sync_runs--) { // or while not sync-ed? 
     384        waitForPeriod(); 
     385 
     386        // drop the frames for all receive SP's 
     387        dryRun(StreamProcessor::E_Receive); 
     388         
     389        // we don't have to dryrun for the xmit SP's since they 
     390        // are not sending data yet. 
     391    } 
     392 
     393    debugOutput( DEBUG_LEVEL_VERBOSE, " sync at TS=%011llu...\n", m_time_of_transfer); 
     394    // FIXME: xruns can screw up the framecounter accounting. do something more sane here 
     395    resetXrunCounters(); 
     396    // lock the isohandlermanager such that things freeze 
     397//     debugShowBackLog(); 
     398 
     399    // we now should have decent sync info 
     400    // the buffers of the receive streams should be (approx) empty 
     401    // the buffers of the xmit streams should be full 
     402     
     403    // note what should the timestamp of the first sample be? 
     404     
     405    // at this point the buffer head timestamp of the transmit buffers can be 
     406    // set properly since we know the sync source's timestamp of the last 
     407    // buffer transfer. we also know the rate. 
     408     
     409    debugOutput( DEBUG_LEVEL_VERBOSE, " propagate sync info...\n"); 
     410    // FIXME: in the SPM it would be nice to have system time instead of 
     411    //        1394 time 
     412//     float rate=m_SyncSource->getTicksPerFrame(); 
     413//     int64_t one_ringbuffer_in_ticks=(int64_t)(((float)(m_nb_buffers*m_period))*rate); 
     414//     // the data at the front of the buffer is intended to be transmitted 
     415//     // nb_periods*period_size after the last received period 
     416//     int64_t transmit_timestamp = addTicks(m_time_of_transfer, one_ringbuffer_in_ticks); 
     417 
     418    for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
     419            it != m_TransmitProcessors.end(); 
     420            ++it ) { 
     421        // FIXME: encapsulate 
     422        (*it)->m_data_buffer->setBufferHeadTimestamp(m_time_of_transfer); 
     423        //(*it)->m_data_buffer->setNominalRate(rate); //CHECK!!! 
     424    } 
     425     
     426    dumpInfo(); 
     427     
     428    // this is the place were we should be syncing the received streams too 
     429    // check how much they differ 
     430     
     431     
    384432    debugOutput( DEBUG_LEVEL_VERBOSE, "Enabling StreamProcessors...\n"); 
    385433 
     
    387435 
    388436    // FIXME: this should not be in cycles, but in 'time' 
     437    // FIXME: remove the timestamp 
    389438    unsigned int enable_at=TICKS_TO_CYCLES(now)+ENABLE_DELAY_CYCLES; 
    390439    if (enable_at > 8000) enable_at -= 8000; 
     
    395444    } 
    396445 
    397     return true; 
     446    debugOutput( DEBUG_LEVEL_VERBOSE, "Running dry for a while...\n"); 
     447    // run some cycles 'dry' such that everything can stabilize 
     448    int nb_dryrun_cycles=10; 
     449    bool no_xrun; 
     450    while(nb_dryrun_cycles--) { 
     451        waitForPeriod(); 
     452        no_xrun = dryRun(); // dry run both receive and xmit 
     453 
     454        if (no_xrun) { 
     455            debugOutput( DEBUG_LEVEL_VERBOSE, " This dry-run was not xrun free...\n" ); 
     456            resetXrunCounters(); 
     457            // FIXME: xruns can screw up the framecounter accounting. do something more sane here 
     458        } 
     459    } 
     460 
     461    // now we should clear the xrun flags 
     462    resetXrunCounters(); 
     463 
     464    // and off we go 
     465    return true; 
     466
     467 
     468void StreamProcessorManager::resetXrunCounters(){ 
     469    debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting xrun flags...\n"); 
     470    for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     471        it != m_ReceiveProcessors.end(); 
     472        ++it ) 
     473    { 
     474        (*it)->resetXrunCounter(); 
     475    } 
     476 
     477    for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
     478        it != m_TransmitProcessors.end(); 
     479        ++it )  
     480    { 
     481        (*it)->resetXrunCounter(); 
     482    } 
    398483} 
    399484 
     
    492577    } 
    493578 
     579    debugOutput( DEBUG_LEVEL_VERBOSE, "Disabling StreamProcessors...\n"); 
     580        if (!disableStreamProcessors()) { 
     581        debugFatal("Could not disable StreamProcessors...\n"); 
     582        return false; 
     583    } 
    494584 
    495585    debugOutput( DEBUG_LEVEL_VERBOSE, "Stopping handlers...\n"); 
     
    585675 
    586676    // now we wait for the SP's to get enabled 
    587     debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for all StreamProcessors to be enabled...\n"); 
    588     // we have to wait until all streamprocessors indicate that they are running 
    589     // i.e. that there is actually some data stream flowing 
    590     int wait_cycles=ENABLE_TIMEOUT_MSEC; // two seconds 
    591     bool notEnabled=true; 
    592     while (notEnabled && wait_cycles) { 
    593         wait_cycles--; 
    594         notEnabled=false; 
    595  
    596         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    597                 it != m_ReceiveProcessors.end(); 
    598                 ++it ) { 
    599             if(!(*it)->isEnabled()) notEnabled=true; 
    600         } 
    601  
    602         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    603                 it != m_TransmitProcessors.end(); 
    604                 ++it ) { 
    605             if(!(*it)->isEnabled()) notEnabled=true; 
    606         } 
    607         usleep(1000); // one cycle 
    608     } 
    609  
    610     if(!wait_cycles) { // timout has occurred 
    611         debugFatal("One or more streams couldn't be enabled (timeout):\n"); 
    612  
    613         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    614                 it != m_ReceiveProcessors.end(); 
    615                 ++it ) { 
    616             if(!(*it)->isEnabled()) { 
    617                     debugFatal(" receive stream %p not enabled\n",*it); 
    618             } else { 
    619                     debugFatal(" receive stream %p enabled\n",*it); 
    620             } 
    621         } 
    622  
    623         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    624                 it != m_TransmitProcessors.end(); 
    625                 ++it ) { 
    626             if(!(*it)->isEnabled()) { 
    627                     debugFatal(" transmit stream %p not enabled\n",*it); 
    628             } else { 
    629                     debugFatal(" transmit stream %p enabled\n",*it); 
    630             } 
    631         } 
    632         return false; 
    633     } 
     677//     debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for all StreamProcessors to be enabled...\n"); 
     678//     // we have to wait until all streamprocessors indicate that they are running 
     679//     // i.e. that there is actually some data stream flowing 
     680//     int wait_cycles=ENABLE_TIMEOUT_MSEC; // two seconds 
     681//     bool notEnabled=true; 
     682//     while (notEnabled && wait_cycles) { 
     683//         wait_cycles--; 
     684//         notEnabled=false; 
     685//  
     686//         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     687//                 it != m_ReceiveProcessors.end(); 
     688//                 ++it ) { 
     689//             if(!(*it)->isEnabled()) notEnabled=true; 
     690//         } 
     691//  
     692//         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
     693//                 it != m_TransmitProcessors.end(); 
     694//                 ++it ) { 
     695//             if(!(*it)->isEnabled()) notEnabled=true; 
     696//         } 
     697//         usleep(1000); // one cycle 
     698//     } 
     699//  
     700//     if(!wait_cycles) { // timout has occurred 
     701//         debugFatal("One or more streams couldn't be enabled (timeout):\n"); 
     702//  
     703//         for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     704//                 it != m_ReceiveProcessors.end(); 
     705//                 ++it ) { 
     706//             if(!(*it)->isEnabled()) { 
     707//                     debugFatal(" receive stream %p not enabled\n",*it); 
     708//             } else { 
     709//                     debugFatal(" receive stream %p enabled\n",*it); 
     710//             } 
     711//         } 
     712//  
     713//         for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
     714//                 it != m_TransmitProcessors.end(); 
     715//                 ++it ) { 
     716//             if(!(*it)->isEnabled()) { 
     717//                     debugFatal(" transmit stream %p not enabled\n",*it); 
     718//             } else { 
     719//                     debugFatal(" transmit stream %p enabled\n",*it); 
     720//             } 
     721//         } 
     722//         return false; 
     723//     } 
    634724 
    635725    debugOutput( DEBUG_LEVEL_VERBOSE, " => all StreamProcessors enabled...\n"); 
     
    661751            ++it ) { 
    662752        (*it)->disable(); 
     753        (*it)->m_data_buffer->setTransparent(true); 
    663754    } 
    664755 
     
    667758            ++it ) { 
    668759        (*it)->disable(); 
     760        (*it)->m_data_buffer->setTransparent(true); 
    669761    } 
    670762 
     
    833925    } 
    834926    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "XF at %011llu ticks, RBF=%d, XBF=%d, SUM=%d...\n", 
    835         m_time_of_transfer,rcv_bf,xmt_bf,rcv_bf+xmt_bf); 
     927        m_time_of_transfer, rcv_bf, xmt_bf, rcv_bf+xmt_bf); 
    836928 
    837929#endif 
     
    9251017        int64_t one_frame_in_ticks=(int64_t)(((float)m_period)*rate); 
    9261018         
    927         int64_t receive_timestamp = substractTicks(m_time_of_transfer,one_frame_in_ticks); 
     1019        int64_t receive_timestamp = substractTicks(m_time_of_transfer, one_frame_in_ticks); 
    9281020         
    9291021        if(receive_timestamp<0) { 
     
    9511043                it != m_TransmitProcessors.end(); 
    9521044                ++it ) { 
    953  
    954             if(!(*it)->putFrames(m_period, (int64_t)m_time_of_transfer)) { 
     1045            // FIXME: in the SPM it would be nice to have system time instead of 
     1046            //        1394 time 
     1047            float rate=m_SyncSource->getTicksPerFrame(); 
     1048            int64_t one_ringbuffer_in_ticks=(int64_t)(((float)(m_nb_buffers*m_period))*rate); 
     1049 
     1050            // the data we are putting into the buffer is intended to be transmitted 
     1051            // one ringbuffer size after it has been received 
     1052            int64_t transmit_timestamp = addTicks(m_time_of_transfer, one_ringbuffer_in_ticks); 
     1053 
     1054            if(!(*it)->putFrames(m_period, transmit_timestamp)) { 
    9551055                debugOutput(DEBUG_LEVEL_VERBOSE, "could not putFrames(%u,%llu) to stream processor (%p)\n", 
    956                         m_period, m_time_of_transfer, *it); 
     1056                        m_period, transmit_timestamp, *it); 
     1057                return false; // buffer overrun 
     1058            } 
     1059 
     1060        } 
     1061    } 
     1062 
     1063    return true; 
     1064
     1065 
     1066/** 
     1067 * @brief Dry run one period for both receive and transmit StreamProcessors 
     1068 * 
     1069 * Process one period of frames for all streamprocessors, without touching the 
     1070 * client buffers. This only removes an incoming period from the ISO receive buffer and 
     1071 * puts one period of silence into the transmit buffers. 
     1072 * 
     1073 * @return true if successful, false otherwise (indicates xrun). 
     1074 */ 
     1075bool StreamProcessorManager::dryRun() { 
     1076    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Dry-running period...\n"); 
     1077    if (!dryRun(StreamProcessor::E_Receive)) return false; 
     1078    if (!dryRun(StreamProcessor::E_Transmit)) return false; 
     1079    return true; 
     1080
     1081 
     1082/** 
     1083 * @brief Dry run one period for either the receive or transmit StreamProcessors 
     1084 * 
     1085 * see dryRun() 
     1086 * 
     1087 * @param t The processor type to dryRun for (receive or transmit) 
     1088 * @return true if successful, false otherwise (indicates xrun). 
     1089 */ 
     1090 
     1091bool StreamProcessorManager::dryRun(enum StreamProcessor::EProcessorType t) { 
     1092    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Transferring period...\n"); 
     1093 
     1094    // a static cast could make sure that there is no performance 
     1095    // penalty for the virtual functions (to be checked) 
     1096    if (t==StreamProcessor::E_Receive) { 
     1097         
     1098        // determine the time at which we want reception to start 
     1099        float rate=m_SyncSource->getTicksPerFrame(); 
     1100        int64_t one_frame_in_ticks=(int64_t)(((float)m_period)*rate); 
     1101         
     1102        int64_t receive_timestamp = substractTicks(m_time_of_transfer, one_frame_in_ticks); 
     1103         
     1104        if(receive_timestamp<0) { 
     1105            debugWarning("receive ts < 0.0 : %lld, m_time_of_transfer= %llu, one_frame_in_ticks=%lld\n", 
     1106             receive_timestamp, m_time_of_transfer, one_frame_in_ticks); 
     1107        } 
     1108        if(receive_timestamp>(128L*TICKS_PER_SECOND)) { 
     1109            debugWarning("receive ts > 128L*TICKS_PER_SECOND : %lld, m_time_of_transfer= %llu, one_frame_in_ticks=%lld\n", 
     1110             receive_timestamp, m_time_of_transfer, one_frame_in_ticks); 
     1111        } 
     1112         
     1113        for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     1114                it != m_ReceiveProcessors.end(); 
     1115                ++it ) { 
     1116 
     1117            if(!(*it)->getFramesDry(m_period, receive_timestamp)) { 
     1118                    debugOutput(DEBUG_LEVEL_VERBOSE,"could not getFrames(%u, %11llu) from stream processor (%p)\n", 
     1119                            m_period, m_time_of_transfer,*it); 
     1120                    return false; // buffer underrun 
     1121            } 
     1122 
     1123        } 
     1124    } else { 
     1125        for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
     1126                it != m_TransmitProcessors.end(); 
     1127                ++it ) { 
     1128            // FIXME: in the SPM it would be nice to have system time instead of 
     1129            //        1394 time 
     1130            float rate=m_SyncSource->getTicksPerFrame(); 
     1131            int64_t one_ringbuffer_in_ticks=(int64_t)(((float)(m_nb_buffers*m_period))*rate); 
     1132 
     1133            // the data we are putting into the buffer is intended to be transmitted 
     1134            // one ringbuffer size after it has been received 
     1135            int64_t transmit_timestamp = addTicks(m_time_of_transfer, one_ringbuffer_in_ticks); 
     1136 
     1137            if(!(*it)->putFramesDry(m_period, transmit_timestamp)) { 
     1138                debugOutput(DEBUG_LEVEL_VERBOSE, "could not putFrames(%u,%llu) to stream processor (%p)\n", 
     1139                        m_period, transmit_timestamp, *it); 
    9571140                return false; // buffer overrun 
    9581141            } 
  • branches/ppalmers-streaming/src/libstreaming/StreamProcessorManager.h

    r445 r703  
    8787    bool transfer(); ///< transfer the buffer contents from/to client 
    8888    bool transfer(enum StreamProcessor::EProcessorType); ///< transfer the buffer contents from/to client (single processor type) 
     89     
     90    bool dryRun(); 
     91    bool dryRun(enum StreamProcessor::EProcessorType); 
    8992 
    9093    int getDelayedUsecs() {return m_delayed_usecs;}; 
     
    9396 
    9497private: 
     98    void resetXrunCounters(); 
     99 
    95100    int m_delayed_usecs; 
    96101    // this stores the time at which the next transfer should occur