Changeset 722

Show
Ignore:
Timestamp:
11/24/07 09:57:25 (13 years ago)
Author:
ppalmers
Message:

more rewrite of streaming

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • branches/ppalmers-streaming/src/dice/dice_avdevice.cpp

    r715 r722  
    448448DiceAvDevice::prepare() { 
    449449    // prepare receive SP's 
    450     for (unsigned int i=0;i<m_nb_tx;i++) { 
     450//     for (unsigned int i=0;i<m_nb_tx;i++) { 
     451    for (unsigned int i=0;i<1;i++) { 
    451452        fb_quadlet_t nb_audio; 
    452453        fb_quadlet_t nb_midi; 
     
    534535 
    535536    // prepare transmit SP's 
    536     for (unsigned int i=0;i<m_nb_rx;i++) { 
     537//     for (unsigned int i=0;i<m_nb_rx;i++) { 
     538    for (unsigned int i=0;i<1;i++) { 
    537539        fb_quadlet_t nb_audio; 
    538540        fb_quadlet_t nb_midi; 
  • branches/ppalmers-streaming/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.cpp

    r720 r722  
    9797 * @param cycle  
    9898 * @param dropped  
    99  * @return true if this is a valid packet, false if not 
    100  */ 
    101 bool 
     99 * @return  
     100 */ 
     101enum StreamProcessor::eChildReturnValue 
    102102AmdtpReceiveStreamProcessor::processPacketHeader(unsigned char *data, unsigned int length, 
    103103                  unsigned char channel, unsigned char tag, unsigned char sy, 
     
    106106    struct iec61883_packet *packet = (struct iec61883_packet *) data; 
    107107    assert(packet); 
    108     bool retval = (packet->syt != 0xFFFF) && 
     108    bool ok = (packet->syt != 0xFFFF) && 
    109109                  (packet->fdf != 0xFF) && 
    110110                  (packet->fmt == 0x10) && 
    111111                  (packet->dbs > 0) && 
    112112                  (length >= 2*sizeof(quadlet_t)); 
    113     if(retval) { 
     113    if(ok) { 
    114114        uint64_t now = m_handler->getCycleTimer(); 
    115115        //=> convert the SYT to a full timestamp in ticks 
     
    117117                                              cycle, now); 
    118118    } 
    119     return retval
     119    return (ok ? eCRV_OK : eCRV_Invalid )
    120120} 
    121121 
     
    130130 * @param cycle  
    131131 * @param dropped  
    132  * @return true if successful, false if xrun 
    133  */ 
    134 bool 
     132 * @return  
     133 */ 
     134enum StreamProcessor::eChildReturnValue 
    135135AmdtpReceiveStreamProcessor::processPacketData(unsigned char *data, unsigned int length, 
    136136                  unsigned char channel, unsigned char tag, unsigned char sy, 
     
    158158        // process all ports that should be handled on a per-packet base 
    159159        // this is MIDI for AMDTP (due to the need of DBC) 
    160         if (!decodePacketPorts((quadlet_t *)(data+8), nevents, packet->dbc)) { 
    161             debugWarning("Problem decoding Packet Ports\n"); 
     160        if(isRunning()) { 
     161            if (!decodePacketPorts((quadlet_t *)(data+8), nevents, packet->dbc)) { 
     162                debugWarning("Problem decoding Packet Ports\n"); 
     163            } 
    162164        } 
    163         return true
     165        return eCRV_OK
    164166    } else { 
    165         return false
     167        return eCRV_XRun
    166168    } 
    167169} 
  • branches/ppalmers-streaming/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.h

    r720 r722  
    7878    virtual ~AmdtpReceiveStreamProcessor() {}; 
    7979 
    80     bool processPacketHeader(unsigned char *data, unsigned int length, 
     80    enum eChildReturnValue processPacketHeader(unsigned char *data, unsigned int length, 
    8181                  unsigned char channel, unsigned char tag, unsigned char sy, 
    8282                  unsigned int cycle, unsigned int dropped); 
    83     bool processPacketData(unsigned char *data, unsigned int length, 
     83    enum eChildReturnValue processPacketData(unsigned char *data, unsigned int length, 
    8484                  unsigned char channel, unsigned char tag, unsigned char sy, 
    8585                  unsigned int cycle, unsigned int dropped); 
  • branches/ppalmers-streaming/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp

    r721 r722  
    4848{} 
    4949 
    50 bool 
     50enum StreamProcessor::eChildReturnValue 
    5151AmdtpTransmitStreamProcessor::generatePacketHeader ( 
    5252    unsigned char *data, unsigned int *length, 
     
    9494    // given by TRANSMIT_TRANSFER_DELAY (in ticks), but we can send 
    9595    // packets early if we want to. (not completely according to spec) 
    96     const int max_cycles_to_transmit_early = 5
     96    const int max_cycles_to_transmit_early = 2
    9797 
    9898try_block_of_frames: 
     
    129129    cycles_until_transmit = diffCycles ( transmit_at_cycle, cycle ); 
    130130 
    131     debugOutput ( DEBUG_LEVEL_VERY_VERBOSE, 
    132                 "Gen HDR: CY=%04u, TC=%04u, CUT=%04d, TST=%011llu (%04u), TSP=%011llu (%04u)\n", 
    133                 cycle, 
    134                 transmit_at_cycle, cycles_until_transmit, 
    135                 transmit_at_time, ( unsigned int ) TICKS_TO_CYCLES ( transmit_at_time ), 
    136                 presentation_time, ( unsigned int ) TICKS_TO_CYCLES ( presentation_time ) ); 
    137  
     131    if (dropped) { 
     132        debugOutput ( DEBUG_LEVEL_VERBOSE, 
     133                    "Gen HDR: CY=%04u, TC=%04u, CUT=%04d, TST=%011llu (%04u), TSP=%011llu (%04u)\n", 
     134                    cycle, 
     135                    transmit_at_cycle, cycles_until_transmit, 
     136                    transmit_at_time, ( unsigned int ) TICKS_TO_CYCLES ( transmit_at_time ), 
     137                    presentation_time, ( unsigned int ) TICKS_TO_CYCLES ( presentation_time ) ); 
     138    } 
    138139    // two different options: 
    139140    // 1) there are not enough frames for one packet 
     
    154155                        fc, cycle, transmit_at_cycle, cycles_until_transmit ); 
    155156            // we are too late 
    156             // meaning that we in some sort of xrun state 
    157             // signal xrun situation ??HERE?? 
    158             m_xruns++; 
    159             // we send an empty packet on this cycle 
    160             return false; 
     157            return eCRV_XRun; 
    161158        } 
    162159        else 
     
    166163                        fc, cycle, transmit_at_cycle, cycles_until_transmit ); 
    167164            // there is still time left to send the packet 
    168             // we want the system to give this packet another go 
    169     //             goto try_packet_again; // UGLY but effective 
    170             // unfortunatly the try_again doesn't work very well, 
    171             // so we'll have to either usleep(one cycle) and goto try_block_of_frames 
    172  
    173             // or just fill this with an empty packet 
    174             // if we have to do this too often, the presentation time will 
    175             // get too close and we're in trouble 
    176             return false; 
     165            // we want the system to give this packet another go at a later time instant 
     166            return eCRV_Again; 
    177167        } 
    178168    } 
     
    195185        //         get next block of frames and repeat 
    196186 
    197         if ( cycles_until_transmit <= max_cycles_to_transmit_early ) 
    198         { 
    199             // it's time send the packet 
    200             m_dbc += fillDataPacketHeader ( packet, length, m_last_timestamp ); 
    201             return true; 
    202         } 
    203         else if ( cycles_until_transmit < 0 ) 
     187        if(cycles_until_transmit < 0) 
    204188        { 
    205189            // we are too late 
    206             debugOutput ( DEBUG_LEVEL_VERBOSE, 
     190            debugOutput(DEBUG_LEVEL_VERBOSE, 
    207191                        "Too late: CY=%04u, TC=%04u, CUT=%04d, TSP=%011llu (%04u)\n", 
    208192                        cycle, 
    209193                        transmit_at_cycle, cycles_until_transmit, 
    210                         presentation_time, ( unsigned int ) TICKS_TO_CYCLES ( presentation_time ) ); 
     194                        presentation_time, (unsigned int)TICKS_TO_CYCLES(presentation_time) ); 
    211195 
    212196            // however, if we can send this sufficiently before the presentation 
     
    214198            // NOTE: dangerous since the device has no way of reporting that it didn't get 
    215199            //       this packet on time. 
    216             if ( cycles_until_presentation <= min_cycles_before_presentation
     200            if(cycles_until_presentation >= min_cycles_before_presentation
    217201            { 
    218202                // we are not that late and can still try to transmit the packet 
    219                 m_dbc += fillDataPacketHeader ( packet, length, m_last_timestamp ); 
    220                 return true
     203                m_dbc += fillDataPacketHeader(packet, length, m_last_timestamp); 
     204                return eCRV_Packet
    221205            } 
    222206            else   // definitely too late 
    223207            { 
    224                 // remove the samples 
    225                 m_data_buffer->dropFrames ( m_syt_interval ); 
    226                 // signal some xrun situation ??HERE?? 
    227                 m_xruns++; 
    228                 // try a new block of frames 
    229                 goto try_block_of_frames; // UGLY but effective 
    230             } 
     208                return eCRV_XRun; 
     209            } 
     210        } 
     211        else if(cycles_until_transmit <= max_cycles_to_transmit_early) 
     212        { 
     213            // it's time send the packet 
     214            m_dbc += fillDataPacketHeader(packet, length, m_last_timestamp); 
     215            return eCRV_Packet; 
    231216        } 
    232217        else 
     
    250235#endif 
    251236            // we are too early, send only an empty packet 
    252             return false
    253         } 
    254     } 
    255     return true
    256 } 
    257  
    258 bool 
     237            return eCRV_EmptyPacket
     238        } 
     239    } 
     240    return eCRV_Invalid
     241} 
     242 
     243enum StreamProcessor::eChildReturnValue 
    259244AmdtpTransmitStreamProcessor::generatePacketData ( 
    260245    unsigned char *data, unsigned int *length, 
     
    273258        debugOutput ( DEBUG_LEVEL_VERY_VERBOSE, "XMIT DATA: TSP=%011llu (%04u)\n", 
    274259                    cycle, m_last_timestamp, ( unsigned int ) TICKS_TO_CYCLES ( m_last_timestamp ) ); 
    275         return true; 
    276     } 
    277     else 
    278     { 
    279         return false; 
    280     } 
    281 
    282  
    283 bool 
     260        return eCRV_OK; 
     261    } 
     262    else return eCRV_XRun; 
     263 
     264
     265 
     266enum StreamProcessor::eChildReturnValue 
    284267AmdtpTransmitStreamProcessor::generateSilentPacketHeader ( 
    285268    unsigned char *data, unsigned int *length, 
     
    308291 
    309292    m_dbc += fillNoDataPacketHeader ( packet, length ); 
    310     return true
    311 } 
    312  
    313 bool 
     293    return eCRV_OK
     294} 
     295 
     296enum StreamProcessor::eChildReturnValue 
    314297AmdtpTransmitStreamProcessor::generateSilentPacketData ( 
    315298    unsigned char *data, unsigned int *length, 
     
    317300    int cycle, unsigned int dropped, unsigned int max_length ) 
    318301{ 
    319     return true; // no need to do anything 
     302    return eCRV_OK; // no need to do anything 
    320303} 
    321304 
  • branches/ppalmers-streaming/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.h

    r720 r722  
    8080    virtual ~AmdtpTransmitStreamProcessor() {}; 
    8181 
    82     bool generatePacketHeader(unsigned char *data, unsigned int *length, 
     82    enum eChildReturnValue generatePacketHeader(unsigned char *data, unsigned int *length, 
    8383                              unsigned char *tag, unsigned char *sy, 
    8484                              int cycle, unsigned int dropped, unsigned int max_length); 
    85     bool generatePacketData(unsigned char *data, unsigned int *length, 
     85    enum eChildReturnValue generatePacketData(unsigned char *data, unsigned int *length, 
    8686                            unsigned char *tag, unsigned char *sy, 
    8787                            int cycle, unsigned int dropped, unsigned int max_length); 
    88     bool generateSilentPacketHeader(unsigned char *data, unsigned int *length, 
     88    enum eChildReturnValue generateSilentPacketHeader(unsigned char *data, unsigned int *length, 
    8989                                    unsigned char *tag, unsigned char *sy, 
    9090                                    int cycle, unsigned int dropped, unsigned int max_length); 
    91     bool generateSilentPacketData(unsigned char *data, unsigned int *length, 
     91    enum eChildReturnValue generateSilentPacketData(unsigned char *data, unsigned int *length, 
    9292                                  unsigned char *tag, unsigned char *sy, 
    9393                                  int cycle, unsigned int dropped, unsigned int max_length); 
  • branches/ppalmers-streaming/src/libstreaming/generic/StreamProcessor.cpp

    r721 r722  
    4141    , m_next_state( ePS_Invalid ) 
    4242    , m_cycle_to_switch_state( 0 ) 
    43     , m_xruns( 0 ) 
    4443    , m_manager( NULL ) 
    4544    , m_ticks_per_frame( 0 ) 
    46     , m_last_cycle( 0
     45    , m_last_cycle( -1
    4746    , m_sync_delay( 0 ) 
     47    , m_in_xrun( false ) 
    4848    , m_last_timestamp(0) 
    4949    , m_last_timestamp2(0) 
     
    166166    unsigned int fc = m_data_buffer->getFrameCounter(); 
    167167    if (getType() == ePT_Receive) { 
    168         can_transfer = fc >= (int) nbframes
     168        can_transfer = (fc >= nbframes)
    169169    } else { 
    170170        // there has to be enough space to put the frames in 
     
    193193                           unsigned char channel, unsigned char tag, unsigned char sy, 
    194194                           unsigned int cycle, unsigned int dropped) { 
    195  
    196     int dropped_cycles = diffCycles(cycle, m_last_cycle) - 1; 
    197     if (dropped_cycles < 0) debugWarning("(%p) dropped < 1 (%d)\n", this, dropped_cycles); 
    198     else m_dropped += dropped_cycles; 
    199     if (dropped_cycles > 0) debugWarning("(%p) dropped %d packets on cycle %u\n", this, dropped_cycles, cycle); 
    200     m_last_cycle = cycle; 
     195    int dropped_cycles = 0; 
     196    if (m_last_cycle != (int)cycle && m_last_cycle != -1) { 
     197        dropped_cycles = diffCycles(cycle, m_last_cycle) - 1; 
     198        if (dropped_cycles < 0) debugWarning("(%p) dropped < 1 (%d)\n", this, dropped_cycles); 
     199        if (dropped_cycles > 0) { 
     200            debugWarning("(%p) dropped %d packets on cycle %u\n", this, dropped_cycles, cycle); 
     201            m_dropped += dropped_cycles; 
     202        } 
     203        m_last_cycle = cycle; 
     204    } 
    201205 
    202206    // bypass based upon state 
     
    208212        return RAW1394_ISO_DEFER; 
    209213    } 
    210  
    211     // normal processing 
    212     enum raw1394_iso_disposition retval = RAW1394_ISO_OK; 
    213214 
    214215    // store the previous timestamp 
     
    254255 
    255256    // check the packet header 
    256     if (processPacketHeader(data, length, channel, tag, sy, cycle, dropped_cycles)) { 
     257    enum eChildReturnValue result = processPacketHeader(data, length, channel, tag, sy, cycle, dropped_cycles); 
     258    if (result == eCRV_OK) { 
    257259        debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "RECV: CY=%04u TS=%011llu\n", 
    258260                cycle, m_last_timestamp); 
     
    301303            debugWarning("(%p) Correcting timestamp for dropped cycles, discarding packet...\n", this); 
    302304            m_data_buffer->setBufferTailTimestamp(m_last_timestamp); 
    303             // we don't want this sample to be written 
    304             return RAW1394_ISO_OK; 
    305         } 
    306  
    307         // for all states that reach this we are allowed to 
    308         // do protocol specific data reception 
    309         bool ok = processPacketData(data, length, channel, tag, sy, cycle, dropped_cycles); 
    310  
    311         // if an xrun occured, switch to the dryRunning state and 
    312         // allow for the xrun to be picked up 
    313         if (!ok) { 
    314             debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to DryRunning due to xrun\n"); 
    315             m_next_state = ePS_DryRunning; 
     305 
     306            // this is an xrun situation 
     307            m_in_xrun = true; 
     308            debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to WaitingForStreamDisable due to dropped packet xrun\n"); 
     309            m_cycle_to_switch_state = cycle + 1; // switch in the next cycle 
     310            m_next_state = ePS_WaitingForStreamDisable; 
    316311            // execute the requested change 
    317312            if (!updateState()) { // we are allowed to change the state directly 
     
    321316            return RAW1394_ISO_DEFER; 
    322317        } 
     318 
     319        // for all states that reach this we are allowed to 
     320        // do protocol specific data reception 
     321        enum eChildReturnValue result2 = processPacketData(data, length, channel, tag, sy, cycle, dropped_cycles); 
     322 
     323        // if an xrun occured, switch to the dryRunning state and 
     324        // allow for the xrun to be picked up 
     325        if (result2 == eCRV_XRun) { 
     326            m_in_xrun = true; 
     327            debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to WaitingForStreamDisable due to data xrun\n"); 
     328            m_cycle_to_switch_state = cycle+1; // switch in the next cycle 
     329            m_next_state = ePS_WaitingForStreamDisable; 
     330            // execute the requested change 
     331            if (!updateState()) { // we are allowed to change the state directly 
     332                debugError("Could not update state!\n"); 
     333                return RAW1394_ISO_ERROR; 
     334            } 
     335            return RAW1394_ISO_DEFER; 
     336        } else if(result2 == eCRV_OK) { 
     337            // no problem here 
     338            return RAW1394_ISO_OK; 
     339        } else { 
     340            debugError("Invalid response\n"); 
     341            return RAW1394_ISO_ERROR; 
     342        } 
     343    } else if(result == eCRV_Invalid) { 
     344        // apparently we don't have to do anything when the packets are not valid 
     345        return RAW1394_ISO_OK; 
    323346    } else { 
    324         // apparently we don't have to do anything when the packets are not valid 
    325     } 
    326     return retval; 
     347        debugError("Invalid response\n"); 
     348        return RAW1394_ISO_ERROR; 
     349    } 
     350    debugError("reached the unreachable\n"); 
     351    return RAW1394_ISO_ERROR; 
    327352} 
    328353 
     
    338363    } 
    339364 
    340     int dropped_cycles = diffCycles(cycle, m_last_cycle) - 1; 
    341     if (dropped_cycles < 0) debugWarning("(%p) dropped < 1 (%d)\n", this, dropped_cycles); 
    342     else m_dropped += dropped_cycles; 
    343     if (dropped_cycles > 0) debugWarning("(%p) dropped %d packets on cycle %u\n", this, dropped_cycles, cycle); 
    344     m_last_cycle = cycle; 
     365    int dropped_cycles = 0; 
     366    if (m_last_cycle != cycle && m_last_cycle != -1) { 
     367        dropped_cycles = diffCycles(cycle, m_last_cycle) - 1; 
     368        if (dropped_cycles < 0) debugWarning("(%p) dropped < 1 (%d)\n", this, dropped_cycles); 
     369        if (dropped_cycles > 0) { 
     370            debugWarning("(%p) dropped %d packets on cycle %u\n", this, dropped_cycles, cycle); 
     371            m_dropped += dropped_cycles; 
     372        } 
     373        m_last_cycle = cycle; 
     374    } 
    345375 
    346376    // bypass based upon state 
     
    431461    else if(m_state == ePS_Running) { 
    432462        // check the packet header 
    433         if (generatePacketHeader(data, length, tag, sy, cycle, dropped_cycles, max_length)) { 
     463        enum eChildReturnValue result = generatePacketHeader(data, length, tag, sy, cycle, dropped_cycles, max_length); 
     464        if (result == eCRV_Packet) { 
    434465            debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "XMIT: CY=%04u TS=%011llu\n", 
    435466                    cycle, m_last_timestamp); 
     
    450481            } 
    451482 
    452             bool ok = generatePacketData(data, length, tag, sy, cycle, dropped_cycles, max_length); 
     483            enum eChildReturnValue result2 = generatePacketData(data, length, tag, sy, cycle, dropped_cycles, max_length); 
    453484            // if an xrun occured, switch to the dryRunning state and 
    454485            // allow for the xrun to be picked up 
    455             if (!ok) { 
    456                 debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to DryRunning due to xrun\n"); 
    457                 m_next_state = ePS_DryRunning; 
     486            if (result2 == eCRV_XRun) { 
     487                debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to WaitingForStreamDisable due to data xrun\n"); 
     488                m_in_xrun = true; 
     489                m_cycle_to_switch_state = cycle+1; // switch in the next cycle 
     490                m_next_state = ePS_WaitingForStreamDisable; 
    458491                // execute the requested change 
    459492                if (!updateState()) { // we are allowed to change the state directly 
     
    464497            } 
    465498            return RAW1394_ISO_OK; 
    466         } else { // pick up the possible xruns 
    467              
     499        } else if (result == eCRV_XRun) { // pick up the possible xruns 
     500            debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state to WaitingForStreamDisable due to header xrun\n"); 
     501            m_in_xrun = true; 
     502            m_cycle_to_switch_state = cycle+1; // switch in the next cycle 
     503            m_next_state = ePS_WaitingForStreamDisable; 
     504            // execute the requested change 
     505            if (!updateState()) { // we are allowed to change the state directly 
     506                debugError("Could not update state!\n"); 
     507                return RAW1394_ISO_ERROR; 
     508            } 
     509        } else if (result == eCRV_EmptyPacket) { 
     510            if(m_state != m_next_state) { 
     511                debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state from %s to %s\n", 
     512                                                ePSToString(m_state), ePSToString(m_next_state)); 
     513                // execute the requested change 
     514                if (!updateState()) { // we are allowed to change the state directly 
     515                    debugError("Could not update state!\n"); 
     516                    return RAW1394_ISO_ERROR; 
     517                } 
     518            } 
     519            goto send_empty_packet; 
     520        } else if (result == eCRV_Again) { 
     521            debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "have to retry cycle %d\n", cycle); 
     522            if(m_state != m_next_state) { 
     523                debugOutput(DEBUG_LEVEL_VERBOSE, "Should update state from %s to %s\n", 
     524                                                ePSToString(m_state), ePSToString(m_next_state)); 
     525                // execute the requested change 
     526                if (!updateState()) { // we are allowed to change the state directly 
     527                    debugError("Could not update state!\n"); 
     528                    return RAW1394_ISO_ERROR; 
     529                } 
     530            } 
     531            // force some delay 
     532            usleep(125); 
     533            return RAW1394_ISO_AGAIN; 
     534        } else { 
     535            debugError("Invalid return value: %d\n", result); 
     536            return RAW1394_ISO_ERROR; 
    468537        } 
    469538    } 
     
    9681037                m_data_buffer->setBufferTailTimestamp(m_last_timestamp); 
    9691038            } else { 
    970                 // FIXME 
    971                 debugError("Implement\n"); 
     1039                // FIXME: PC=master mode will have to do something here I guess... 
    9721040            } 
    9731041            break; 
     
    10581126            debugOutput(DEBUG_LEVEL_VERBOSE, "StreamProcessor %p started running at cycle %d\n",  
    10591127                                             this, m_last_cycle); 
    1060             m_xruns = 0
     1128            m_in_xrun = false
    10611129            m_data_buffer->setTransparent(false); 
    10621130            break; 
     
    13061374                          (unsigned int)TICKS_TO_OFFSET(now)); 
    13071375    } 
    1308     debugOutputShort( DEBUG_LEVEL_NORMAL, "  Xruns                 : %d\n", m_xruns); 
     1376    debugOutputShort( DEBUG_LEVEL_NORMAL, "  Xruns                 : %s\n", (m_in_xrun ? "True":"False")); 
    13091377    debugOutputShort( DEBUG_LEVEL_NORMAL, "  State                 : %s\n", ePSToString(m_state)); 
    13101378    debugOutputShort( DEBUG_LEVEL_NORMAL, "   Next state           : %s\n", ePSToString(m_next_state)); 
  • branches/ppalmers-streaming/src/libstreaming/generic/StreamProcessor.h

    r721 r722  
    155155 
    156156protected: // the helper receive/transmit functions 
     157    enum eChildReturnValue { 
     158        eCRV_OK, 
     159        eCRV_Invalid, 
     160        eCRV_Packet, 
     161        eCRV_EmptyPacket, 
     162        eCRV_XRun, 
     163        eCRV_Again, 
     164    }; 
    157165    // to be implemented by the children 
    158166    // the following methods are to be implemented by receive SP subclasses 
    159     virtual bool processPacketHeader(unsigned char *data, unsigned int length, 
     167    virtual enum eChildReturnValue processPacketHeader(unsigned char *data, unsigned int length, 
    160168                                     unsigned char channel, unsigned char tag, 
    161169                                     unsigned char sy, unsigned int cycle, 
    162170                                     unsigned int dropped) 
    163         {debugWarning("call not allowed\n"); return false;}; 
    164     virtual bool processPacketData(unsigned char *data, unsigned int length, 
     171        {debugWarning("call not allowed\n"); return eCRV_Invalid;}; 
     172    virtual enum eChildReturnValue processPacketData(unsigned char *data, unsigned int length, 
    165173                                   unsigned char channel, unsigned char tag, 
    166174                                   unsigned char sy, unsigned int cycle, 
    167175                                   unsigned int dropped) 
    168         {debugWarning("call not allowed\n"); return false;}; 
     176        {debugWarning("call not allowed\n"); return eCRV_Invalid;}; 
    169177    virtual bool processReadBlock(char *data, unsigned int nevents, unsigned int offset) 
    170178        {debugWarning("call not allowed\n"); return false;}; 
     
    173181 
    174182    // the following methods are to be implemented by transmit SP subclasses 
    175     virtual bool generatePacketHeader(unsigned char *data, unsigned int *length, 
     183    virtual enum eChildReturnValue generatePacketHeader(unsigned char *data, unsigned int *length, 
    176184                                      unsigned char *tag, unsigned char *sy, 
    177185                                      int cycle, unsigned int dropped, 
    178186                                      unsigned int max_length) 
    179         {debugWarning("call not allowed\n"); return false;}; 
    180     virtual bool generatePacketData(unsigned char *data, unsigned int *length, 
     187        {debugWarning("call not allowed\n"); return eCRV_Invalid;}; 
     188    virtual enum eChildReturnValue generatePacketData(unsigned char *data, unsigned int *length, 
    181189                                    unsigned char *tag, unsigned char *sy, 
    182190                                    int cycle, unsigned int dropped, 
    183191                                    unsigned int max_length) 
    184         {debugWarning("call not allowed\n"); return false;}; 
    185     virtual bool generateSilentPacketHeader(unsigned char *data, unsigned int *length, 
     192        {debugWarning("call not allowed\n"); return eCRV_Invalid;}; 
     193    virtual enum eChildReturnValue generateSilentPacketHeader(unsigned char *data, unsigned int *length, 
    186194                                            unsigned char *tag, unsigned char *sy, 
    187195                                            int cycle, unsigned int dropped, 
    188196                                            unsigned int max_length) 
    189         {debugWarning("call not allowed\n"); return false;}; 
    190     virtual bool generateSilentPacketData(unsigned char *data, unsigned int *length, 
     197        {debugWarning("call not allowed\n"); return eCRV_Invalid;}; 
     198    virtual enum eChildReturnValue generateSilentPacketData(unsigned char *data, unsigned int *length, 
    191199                                          unsigned char *tag, unsigned char *sy, 
    192200                                          int cycle, unsigned int dropped, 
    193201                                          unsigned int max_length) 
    194         {debugWarning("call not allowed\n"); return false;}; 
     202        {debugWarning("call not allowed\n"); return eCRV_Invalid;}; 
    195203    virtual bool processWriteBlock(char *data, unsigned int nevents, unsigned int offset) 
    196204        {debugWarning("call not allowed\n"); return false;}; 
     
    207215 
    208216    // move to private? 
    209     bool xrunOccurred() { return (m_xruns>0); }; // FIXME: m_xruns not updated 
     217    bool xrunOccurred() { return m_in_xrun; }; 
    210218 
    211219protected: // FIXME: move to private 
     
    232240 
    233241protected: 
    234     unsigned int m_xruns; 
    235  
    236242    StreamProcessorManager *m_manager; 
    237243 
     
    367373        int m_last_cycle; 
    368374        int m_sync_delay; 
     375    private: 
     376        bool m_in_xrun; 
    369377 
    370378protected: // SPM related 
  • branches/ppalmers-streaming/src/libstreaming/StreamProcessorManager.cpp

    r721 r722  
    158158    } 
    159159    m_isoManager->setVerboseLevel(getDebugLevel()); 
     160    m_isoManager->setTransmitBufferNbPeriods(getNbBuffers() - 1); 
     161 
    160162    if(!m_isoManager->init()) { 
    161163        debugFatal("Could not initialize IsoHandlerManager\n"); 
     
    243245            it != m_ReceiveProcessors.end(); 
    244246            ++it ) { 
    245         if(!(*it)->startDryRunning(-1)) { 
    246             debugError("Could not put SP %p into the dry-running state\n", *it); 
    247             return false; 
     247        if (!(*it)->isDryRunning()) { 
     248            if(!(*it)->startDryRunning(-1)) { 
     249                debugError("Could not put SP %p into the dry-running state\n", *it); 
     250                return false; 
     251            } 
    248252        } 
    249253    } 
     
    251255            it != m_TransmitProcessors.end(); 
    252256            ++it ) { 
    253         if(!(*it)->startDryRunning(-1)) { 
    254             debugError("Could not put SP %p into the dry-running state\n", *it); 
    255             return false; 
     257        if (!(*it)->isDryRunning()) { 
     258            if(!(*it)->startDryRunning(-1)) { 
     259                debugError("Could not put SP %p into the dry-running state\n", *it); 
     260                return false; 
     261            } 
    256262        } 
    257263    } 
     
    621627bool StreamProcessorManager::waitForPeriod() { 
    622628    int time_till_next_period; 
    623     bool xrun_occurred=false; 
     629    bool xrun_occurred = false; 
    624630 
    625631    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "enter...\n"); 
     
    649655            xrun_occurred |= (*it)->xrunOccurred(); 
    650656        } 
    651  
    652657        if(xrun_occurred) break; 
    653658 
    654659        // check if we were waked up too soon 
    655         time_till_next_period=m_SyncSource->getTimeUntilNextPeriodSignalUsecs(); 
    656     } 
    657  
    658     debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "delayed for %d usecs...\n", time_till_next_period); 
    659  
    660     // this is to notify the client of the delay 
    661     // that we introduced 
    662     m_delayed_usecs = -time_till_next_period; 
     660        time_till_next_period = m_SyncSource->getTimeUntilNextPeriodSignalUsecs(); 
     661    } 
    663662 
    664663    // we save the 'ideal' time of the transfer at this point, 
     
    672671        m_time_of_transfer); 
    673672 
     673    // normally we can transfer frames at this time, but in some cases this is not true 
     674    // e.g. when there are not enough frames in the receive buffer. 
     675    // however this doesn't have to be a problem, since we can wait some more until we 
     676    // have enough frames. There is only a problem once the ISO xmit doesn't have packets 
     677    // to transmit, or if the receive buffer overflows. These conditions are signaled by 
     678    // the iso threads 
     679    // check if xruns occurred on the Iso side. 
     680    // also check if xruns will occur should we transfer() now 
     681    #ifdef DEBUG 
     682    int waited = -1; 
     683    #endif 
     684    bool ready_for_transfer = false; 
     685    xrun_occurred = false; 
     686    while (!ready_for_transfer && !xrun_occurred) { 
     687        ready_for_transfer = true; 
     688        for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
     689            it != m_ReceiveProcessors.end(); 
     690            ++it ) { 
     691            ready_for_transfer &= ((*it)->canClientTransferFrames(m_period)); 
     692            xrun_occurred |= (*it)->xrunOccurred(); 
     693        } 
     694        for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
     695            it != m_TransmitProcessors.end(); 
     696            ++it ) { 
     697            ready_for_transfer &= ((*it)->canClientTransferFrames(m_period)); 
     698            xrun_occurred |= (*it)->xrunOccurred(); 
     699        } 
     700        usleep(125); // MAGIC: one cycle sleep... 
     701        #ifdef DEBUG 
     702        waited++; 
     703        #endif 
     704    } // we are either ready or an xrun occurred 
     705 
     706    #ifdef DEBUG 
     707    if(waited > 0) { 
     708        debugOutput(DEBUG_LEVEL_VERBOSE, "Waited %d x 125us due to SP not ready for transfer\n", waited); 
     709    } 
     710    #endif 
     711 
     712    // this is to notify the client of the delay that we introduced by waiting 
     713    m_delayed_usecs = - m_SyncSource->getTimeUntilNextPeriodSignalUsecs(); 
     714    debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "delayed for %d usecs...\n", m_delayed_usecs); 
     715 
    674716#ifdef DEBUG 
    675717    int rcv_bf=0, xmt_bf=0; 
     
    687729        m_time_of_transfer, rcv_bf, xmt_bf, rcv_bf+xmt_bf); 
    688730 
    689 #endif 
    690  
    691     xrun_occurred=false; 
    692  
    693731    // check if xruns occurred on the Iso side. 
    694732    // also check if xruns will occur should we transfer() now 
    695  
    696733    for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 
    697734          it != m_ReceiveProcessors.end(); 
    698735          ++it ) { 
    699         // a xrun has occurred on the Iso side 
    700         xrun_occurred |= (*it)->xrunOccurred(); 
    701  
    702         // if this is true, a xrun will occur 
    703         xrun_occurred |= !((*it)->canClientTransferFrames(m_period)); 
    704  
    705 #ifdef DEBUG 
     736 
    706737        if ((*it)->xrunOccurred()) { 
    707             debugWarning("Xrun on RECV SP %p due to ISO xrun\n",*it); 
     738            debugWarning("Xrun on RECV SP %p due to ISO side xrun\n",*it); 
    708739            (*it)->dumpInfo(); 
    709740        } 
    710741        if (!((*it)->canClientTransferFrames(m_period))) { 
    711             debugWarning("Xrun on RECV SP %p due to buffer xrun\n",*it); 
     742            debugWarning("Xrun on RECV SP %p due to buffer side xrun\n",*it); 
    712743            (*it)->dumpInfo(); 
    713744        } 
     745    } 
     746    for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
     747          it != m_TransmitProcessors.end(); 
     748          ++it ) { 
     749        if ((*it)->xrunOccurred()) { 
     750            debugWarning("Xrun on XMIT SP %p due to ISO side xrun\n",*it); 
     751        } 
     752        if (!((*it)->canClientTransferFrames(m_period))) { 
     753            debugWarning("Xrun on XMIT SP %p due to buffer side xrun\n",*it); 
     754        } 
     755    } 
    714756#endif 
    715757 
    716     } 
    717     for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 
    718           it != m_TransmitProcessors.end(); 
    719           ++it ) { 
    720         // a xrun has occurred on the Iso side 
    721         xrun_occurred |= (*it)->xrunOccurred(); 
    722  
    723         // if this is true, a xrun will occur 
    724         xrun_occurred |= !((*it)->canClientTransferFrames(m_period)); 
    725  
    726 #ifdef DEBUG 
    727         if ((*it)->xrunOccurred()) { 
    728             debugWarning("Xrun on XMIT SP %p due to ISO xrun\n",*it); 
    729         } 
    730         if (!((*it)->canClientTransferFrames(m_period))) { 
    731             debugWarning("Xrun on XMIT SP %p due to buffer xrun\n",*it); 
    732         } 
    733 #endif 
    734     } 
    735  
    736758    m_nbperiods++; 
    737  
    738759    // now we can signal the client that we are (should be) ready 
    739760    return !xrun_occurred; 
  • branches/ppalmers-streaming/src/libstreaming/util/IsoHandlerManager.cpp

    r719 r722  
    4141   m_State(E_Created), 
    4242   m_poll_timeout(100), m_poll_fds(0), m_poll_nfds(0), 
    43    m_realtime(false), m_priority(0) 
     43   m_realtime(false), m_priority(0), m_xmit_nb_periods( 1 ) 
    4444{ 
    4545 
     
    4949   m_State(E_Created), 
    5050   m_poll_timeout(1), m_poll_fds(0), m_poll_nfds(0), 
    51    m_realtime(run_rt), m_priority(rt_prio) 
     51   m_realtime(run_rt), m_priority(rt_prio), m_xmit_nb_periods( 1 ) 
    5252{ 
    5353 
     
    400400    if (stream->getStreamType()==IsoStream::eST_Transmit) { 
    401401        // setup the optimal parameters for the raw1394 ISO buffering 
    402         unsigned int packets_per_period=stream->getPacketsPerPeriod(); 
     402        unsigned int packets_per_period = stream->getPacketsPerPeriod(); 
    403403 
    404404#if 1 
     
    410410        unsigned int max_packet_size=MINIMUM_INTERRUPTS_PER_PERIOD * getpagesize() / packets_per_period; 
    411411        if (max_packet_size < stream->getMaxPacketSize()) { 
    412             max_packet_size=stream->getMaxPacketSize(); 
     412            max_packet_size = stream->getMaxPacketSize(); 
    413413        } 
    414414 
     
    418418                    max_packet_size = getpagesize(); 
    419419 
    420          unsigned int irq_interval=packets_per_period / MINIMUM_INTERRUPTS_PER_PERIOD; 
     420         unsigned int irq_interval = packets_per_period / MINIMUM_INTERRUPTS_PER_PERIOD; 
    421421         if(irq_interval <= 0) irq_interval=1; 
    422422#else 
     
    427427 
    428428        // configure it such that we have an irq for every PACKETS_PER_INTERRUPT packets 
    429         unsigned int irq_interval=PACKETS_PER_INTERRUPT; 
     429        unsigned int irq_interval = PACKETS_PER_INTERRUPT; 
    430430 
    431431        // unless the period size doesn't allow this 
    432432        if ((packets_per_period/MINIMUM_INTERRUPTS_PER_PERIOD) < irq_interval) { 
    433             irq_interval=1; 
     433            irq_interval = 1; 
    434434        } 
    435435 
    436436        // FIXME: test 
    437         irq_interval=1; 
     437        irq_interval = 1; 
    438438#warning Using fixed irq_interval 
    439439 
    440         unsigned int max_packet_size=getpagesize() / irq_interval; 
     440        unsigned int max_packet_size = getpagesize() / irq_interval; 
    441441 
    442442        if (max_packet_size < stream->getMaxPacketSize()) { 
    443             max_packet_size=stream->getMaxPacketSize(); 
     443            max_packet_size = stream->getMaxPacketSize(); 
    444444        } 
    445445 
     
    458458        // buffers get transfered, meaning that we should have at least some 
    459459        // margin here 
    460         int buffers=irq_interval * 2; 
    461  
    462         // half a period. the xmit handler will take care of this 
    463 //         int buffers=packets_per_period/4; 
    464  
    465         // NOTE: this is dangerous: what if there is not enough prefill? 
    466 //         if (buffers<10) buffers=10; 
     460//         int buffers=irq_interval * 2; 
     461 
     462        // we should queue up as much as possible 
     463        int buffers = packets_per_period * m_xmit_nb_periods; 
    467464 
    468465        // create the actual handler 
  • branches/ppalmers-streaming/src/libstreaming/util/IsoHandlerManager.h

    r705 r722  
    4343namespace Streaming 
    4444{ 
    45  
    4645class IsoHandler; 
    4746class IsoStream; 
     
    7877        void setPollTimeout(int t) {m_poll_timeout=t;}; ///< set the timeout used for poll() 
    7978        int getPollTimeout() {return m_poll_timeout;};  ///< get the timeout used for poll() 
     79 
     80        void setTransmitBufferNbPeriods(unsigned int t) {m_xmit_nb_periods = t;}; 
     81        int getTransmitBufferNbPeriods() {return m_xmit_nb_periods;}; 
    8082 
    8183        void setVerboseLevel(int l); ///< set the verbose level 
     
    151153        Util::PosixThread *m_isoManagerThread; 
    152154 
     155        // the preferred number of periods to buffer on xmit 
     156        unsigned int m_xmit_nb_periods; 
     157 
    153158        // debug stuff 
    154159        DECLARE_DEBUG_MODULE;