Changeset 722
- Timestamp:
- 11/24/07 09:57:25 (16 years ago)
- Files:
-
- branches/ppalmers-streaming/src/dice/dice_avdevice.cpp (modified) (2 diffs)
- branches/ppalmers-streaming/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.cpp (modified) (5 diffs)
- branches/ppalmers-streaming/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.h (modified) (1 diff)
- branches/ppalmers-streaming/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp (modified) (11 diffs)
- branches/ppalmers-streaming/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.h (modified) (1 diff)
- branches/ppalmers-streaming/src/libstreaming/generic/StreamProcessor.cpp (modified) (14 diffs)
- branches/ppalmers-streaming/src/libstreaming/generic/StreamProcessor.h (modified) (5 diffs)
- branches/ppalmers-streaming/src/libstreaming/StreamProcessorManager.cpp (modified) (7 diffs)
- branches/ppalmers-streaming/src/libstreaming/util/IsoHandlerManager.cpp (modified) (7 diffs)
- branches/ppalmers-streaming/src/libstreaming/util/IsoHandlerManager.h (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/ppalmers-streaming/src/dice/dice_avdevice.cpp
r715 r722 448 448 DiceAvDevice::prepare() { 449 449 // 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++) { 451 452 fb_quadlet_t nb_audio; 452 453 fb_quadlet_t nb_midi; … … 534 535 535 536 // 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++) { 537 539 fb_quadlet_t nb_audio; 538 540 fb_quadlet_t nb_midi; branches/ppalmers-streaming/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.cpp
r720 r722 97 97 * @param cycle 98 98 * @param dropped 99 * @return true if this is a valid packet, false if not100 */ 101 bool 99 * @return 100 */ 101 enum StreamProcessor::eChildReturnValue 102 102 AmdtpReceiveStreamProcessor::processPacketHeader(unsigned char *data, unsigned int length, 103 103 unsigned char channel, unsigned char tag, unsigned char sy, … … 106 106 struct iec61883_packet *packet = (struct iec61883_packet *) data; 107 107 assert(packet); 108 bool retval= (packet->syt != 0xFFFF) &&108 bool ok = (packet->syt != 0xFFFF) && 109 109 (packet->fdf != 0xFF) && 110 110 (packet->fmt == 0x10) && 111 111 (packet->dbs > 0) && 112 112 (length >= 2*sizeof(quadlet_t)); 113 if( retval) {113 if(ok) { 114 114 uint64_t now = m_handler->getCycleTimer(); 115 115 //=> convert the SYT to a full timestamp in ticks … … 117 117 cycle, now); 118 118 } 119 return retval;119 return (ok ? eCRV_OK : eCRV_Invalid ); 120 120 } 121 121 … … 130 130 * @param cycle 131 131 * @param dropped 132 * @return true if successful, false if xrun133 */ 134 bool 132 * @return 133 */ 134 enum StreamProcessor::eChildReturnValue 135 135 AmdtpReceiveStreamProcessor::processPacketData(unsigned char *data, unsigned int length, 136 136 unsigned char channel, unsigned char tag, unsigned char sy, … … 158 158 // process all ports that should be handled on a per-packet base 159 159 // 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 } 162 164 } 163 return true;165 return eCRV_OK; 164 166 } else { 165 return false;167 return eCRV_XRun; 166 168 } 167 169 } branches/ppalmers-streaming/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.h
r720 r722 78 78 virtual ~AmdtpReceiveStreamProcessor() {}; 79 79 80 boolprocessPacketHeader(unsigned char *data, unsigned int length,80 enum eChildReturnValue processPacketHeader(unsigned char *data, unsigned int length, 81 81 unsigned char channel, unsigned char tag, unsigned char sy, 82 82 unsigned int cycle, unsigned int dropped); 83 boolprocessPacketData(unsigned char *data, unsigned int length,83 enum eChildReturnValue processPacketData(unsigned char *data, unsigned int length, 84 84 unsigned char channel, unsigned char tag, unsigned char sy, 85 85 unsigned int cycle, unsigned int dropped); branches/ppalmers-streaming/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp
r721 r722 48 48 {} 49 49 50 bool 50 enum StreamProcessor::eChildReturnValue 51 51 AmdtpTransmitStreamProcessor::generatePacketHeader ( 52 52 unsigned char *data, unsigned int *length, … … 94 94 // given by TRANSMIT_TRANSFER_DELAY (in ticks), but we can send 95 95 // 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; 97 97 98 98 try_block_of_frames: … … 129 129 cycles_until_transmit = diffCycles ( transmit_at_cycle, cycle ); 130 130 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 } 138 139 // two different options: 139 140 // 1) there are not enough frames for one packet … … 154 155 fc, cycle, transmit_at_cycle, cycles_until_transmit ); 155 156 // 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; 161 158 } 162 159 else … … 166 163 fc, cycle, transmit_at_cycle, cycles_until_transmit ); 167 164 // 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; 177 167 } 178 168 } … … 195 185 // get next block of frames and repeat 196 186 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) 204 188 { 205 189 // we are too late 206 debugOutput (DEBUG_LEVEL_VERBOSE,190 debugOutput(DEBUG_LEVEL_VERBOSE, 207 191 "Too late: CY=%04u, TC=%04u, CUT=%04d, TSP=%011llu (%04u)\n", 208 192 cycle, 209 193 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) ); 211 195 212 196 // however, if we can send this sufficiently before the presentation … … 214 198 // NOTE: dangerous since the device has no way of reporting that it didn't get 215 199 // this packet on time. 216 if ( cycles_until_presentation <= min_cycles_before_presentation)200 if(cycles_until_presentation >= min_cycles_before_presentation) 217 201 { 218 202 // 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; 221 205 } 222 206 else // definitely too late 223 207 { 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; 231 216 } 232 217 else … … 250 235 #endif 251 236 // 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 243 enum StreamProcessor::eChildReturnValue 259 244 AmdtpTransmitStreamProcessor::generatePacketData ( 260 245 unsigned char *data, unsigned int *length, … … 273 258 debugOutput ( DEBUG_LEVEL_VERY_VERBOSE, "XMIT DATA: TSP=%011llu (%04u)\n", 274 259 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 266 enum StreamProcessor::eChildReturnValue 284 267 AmdtpTransmitStreamProcessor::generateSilentPacketHeader ( 285 268 unsigned char *data, unsigned int *length, … … 308 291 309 292 m_dbc += fillNoDataPacketHeader ( packet, length ); 310 return true;311 } 312 313 bool 293 return eCRV_OK; 294 } 295 296 enum StreamProcessor::eChildReturnValue 314 297 AmdtpTransmitStreamProcessor::generateSilentPacketData ( 315 298 unsigned char *data, unsigned int *length, … … 317 300 int cycle, unsigned int dropped, unsigned int max_length ) 318 301 { 319 return true; // no need to do anything302 return eCRV_OK; // no need to do anything 320 303 } 321 304 branches/ppalmers-streaming/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.h
r720 r722 80 80 virtual ~AmdtpTransmitStreamProcessor() {}; 81 81 82 boolgeneratePacketHeader(unsigned char *data, unsigned int *length,82 enum eChildReturnValue generatePacketHeader(unsigned char *data, unsigned int *length, 83 83 unsigned char *tag, unsigned char *sy, 84 84 int cycle, unsigned int dropped, unsigned int max_length); 85 boolgeneratePacketData(unsigned char *data, unsigned int *length,85 enum eChildReturnValue generatePacketData(unsigned char *data, unsigned int *length, 86 86 unsigned char *tag, unsigned char *sy, 87 87 int cycle, unsigned int dropped, unsigned int max_length); 88 boolgenerateSilentPacketHeader(unsigned char *data, unsigned int *length,88 enum eChildReturnValue generateSilentPacketHeader(unsigned char *data, unsigned int *length, 89 89 unsigned char *tag, unsigned char *sy, 90 90 int cycle, unsigned int dropped, unsigned int max_length); 91 boolgenerateSilentPacketData(unsigned char *data, unsigned int *length,91 enum eChildReturnValue generateSilentPacketData(unsigned char *data, unsigned int *length, 92 92 unsigned char *tag, unsigned char *sy, 93 93 int cycle, unsigned int dropped, unsigned int max_length); branches/ppalmers-streaming/src/libstreaming/generic/StreamProcessor.cpp
r721 r722 41 41 , m_next_state( ePS_Invalid ) 42 42 , m_cycle_to_switch_state( 0 ) 43 , m_xruns( 0 )44 43 , m_manager( NULL ) 45 44 , m_ticks_per_frame( 0 ) 46 , m_last_cycle( 0)45 , m_last_cycle( -1 ) 47 46 , m_sync_delay( 0 ) 47 , m_in_xrun( false ) 48 48 , m_last_timestamp(0) 49 49 , m_last_timestamp2(0) … … 166 166 unsigned int fc = m_data_buffer->getFrameCounter(); 167 167 if (getType() == ePT_Receive) { 168 can_transfer = fc >= (int) nbframes;168 can_transfer = (fc >= nbframes); 169 169 } else { 170 170 // there has to be enough space to put the frames in … … 193 193 unsigned char channel, unsigned char tag, unsigned char sy, 194 194 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 } 201 205 202 206 // bypass based upon state … … 208 212 return RAW1394_ISO_DEFER; 209 213 } 210 211 // normal processing212 enum raw1394_iso_disposition retval = RAW1394_ISO_OK;213 214 214 215 // store the previous timestamp … … 254 255 255 256 // 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) { 257 259 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "RECV: CY=%04u TS=%011llu\n", 258 260 cycle, m_last_timestamp); … … 301 303 debugWarning("(%p) Correcting timestamp for dropped cycles, discarding packet...\n", this); 302 304 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; 316 311 // execute the requested change 317 312 if (!updateState()) { // we are allowed to change the state directly … … 321 316 return RAW1394_ISO_DEFER; 322 317 } 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; 323 346 } 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; 327 352 } 328 353 … … 338 363 } 339 364 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 } 345 375 346 376 // bypass based upon state … … 431 461 else if(m_state == ePS_Running) { 432 462 // 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) { 434 465 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "XMIT: CY=%04u TS=%011llu\n", 435 466 cycle, m_last_timestamp); … … 450 481 } 451 482 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); 453 484 // if an xrun occured, switch to the dryRunning state and 454 485 // 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; 458 491 // execute the requested change 459 492 if (!updateState()) { // we are allowed to change the state directly … … 464 497 } 465 498 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; 468 537 } 469 538 } … … 968 1037 m_data_buffer->setBufferTailTimestamp(m_last_timestamp); 969 1038 } else { 970 // FIXME 971 debugError("Implement\n"); 1039 // FIXME: PC=master mode will have to do something here I guess... 972 1040 } 973 1041 break; … … 1058 1126 debugOutput(DEBUG_LEVEL_VERBOSE, "StreamProcessor %p started running at cycle %d\n", 1059 1127 this, m_last_cycle); 1060 m_ xruns = 0;1128 m_in_xrun = false; 1061 1129 m_data_buffer->setTransparent(false); 1062 1130 break; … … 1306 1374 (unsigned int)TICKS_TO_OFFSET(now)); 1307 1375 } 1308 debugOutputShort( DEBUG_LEVEL_NORMAL, " Xruns : % d\n", m_xruns);1376 debugOutputShort( DEBUG_LEVEL_NORMAL, " Xruns : %s\n", (m_in_xrun ? "True":"False")); 1309 1377 debugOutputShort( DEBUG_LEVEL_NORMAL, " State : %s\n", ePSToString(m_state)); 1310 1378 debugOutputShort( DEBUG_LEVEL_NORMAL, " Next state : %s\n", ePSToString(m_next_state)); branches/ppalmers-streaming/src/libstreaming/generic/StreamProcessor.h
r721 r722 155 155 156 156 protected: // 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 }; 157 165 // to be implemented by the children 158 166 // the following methods are to be implemented by receive SP subclasses 159 virtual boolprocessPacketHeader(unsigned char *data, unsigned int length,167 virtual enum eChildReturnValue processPacketHeader(unsigned char *data, unsigned int length, 160 168 unsigned char channel, unsigned char tag, 161 169 unsigned char sy, unsigned int cycle, 162 170 unsigned int dropped) 163 {debugWarning("call not allowed\n"); return false;};164 virtual boolprocessPacketData(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, 165 173 unsigned char channel, unsigned char tag, 166 174 unsigned char sy, unsigned int cycle, 167 175 unsigned int dropped) 168 {debugWarning("call not allowed\n"); return false;};176 {debugWarning("call not allowed\n"); return eCRV_Invalid;}; 169 177 virtual bool processReadBlock(char *data, unsigned int nevents, unsigned int offset) 170 178 {debugWarning("call not allowed\n"); return false;}; … … 173 181 174 182 // the following methods are to be implemented by transmit SP subclasses 175 virtual boolgeneratePacketHeader(unsigned char *data, unsigned int *length,183 virtual enum eChildReturnValue generatePacketHeader(unsigned char *data, unsigned int *length, 176 184 unsigned char *tag, unsigned char *sy, 177 185 int cycle, unsigned int dropped, 178 186 unsigned int max_length) 179 {debugWarning("call not allowed\n"); return false;};180 virtual boolgeneratePacketData(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, 181 189 unsigned char *tag, unsigned char *sy, 182 190 int cycle, unsigned int dropped, 183 191 unsigned int max_length) 184 {debugWarning("call not allowed\n"); return false;};185 virtual boolgenerateSilentPacketHeader(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, 186 194 unsigned char *tag, unsigned char *sy, 187 195 int cycle, unsigned int dropped, 188 196 unsigned int max_length) 189 {debugWarning("call not allowed\n"); return false;};190 virtual boolgenerateSilentPacketData(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, 191 199 unsigned char *tag, unsigned char *sy, 192 200 int cycle, unsigned int dropped, 193 201 unsigned int max_length) 194 {debugWarning("call not allowed\n"); return false;};202 {debugWarning("call not allowed\n"); return eCRV_Invalid;}; 195 203 virtual bool processWriteBlock(char *data, unsigned int nevents, unsigned int offset) 196 204 {debugWarning("call not allowed\n"); return false;}; … … 207 215 208 216 // move to private? 209 bool xrunOccurred() { return (m_xruns>0); }; // FIXME: m_xruns not updated217 bool xrunOccurred() { return m_in_xrun; }; 210 218 211 219 protected: // FIXME: move to private … … 232 240 233 241 protected: 234 unsigned int m_xruns;235 236 242 StreamProcessorManager *m_manager; 237 243 … … 367 373 int m_last_cycle; 368 374 int m_sync_delay; 375 private: 376 bool m_in_xrun; 369 377 370 378 protected: // SPM related branches/ppalmers-streaming/src/libstreaming/StreamProcessorManager.cpp
r721 r722 158 158 } 159 159 m_isoManager->setVerboseLevel(getDebugLevel()); 160 m_isoManager->setTransmitBufferNbPeriods(getNbBuffers() - 1); 161 160 162 if(!m_isoManager->init()) { 161 163 debugFatal("Could not initialize IsoHandlerManager\n"); … … 243 245 it != m_ReceiveProcessors.end(); 244 246 ++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 } 248 252 } 249 253 } … … 251 255 it != m_TransmitProcessors.end(); 252 256 ++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 } 256 262 } 257 263 } … … 621 627 bool StreamProcessorManager::waitForPeriod() { 622 628 int time_till_next_period; 623 bool xrun_occurred =false;629 bool xrun_occurred = false; 624 630 625 631 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "enter...\n"); … … 649 655 xrun_occurred |= (*it)->xrunOccurred(); 650 656 } 651 652 657 if(xrun_occurred) break; 653 658 654 659 // 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 } 663 662 664 663 // we save the 'ideal' time of the transfer at this point, … … 672 671 m_time_of_transfer); 673 672 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 674 716 #ifdef DEBUG 675 717 int rcv_bf=0, xmt_bf=0; … … 687 729 m_time_of_transfer, rcv_bf, xmt_bf, rcv_bf+xmt_bf); 688 730 689 #endif690 691 xrun_occurred=false;692 693 731 // check if xruns occurred on the Iso side. 694 732 // also check if xruns will occur should we transfer() now 695 696 733 for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 697 734 it != m_ReceiveProcessors.end(); 698 735 ++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 706 737 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); 708 739 (*it)->dumpInfo(); 709 740 } 710 741 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); 712 743 (*it)->dumpInfo(); 713 744 } 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 } 714 756 #endif 715 757 716 }717 for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();718 it != m_TransmitProcessors.end();719 ++it ) {720 // a xrun has occurred on the Iso side721 xrun_occurred |= (*it)->xrunOccurred();722 723 // if this is true, a xrun will occur724 xrun_occurred |= !((*it)->canClientTransferFrames(m_period));725 726 #ifdef DEBUG727 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 #endif734 }735 736 758 m_nbperiods++; 737 738 759 // now we can signal the client that we are (should be) ready 739 760 return !xrun_occurred; branches/ppalmers-streaming/src/libstreaming/util/IsoHandlerManager.cpp
r719 r722 41 41 m_State(E_Created), 42 42 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 ) 44 44 { 45 45 … … 49 49 m_State(E_Created), 50 50 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 ) 52 52 { 53 53 … … 400 400 if (stream->getStreamType()==IsoStream::eST_Transmit) { 401 401 // 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(); 403 403 404 404 #if 1 … … 410 410 unsigned int max_packet_size=MINIMUM_INTERRUPTS_PER_PERIOD * getpagesize() / packets_per_period; 411 411 if (max_packet_size < stream->getMaxPacketSize()) { 412 max_packet_size =stream->getMaxPacketSize();412 max_packet_size = stream->getMaxPacketSize(); 413 413 } 414 414 … … 418 418 max_packet_size = getpagesize(); 419 419 420 unsigned int irq_interval =packets_per_period / MINIMUM_INTERRUPTS_PER_PERIOD;420 unsigned int irq_interval = packets_per_period / MINIMUM_INTERRUPTS_PER_PERIOD; 421 421 if(irq_interval <= 0) irq_interval=1; 422 422 #else … … 427 427 428 428 // 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; 430 430 431 431 // unless the period size doesn't allow this 432 432 if ((packets_per_period/MINIMUM_INTERRUPTS_PER_PERIOD) < irq_interval) { 433 irq_interval =1;433 irq_interval = 1; 434 434 } 435 435 436 436 // FIXME: test 437 irq_interval =1;437 irq_interval = 1; 438 438 #warning Using fixed irq_interval 439 439 440 unsigned int max_packet_size =getpagesize() / irq_interval;440 unsigned int max_packet_size = getpagesize() / irq_interval; 441 441 442 442 if (max_packet_size < stream->getMaxPacketSize()) { 443 max_packet_size =stream->getMaxPacketSize();443 max_packet_size = stream->getMaxPacketSize(); 444 444 } 445 445 … … 458 458 // buffers get transfered, meaning that we should have at least some 459 459 // 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; 467 464 468 465 // create the actual handler branches/ppalmers-streaming/src/libstreaming/util/IsoHandlerManager.h
r705 r722 43 43 namespace Streaming 44 44 { 45 46 45 class IsoHandler; 47 46 class IsoStream; … … 78 77 void setPollTimeout(int t) {m_poll_timeout=t;}; ///< set the timeout used for poll() 79 78 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;}; 80 82 81 83 void setVerboseLevel(int l); ///< set the verbose level … … 151 153 Util::PosixThread *m_isoManagerThread; 152 154 155 // the preferred number of periods to buffer on xmit 156 unsigned int m_xmit_nb_periods; 157 153 158 // debug stuff 154 159 DECLARE_DEBUG_MODULE;