Changeset 385
- Timestamp:
- 02/01/07 15:02:24 (16 years ago)
- Files:
-
- branches/streaming-rework/src/debugmodule/debugmodule.cpp (modified) (1 diff)
- branches/streaming-rework/src/libstreaming/AmdtpStreamProcessor.cpp (modified) (23 diffs)
- branches/streaming-rework/src/libstreaming/cycletimer.h (modified) (1 diff)
- branches/streaming-rework/src/libstreaming/freebob_streaming.cpp (modified) (3 diffs)
- branches/streaming-rework/src/libstreaming/IsoHandler.cpp (modified) (1 diff)
- branches/streaming-rework/src/libstreaming/IsoHandlerManager.cpp (modified) (4 diffs)
- branches/streaming-rework/src/libstreaming/StreamProcessor.cpp (modified) (12 diffs)
- branches/streaming-rework/src/libstreaming/StreamProcessor.h (modified) (6 diffs)
- branches/streaming-rework/src/libstreaming/StreamProcessorManager.cpp (modified) (17 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
branches/streaming-rework/src/debugmodule/debugmodule.cpp
r384 r385 276 276 /* called WITHOUT the mb_write_lock */ 277 277 while (mb_outbuffer != mb_inbuffer) { 278 fputs(mb_buffers[mb_outbuffer], std out);278 fputs(mb_buffers[mb_outbuffer], stderr); 279 279 mb_outbuffer = MB_NEXT(mb_outbuffer); 280 280 } branches/streaming-rework/src/libstreaming/AmdtpStreamProcessor.cpp
r384 r385 38 38 #define RECEIVE_DLL_INTEGRATION_COEFFICIENT 0.015 39 39 40 #define RECEIVE_PROCESSING_DELAY 5120040 #define RECEIVE_PROCESSING_DELAY (10000) 41 41 42 42 // in ticks 43 #define TRANSMIT_TRANSFER_DELAY 1000 44 #define TRANSMIT_ADVANCE_CYCLES 10 45 46 //#define DO_SYT_SYNC 43 #define TRANSMIT_TRANSFER_DELAY 9000U 44 // the number of cycles to send a packet in advance of it's timestamp 45 #define TRANSMIT_ADVANCE_CYCLES 1U 47 46 48 47 namespace FreebobStreaming { … … 117 116 packet->fmt = IEC61883_FMT_AMDTP; 118 117 119 // signal that we are running (a transmit stream is always 'runnable') 120 m_running=true; 121 122 // we calculate the timestamp of the next sample in the buffer, which will 123 // allow us to check if we are to send this sample now, or later 124 125 // FIXME: maybe we should use the buffer head timestamp for this? 126 118 // recalculate the buffer head timestamp 127 119 float ticks_per_frame=m_SyncSource->getTicksPerFrame(); 128 120 129 121 // the base timestamp is the one of the last sample in the buffer 130 int64_t timestamp = m_buffer_tail_timestamp; 131 122 uint64_t ts_tail; 123 uint64_t fc; 124 125 getBufferTailTimestamp(&ts_tail, &fc); // thread safe 126 127 int64_t timestamp = ts_tail; 132 128 133 129 // meaning that the first sample in the buffer lies m_framecounter * rate 134 // earlier. This would givethe next equation:130 // earlier. This gives the next equation: 135 131 // timestamp = m_last_timestamp - m_framecounter * rate 136 // but to preserve causality, we have to make sure that this timestamp is 137 // always bigger than m_last_timestamp. this can be done by adding 138 // m_ringbuffersize_frames * rate. 139 timestamp += (int64_t)((((int64_t)m_ringbuffer_size_frames) 140 - ((int64_t)m_framecounter)) 141 * ticks_per_frame); 132 timestamp -= (int64_t)((float)fc * ticks_per_frame); 133 134 // FIXME: test 135 // substract the receive transfer delay 136 timestamp -= RECEIVE_PROCESSING_DELAY; 142 137 143 138 // this happens if m_buffer_tail_timestamp wraps around while there are … … 158 153 159 154 // determine if we want to send a packet or not 160 uint64_t cycle_timer=m_handler->getCycleTimerTicks(); 161 162 int64_t until_next=timestamp-cycle_timer; 155 // note that we can't use getCycleTimer directly here, 156 // because packets are queued in advance. This means that 157 // we the packet we are constructing will be sent out 158 // on 'cycle', not 'now'. 159 unsigned int ctr=m_handler->getCycleTimer(); 160 int now_cycles = (int)CYCLE_TIMER_GET_CYCLES(ctr); 161 162 // the difference between 'now' and the cycle this 163 // packet is intended for 164 int cycle_diff = cycle - now_cycles; 165 166 // detect wraparounds 167 if(cycle_diff < -(int)(CYCLES_PER_SECOND/2)) { 168 cycle_diff += CYCLES_PER_SECOND; 169 } else if(cycle_diff > (int)(CYCLES_PER_SECOND/2)) { 170 cycle_diff -= CYCLES_PER_SECOND; 171 } 172 173 // as long as the cycle parameter is not in sync with 174 // the current time, the stream is considered not 175 // to be 'running' 176 if(cycle_diff < 0 || cycle == -1) { 177 m_running=false; 178 } else { 179 m_running=true; 180 } 181 182 #ifdef DEBUG 183 if(cycle_diff < 0) { 184 debugWarning("Requesting packet for cycle %04d which is in the past (now=%04dcy)\n", 185 cycle, now_cycles); 186 } 187 #endif 188 // if cycle lies cycle_diff cycles in the future, we should 189 // queue this packet cycle_diff * TICKS_PER_CYCLE earlier than 190 // we would if it were to be sent immediately. 191 192 // determine the 'now' time in ticks 193 uint64_t cycle_timer=CYCLE_TIMER_TO_TICKS(ctr); 194 195 // time until the packet is to be sent (if > 0: send packet) 196 int64_t until_next=timestamp-(int64_t)cycle_timer; 197 198 int64_t utn2=until_next; // debug!! 163 199 164 200 // we send a packet some cycles in advance, to avoid the 165 201 // following situation: 166 202 // suppose we are only a few ticks away from 167 // the moment to send this packet. This means that in 168 // order to keep causality, we have to make sure that 169 // the TRANSFER_DELAY is bigger than one cycle, which 170 // might be a little much. 171 // this means that we need one cycle of extra buffering. 203 // the moment to send this packet. therefore we decide 204 // not to send the packet, but send it in the next cycle. 205 // This means that the next time point will be 3072 ticks 206 // later, making that the timestamp will be expired when the 207 // packet is sent, unless TRANSFER_DELAY > 3072. 208 // this means that we need at least one cycle of extra buffering. 172 209 until_next -= TICKS_PER_CYCLE * TRANSMIT_ADVANCE_CYCLES; 173 210 211 // we have to queue it cycle_diff * TICKS_PER_CYCLE earlier 212 until_next -= cycle_diff * TICKS_PER_CYCLE; 213 174 214 // the maximal difference we can allow (64secs) 175 215 const int64_t max=TICKS_PER_SECOND*64L; 176 216 217 #ifdef DEBUG 177 218 if(!m_disabled) { 178 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "=> TS=%11llu, CTR=%11llu, FC=%5d , TPS=%10.6f, UTN=%11lld\n",179 timestamp, cycle_timer, m_framecounter, ticks_per_frame, until_next219 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "=> TS=%11llu, CTR=%11llu, FC=%5d\n", 220 timestamp, cycle_timer, fc 180 221 ); 181 } 222 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " UTN=%11lld, UTN2=%11lld\n", 223 until_next, utn2 224 ); 225 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " CY_NOW=%04d, CY_TARGET=%04d, CY_DIFF=%04lld\n", 226 now_cycles, cycle, cycle_diff 227 ); 228 } 229 #endif 182 230 183 231 if(until_next > max) { … … 194 242 until_next += TICKS_PER_SECOND*128L; 195 243 } 196 244 245 #ifdef DEBUG 197 246 if(!m_disabled) { 198 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " TS=%11llu, CTR=%11llu, FC=%5d, TPS=%10.6f, UTN=%11lld\n",199 timestamp, cycle_timer, m_framecounter, ticks_per_frame, until_next247 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " > TS=%11llu, CTR=%11llu, FC=%5d\n", 248 timestamp, cycle_timer, fc 200 249 ); 201 } 202 203 // don't process the stream when it is not enabled, 250 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " UTN=%11lld, UTN2=%11lld\n", 251 until_next, utn2 252 ); 253 } 254 #endif 255 256 // don't process the stream when it is not enabled, not running 204 257 // or when the next sample is not due yet. 205 258 … … 207 260 // that means that we'll send NODATA packets. 208 261 // we don't add payload because DICE devices don't like that. 209 if((until_next>0) || m_disabled ) {262 if((until_next>0) || m_disabled || !m_running) { 210 263 // no-data packets have syt=0xFFFF 211 264 // and have the usual amount of events as dummy data (?) … … 224 277 *tag = IEC61883_TAG_WITH_CIP; 225 278 *sy = 0; 226 279 280 if(m_disabled) { 281 // indicate that we are now in a disabled state. 282 m_is_disabled=true; 283 } else { 284 // indicate that we are now in an enabled state. 285 m_is_disabled=false; 286 } 287 227 288 return RAW1394_ISO_DEFER; 228 289 } 229 290 291 // indicate that we are now in an enabled state. 292 m_is_disabled=false; 293 230 294 // construct the packet 231 295 nevents = m_syt_interval; … … 245 309 246 310 debugWarning("Transmit buffer underrun (cycle %d, FC=%d, PC=%d)\n", 247 cycle, m_framecounter, m_handler->getPacketCount()); 311 cycle, getFrameCounter(), m_handler->getPacketCount()); 312 313 nevents=0; 248 314 249 315 // TODO: we have to be a little smarter here … … 257 323 packet->fdf = IEC61883_FDF_NODATA; 258 324 packet->syt = 0xffff; 259 325 260 326 // this means no-data packets with payload (DICE doesn't like that) 261 327 *length = 2*sizeof(quadlet_t) + m_syt_interval * m_dimension * sizeof(quadlet_t); … … 277 343 278 344 // convert the timestamp to SYT format 279 unsigned int timestamp_SYT = TICKS_TO_SYT(timestamp); 345 uint64_t ts=timestamp + TRANSMIT_TRANSFER_DELAY; 346 347 // check if it wrapped 348 if (ts >= TICKS_PER_SECOND * 128L) { 349 ts -= TICKS_PER_SECOND * 128L; 350 } 351 352 unsigned int timestamp_SYT = TICKS_TO_SYT(ts); 280 353 packet->syt = ntohs(timestamp_SYT); 281 354 … … 284 357 285 358 // calculate the new buffer head timestamp. this is 286 // the timestamp of the current packet plus 287 // SYT_INTERVAL * rate 288 289 timestamp += (int64_t)((float)m_syt_interval * ticks_per_frame ); 359 // the previous buffer head timestamp plus 360 // the number of frames sent * ticks_per_frame 361 timestamp += (int64_t)((float)nevents * ticks_per_frame ); 290 362 291 363 // check if it wrapped … … 336 408 uint64_t ts; 337 409 uint64_t fc; 338 m_SyncSource->getBufferHeadTimestamp(&ts, &fc); 410 m_SyncSource->getBufferHeadTimestamp(&ts, &fc); // thread safe 339 411 340 412 // update the frame counter such that it reflects the buffer content, … … 440 512 441 513 // add the receive processing delay 442 m_ringbuffer_size_frames+=(uint)(RECEIVE_PROCESSING_DELAY/m_ticks_per_frame);514 // m_ringbuffer_size_frames+=(uint)(RECEIVE_PROCESSING_DELAY/m_ticks_per_frame); 443 515 444 516 if( !(m_event_buffer=freebob_ringbuffer_create( … … 583 655 uint64_t fc; 584 656 585 m_SyncSource->getBufferHeadTimestamp(&ts, &fc); 586 587 setBufferTailTimestamp(ts); 588 657 debugOutput(DEBUG_LEVEL_VERBOSE,"Preparing to enable...\n"); 658 659 m_SyncSource->getBufferHeadTimestamp(&ts, &fc); // thread safe 660 661 // recalculate the buffer head timestamp 662 float ticks_per_frame=m_SyncSource->getTicksPerFrame(); 663 664 // set buffer head timestamp 665 // this makes that the next sample to be sent out 666 // has the same timestamp as the last one received 667 // plus one frame 668 ts += (uint64_t)ticks_per_frame; 669 setBufferHeadTimestamp(ts); 670 int64_t timestamp = ts; 671 672 // since we have a full buffer, we know that the buffer tail lies 673 // m_ringbuffer_size_frames * rate earlier 674 timestamp += (int64_t)((float)m_ringbuffer_size_frames * ticks_per_frame); 675 676 // this happens when the last timestamp is near wrapping, and 677 // m_framecounter is low. 678 // this means: m_last_timestamp is near wrapping and have just had 679 // a getPackets() from the client side. the projected next_period 680 // boundary lies beyond the wrap value. 681 // the action is to wrap the value. 682 if (timestamp >= TICKS_PER_SECOND * 128L) { 683 timestamp -= TICKS_PER_SECOND * 128L; 684 } 685 686 StreamProcessor::setBufferTailTimestamp(timestamp); 687 688 debugOutput(DEBUG_LEVEL_VERBOSE,"TS=%10lld, TSTMP=%10llu, %f\n", 689 ts, timestamp, ticks_per_frame); 690 691 if (!StreamProcessor::prepareForEnable()) { 692 debugError("StreamProcessor::prepareForEnable failed\n"); 693 return false; 694 } 695 589 696 return true; 590 697 } … … 617 724 int xrun; 618 725 unsigned int offset=0; 726 727 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "AmdtpTransmitStreamProcessor::putFrames(%d, %llu)\n",nbframes, ts); 619 728 620 729 freebob_ringbuffer_data_t vec[2]; … … 700 809 701 810 } 811 812 // recalculate the buffer tail timestamp 813 float ticks_per_frame=m_SyncSource->getTicksPerFrame(); 814 815 // this makes that the last sample to be sent out on ISO 816 // has the same timestamp as the last one transfered 817 // to the client 818 // plus one frame 819 ts += (uint64_t)ticks_per_frame; 820 int64_t timestamp = ts; 821 822 // however we have to preserve causality, meaning that we have to make 823 // sure that the worst-case buffer head timestamp still lies in the future. 824 // this worst case timestamp occurs when the xmit buffer is completely full. 825 // therefore we add m_ringbuffer_size_frames * ticks_per_frame to the timestamp. 826 // this will make sure that the buffer head timestamp lies in the future. 827 // the netto effect of this is that the system works as if the buffer processing 828 // by the client doesn't take time. 829 830 timestamp += (int64_t)((float)m_ringbuffer_size_frames * ticks_per_frame); 831 832 // wrap the timestamp if nescessary 833 if (timestamp >= TICKS_PER_SECOND * 128L) { 834 timestamp -= TICKS_PER_SECOND * 128L; 835 } 836 837 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "StreamProcessor::putFrames(%d, %llu)\n",nbframes, timestamp); 702 838 703 839 // update the frame counter such that it reflects the new value, 704 840 // and also update the buffer tail timestamp 705 841 // done in the SP base class 706 debugOutput(DEBUG_LEVEL_VERBOSE, "StreamProcessor::putFrames(%d, %llu)\n",nbframes, ts); 707 708 if (!StreamProcessor::putFrames(nbframes, ts)) { 709 debugError("Could not do StreamProcessor::putFrames(%d, %llu)\n",nbframes, ts); 842 if (!StreamProcessor::putFrames(nbframes, timestamp)) { 843 debugError("Could not do StreamProcessor::putFrames(%d, %llu)\n",nbframes, timestamp); 710 844 return false; 711 845 } … … 1029 1163 m_last_timestamp += CYCLE_TIMER_GET_OFFSET(syt_timestamp); 1030 1164 m_last_timestamp += cc_seconds * TICKS_PER_SECOND; 1165 1166 // the receive processing delay indicates how much 1167 // extra time we need as slack 1168 m_last_timestamp += RECEIVE_PROCESSING_DELAY; 1031 1169 1032 1170 //=> now estimate the device frame rate … … 1083 1221 //=> don't process the stream samples when it is not enabled. 1084 1222 if(m_disabled) { 1223 1085 1224 // we keep track of the timestamp here 1086 1225 // this makes sure that we will have a somewhat accurate … … 1091 1230 // SYT_INTERVAL * rate later 1092 1231 uint64_t ts=m_last_timestamp+(uint64_t)((float)m_syt_interval * m_ticks_per_frame); 1232 1233 // wrap if nescessary 1234 if (ts >= TICKS_PER_SECOND * 128L) { 1235 ts -= TICKS_PER_SECOND * 128L; 1236 } 1237 // set the timestamps 1093 1238 StreamProcessor::setBufferTimestamps(ts,ts); 1239 1240 // indicate that we are now in a disabled state. 1241 m_is_disabled=true; 1094 1242 1095 1243 return RAW1394_ISO_DEFER; 1096 1244 } 1245 1246 // indicate that we are now in an enabled state. 1247 m_is_disabled=false; 1097 1248 1098 1249 //=> process the packet … … 1103 1254 { 1104 1255 debugWarning("Receive buffer overrun (cycle %d, FC=%d, PC=%d)\n", 1105 cycle, m_framecounter, m_handler->getPacketCount());1256 cycle, getFrameCounter(), m_handler->getPacketCount()); 1106 1257 1107 1258 m_xruns++; … … 1224 1375 // currently this is in ticks 1225 1376 1377 int64_t fc=getFrameCounter(); 1378 1226 1379 int64_t next_period_boundary = m_last_timestamp; 1227 next_period_boundary += (int64_t)(((int64_t)m_period-(int64_t)m_framecounter) * m_ticks_per_frame); 1228 next_period_boundary += RECEIVE_PROCESSING_DELAY; 1380 next_period_boundary += (int64_t)(((int64_t)m_period 1381 - fc) * m_ticks_per_frame); 1382 // next_period_boundary += RECEIVE_PROCESSING_DELAY; 1229 1383 1230 1384 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "=> NPD=%11lld, LTS=%11llu, FC=%5d, TPF=%f\n", 1231 next_period_boundary, m_last_timestamp, m_framecounter, m_ticks_per_frame1385 next_period_boundary, m_last_timestamp, fc, m_ticks_per_frame 1232 1386 ); 1233 1387 … … 1249 1403 1250 1404 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " NPD=%11lld, LTS=%11llu, FC=%5d, TPF=%f\n", 1251 next_period_boundary, m_last_timestamp, m_framecounter, m_ticks_per_frame1405 next_period_boundary, m_last_timestamp, fc, m_ticks_per_frame 1252 1406 ); 1253 1407 … … 1283 1437 m_WakeupStat.reset(); 1284 1438 1285 m_ticks_per_frame = (TICKS_PER_SECOND*1.0) / ((float)m_framerate);1439 // m_ticks_per_frame = (TICKS_PER_SECOND*1.0) / ((float)m_framerate); 1286 1440 1287 1441 // reset all non-device specific stuff … … 1554 1708 1555 1709 if (!StreamProcessor::getFrames(nbframes, ts)) { 1556 debugError("Could not do StreamProcessor::getFrames(%d, %llu)\n", nbframes, ts);1710 debugError("Could not do StreamProcessor::getFrames(%d, %llu)\n", nbframes, ts); 1557 1711 return false; 1558 1712 } branches/streaming-rework/src/libstreaming/cycletimer.h
r384 r385 38 38 #define TICKS_PER_CYCLE 3072U 39 39 #define TICKS_PER_SECOND 24576000UL 40 #define TICKS_PER_USEC ( TICKS_PER_SECOND/1000000.0)40 #define TICKS_PER_USEC (24.576000) 41 41 42 42 #define USECS_PER_TICK (1.0/TICKS_PER_USEC) 43 #define USECS_PER_CYCLE (125U) 43 44 44 45 #define CYCLE_TIMER_GET_SECS(x) ((((x) & 0xFE000000U) >> 25)) branches/streaming-rework/src/libstreaming/freebob_streaming.cpp
r384 r385 119 119 // discover the devices on the bus 120 120 if(!dev->m_deviceManager->discover(DEBUG_LEVEL_NORMAL)) { 121 debug Output(DEBUG_LEVEL_VERBOSE,"Could not discover devices\n");121 debugFatal("Could not discover devices\n"); 122 122 delete dev->processorManager; 123 123 delete dev->m_deviceManager; … … 132 132 assert(device); 133 133 134 debugOutput(DEBUG_LEVEL_VERBOSE, "Setting samplerate to %d for (%p)\n", 135 dev->options.sample_rate, device); 134 136 // Set the device's sampling rate to that requested 135 137 // FIXME: does this really belong here? If so we need to handle errors. 136 138 if (!device->setSamplingFrequency(parseSampleRate(dev->options.sample_rate))) { 139 debugOutput(DEBUG_LEVEL_VERBOSE, " => Retry setting samplerate to %d for (%p)\n", 140 dev->options.sample_rate, device); 141 137 142 // try again: 138 143 if (!device->setSamplingFrequency(parseSampleRate(dev->options.sample_rate))) { … … 252 257 periods++; 253 258 if(periods>periods_print) { 254 debugOutput (DEBUG_LEVEL_VERBOSE, "\n");255 debugOutput (DEBUG_LEVEL_VERBOSE, "============================================\n");256 debugOutput (DEBUG_LEVEL_VERBOSE, "Xruns: %d\n",xruns);257 debugOutput (DEBUG_LEVEL_VERBOSE, "============================================\n");259 debugOutputShort(DEBUG_LEVEL_VERBOSE, "\nfreebob_streaming_wait\n"); 260 debugOutputShort(DEBUG_LEVEL_VERBOSE, "============================================\n"); 261 debugOutputShort(DEBUG_LEVEL_VERBOSE, "Xruns: %d\n",xruns); 262 debugOutputShort(DEBUG_LEVEL_VERBOSE, "============================================\n"); 258 263 dev->processorManager->dumpInfo(); 259 debugOutput (DEBUG_LEVEL_VERBOSE, "\n");264 debugOutputShort(DEBUG_LEVEL_VERBOSE, "\n"); 260 265 periods_print+=100; 261 266 } branches/streaming-rework/src/libstreaming/IsoHandler.cpp
r384 r385 877 877 debugOutput( DEBUG_LEVEL_VERBOSE, " Irq interval : %d \n",m_irq_interval); 878 878 879 if(raw1394_iso_recv_init(m_handle, 880 iso_receive_handler, 881 m_buf_packets, 882 m_max_packet_size, 883 m_Client->getChannel(), 884 RAW1394_DMA_BUFFERFILL, 885 m_irq_interval)) { 886 debugFatal("Could not do receive initialisation!\n" ); 887 debugFatal(" %s\n",strerror(errno)); 888 889 return false; 879 if(m_irq_interval > 1) { 880 if(raw1394_iso_recv_init(m_handle, 881 iso_receive_handler, 882 m_buf_packets, 883 m_max_packet_size, 884 m_Client->getChannel(), 885 RAW1394_DMA_BUFFERFILL, 886 m_irq_interval)) { 887 debugFatal("Could not do receive initialisation!\n" ); 888 debugFatal(" %s\n",strerror(errno)); 889 890 return false; 891 } 892 } else { 893 if(raw1394_iso_recv_init(m_handle, 894 iso_receive_handler, 895 m_buf_packets, 896 m_max_packet_size, 897 m_Client->getChannel(), 898 RAW1394_DMA_PACKET_PER_BUFFER, 899 m_irq_interval)) { 900 debugFatal("Could not do receive initialisation!\n" ); 901 debugFatal(" %s\n",strerror(errno)); 902 903 return false; 904 } 890 905 } 891 906 return true; branches/streaming-rework/src/libstreaming/IsoHandlerManager.cpp
r384 r385 31 31 #include "IsoStream.h" 32 32 #include <assert.h> 33 34 #define MINIMUM_INTERRUPTS_PER_PERIOD 4U 35 #define PACKETS_PER_INTERRUPT 4U 33 36 34 37 namespace FreebobStreaming … … 285 288 unsigned int packets_per_period=stream->getPacketsPerPeriod(); 286 289 290 #if 0 287 291 // hardware interrupts occur when one DMA block is full, and the size of one DMA 288 292 // block = PAGE_SIZE. Setting the max_packet_size makes sure that the HW irq is 289 293 // occurs at a period boundary (optimal CPU use) 290 294 291 // NOTE: try and use 4 hardware interrupts per period for better latency. 292 unsigned int max_packet_size=4 * getpagesize() / packets_per_period; 295 // NOTE: try and use MINIMUM_INTERRUPTS_PER_PERIOD hardware interrupts 296 // per period for better latency. 297 unsigned int max_packet_size=MINIMUM_INTERRUPTS_PER_PERIOD * getpagesize() / packets_per_period; 293 298 if (max_packet_size < stream->getMaxPacketSize()) { 294 299 max_packet_size=stream->getMaxPacketSize(); … … 300 305 max_packet_size = getpagesize(); 301 306 302 int irq_interval=packets_per_period / 4; 303 if(irq_interval <= 0) irq_interval=1; 304 305 /* the receive buffer size doesn't matter for the latency, 306 but it has a minimal value in order for libraw to operate correctly (300) */ 307 int buffers=400; 308 309 // create the actual handler 310 IsoRecvHandler *h = new IsoRecvHandler(stream->getPort(), buffers, 311 max_packet_size, irq_interval); 312 313 debugOutput( DEBUG_LEVEL_VERBOSE, " registering IsoRecvHandler\n"); 314 315 if(!h) { 316 debugFatal("Could not create IsoRecvHandler\n"); 317 return false; 318 } 319 320 h->setVerboseLevel(getDebugLevel()); 321 322 // init the handler 323 if(!h->init()) { 324 debugFatal("Could not initialize receive handler\n"); 325 return false; 326 } 327 328 // register the stream with the handler 329 if(!h->registerStream(stream)) { 330 debugFatal("Could not register receive stream with handler\n"); 331 return false; 332 } 333 334 // register the handler with the manager 335 if(!registerHandler(h)) { 336 debugFatal("Could not register receive handler with manager\n"); 337 return false; 338 } 339 debugOutput( DEBUG_LEVEL_VERBOSE, " registered stream (%p) with handler (%p)\n",stream,h); 340 } 341 342 if (stream->getType()==IsoStream::EST_Transmit) { 343 344 // setup the optimal parameters for the raw1394 ISO buffering 345 unsigned int packets_per_period=stream->getPacketsPerPeriod(); 307 unsigned int irq_interval=packets_per_period / MINIMUM_INTERRUPTS_PER_PERIOD; 308 if(irq_interval <= 0) irq_interval=1; 309 #else 346 310 // hardware interrupts occur when one DMA block is full, and the size of one DMA 347 // block = PAGE_SIZE. Setting the max_packet_size makes sure that the HW irq 348 // occurs at a period boundary (optimal CPU use) 349 // NOTE: try and use 4 interrupts per period for better latency. 350 unsigned int max_packet_size=4 * getpagesize() / packets_per_period; 311 // block = PAGE_SIZE. Setting the max_packet_size enables control over the IRQ 312 // frequency, as the controller uses max_packet_size, and not the effective size 313 // when writing to the DMA buffer. 314 315 // configure it such that we have an irq for every PACKETS_PER_INTERRUPT packets 316 unsigned int irq_interval=PACKETS_PER_INTERRUPT; 317 318 // unless the period size doesn't allow this 319 if ((packets_per_period/MINIMUM_INTERRUPTS_PER_PERIOD) < irq_interval) { 320 irq_interval=1; 321 } 322 323 // FIXME: test 324 irq_interval=1; 325 326 unsigned int max_packet_size=getpagesize() / irq_interval; 327 351 328 if (max_packet_size < stream->getMaxPacketSize()) { 352 329 max_packet_size=stream->getMaxPacketSize(); … … 358 335 max_packet_size = getpagesize(); 359 336 360 int irq_interval=packets_per_period / 4; 337 #endif 338 /* the receive buffer size doesn't matter for the latency, 339 but it has a minimal value in order for libraw to operate correctly (300) */ 340 int buffers=400; 341 342 // create the actual handler 343 IsoRecvHandler *h = new IsoRecvHandler(stream->getPort(), buffers, 344 max_packet_size, irq_interval); 345 346 debugOutput( DEBUG_LEVEL_VERBOSE, " registering IsoRecvHandler\n"); 347 348 if(!h) { 349 debugFatal("Could not create IsoRecvHandler\n"); 350 return false; 351 } 352 353 h->setVerboseLevel(getDebugLevel()); 354 355 // init the handler 356 if(!h->init()) { 357 debugFatal("Could not initialize receive handler\n"); 358 return false; 359 } 360 361 // register the stream with the handler 362 if(!h->registerStream(stream)) { 363 debugFatal("Could not register receive stream with handler\n"); 364 return false; 365 } 366 367 // register the handler with the manager 368 if(!registerHandler(h)) { 369 debugFatal("Could not register receive handler with manager\n"); 370 return false; 371 } 372 debugOutput( DEBUG_LEVEL_VERBOSE, " registered stream (%p) with handler (%p)\n",stream,h); 373 } 374 375 if (stream->getType()==IsoStream::EST_Transmit) { 376 // setup the optimal parameters for the raw1394 ISO buffering 377 unsigned int packets_per_period=stream->getPacketsPerPeriod(); 378 379 #if 0 380 // hardware interrupts occur when one DMA block is full, and the size of one DMA 381 // block = PAGE_SIZE. Setting the max_packet_size makes sure that the HW irq 382 // occurs at a period boundary (optimal CPU use) 383 // NOTE: try and use MINIMUM_INTERRUPTS_PER_PERIOD interrupts per period 384 // for better latency. 385 unsigned int max_packet_size=MINIMUM_INTERRUPTS_PER_PERIOD * getpagesize() / packets_per_period; 386 if (max_packet_size < stream->getMaxPacketSize()) { 387 max_packet_size=stream->getMaxPacketSize(); 388 } 389 390 // Ensure we don't request a packet size bigger than the 391 // kernel-enforced maximum which is currently 1 page. 392 if (max_packet_size > (unsigned int)getpagesize()) 393 max_packet_size = getpagesize(); 394 395 unsigned int irq_interval=packets_per_period / MINIMUM_INTERRUPTS_PER_PERIOD; 361 396 if(irq_interval <= 0) irq_interval=1; 362 397 #else 398 // hardware interrupts occur when one DMA block is full, and the size of one DMA 399 // block = PAGE_SIZE. Setting the max_packet_size enables control over the IRQ 400 // frequency, as the controller uses max_packet_size, and not the effective size 401 // when writing to the DMA buffer. 402 403 // configure it such that we have an irq for every PACKETS_PER_INTERRUPT packets 404 unsigned int irq_interval=PACKETS_PER_INTERRUPT; 405 406 // unless the period size doesn't allow this 407 if ((packets_per_period/MINIMUM_INTERRUPTS_PER_PERIOD) < irq_interval) { 408 irq_interval=1; 409 } 410 411 // FIXME: test 412 irq_interval=1; 413 414 unsigned int max_packet_size=getpagesize() / irq_interval; 415 416 if (max_packet_size < stream->getMaxPacketSize()) { 417 max_packet_size=stream->getMaxPacketSize(); 418 } 419 420 // Ensure we don't request a packet size bigger than the 421 // kernel-enforced maximum which is currently 1 page. 422 if (max_packet_size > (unsigned int)getpagesize()) 423 max_packet_size = getpagesize(); 424 #endif 363 425 // the transmit buffer size should be as low as possible for latency. 364 426 // note however that the raw1394 subsystem tries to keep this buffer 365 427 // full, so we have to make sure that we have enough events in our 366 428 // event buffers 367 int buffers=packets_per_period; 429 430 // every irq_interval packets an interrupt will occur. that is when 431 // buffers get transfered, meaning that we should have at least some 432 // margin here 433 // int buffers=irq_interval * 2; 434 435 // half a period. the xmit handler will take care of this 436 int buffers=packets_per_period/2; 368 437 369 438 // NOTE: this is dangerous: what if there is not enough prefill? branches/streaming-rework/src/libstreaming/StreamProcessor.cpp
r384 r385 35 35 namespace FreebobStreaming { 36 36 37 IMPL_DEBUG_MODULE( StreamProcessor, StreamProcessor, DEBUG_LEVEL_ NORMAL);38 IMPL_DEBUG_MODULE( ReceiveStreamProcessor, ReceiveStreamProcessor, DEBUG_LEVEL_ NORMAL);39 IMPL_DEBUG_MODULE( TransmitStreamProcessor, TransmitStreamProcessor, DEBUG_LEVEL_ NORMAL);37 IMPL_DEBUG_MODULE( StreamProcessor, StreamProcessor, DEBUG_LEVEL_VERBOSE ); 38 IMPL_DEBUG_MODULE( ReceiveStreamProcessor, ReceiveStreamProcessor, DEBUG_LEVEL_VERBOSE ); 39 IMPL_DEBUG_MODULE( TransmitStreamProcessor, TransmitStreamProcessor, DEBUG_LEVEL_VERBOSE ); 40 40 41 41 StreamProcessor::StreamProcessor(enum IsoStream::EStreamType type, int port, int framerate) … … 51 51 , m_running(false) 52 52 , m_disabled(true) 53 , m_is_disabled(true) 53 54 { 54 55 … … 61 62 void StreamProcessor::dumpInfo() 62 63 { 64 int64_t diff=(int64_t)m_buffer_head_timestamp - (int64_t)m_buffer_tail_timestamp; 63 65 64 66 debugOutputShort( DEBUG_LEVEL_NORMAL, " StreamProcessor information\n"); … … 66 68 67 69 IsoStream::dumpInfo(); 68 debugOutputShort( DEBUG_LEVEL_NORMAL, " Frame counter : %d\n", m_framecounter); 69 debugOutputShort( DEBUG_LEVEL_NORMAL, " Xruns : %d\n", m_xruns); 70 debugOutputShort( DEBUG_LEVEL_NORMAL, " Running : %d\n", m_running); 71 debugOutputShort( DEBUG_LEVEL_NORMAL, " Enabled : %d\n", !m_disabled); 70 debugOutputShort( DEBUG_LEVEL_NORMAL, " StreamProcessor info:\n"); 71 debugOutputShort( DEBUG_LEVEL_NORMAL, " Frame counter : %d\n", m_framecounter); 72 debugOutputShort( DEBUG_LEVEL_NORMAL, " Buffer head timestamp : %011llu\n",m_buffer_head_timestamp); 73 debugOutputShort( DEBUG_LEVEL_NORMAL, " Buffer tail timestamp : %011llu\n",m_buffer_tail_timestamp); 74 debugOutputShort( DEBUG_LEVEL_NORMAL, " Head - Tail : %011lld\n",diff); 75 debugOutputShort( DEBUG_LEVEL_NORMAL, " Now : %011u\n",m_handler->getCycleTimerTicks()); 76 debugOutputShort( DEBUG_LEVEL_NORMAL, " Xruns : %d\n", m_xruns); 77 debugOutputShort( DEBUG_LEVEL_NORMAL, " Running : %d\n", m_running); 78 debugOutputShort( DEBUG_LEVEL_NORMAL, " Enabled : %s\n", m_disabled ? "No" : "Yes"); 79 debugOutputShort( DEBUG_LEVEL_NORMAL, " enable status : %s\n", m_is_disabled ? "No" : "Yes"); 72 80 73 81 // m_PeriodStat.dumpInfo(); … … 111 119 return true; 112 120 121 } 122 123 bool StreamProcessor::prepareForEnable() { 124 int64_t diff=(int64_t)m_buffer_head_timestamp - (int64_t)m_buffer_tail_timestamp; 125 126 debugOutput(DEBUG_LEVEL_VERBOSE," StreamProcessor::prepareForEnable for (%p)\n",this); 127 debugOutput(DEBUG_LEVEL_VERBOSE," Frame Counter : %05d\n",m_framecounter); 128 debugOutput(DEBUG_LEVEL_VERBOSE," Buffer head timestamp : %011llu\n",m_buffer_head_timestamp); 129 debugOutput(DEBUG_LEVEL_VERBOSE," Buffer tail timestamp : %011llu\n",m_buffer_tail_timestamp); 130 debugOutput(DEBUG_LEVEL_VERBOSE," Head - Tail : %011lld\n",diff); 131 debugOutput(DEBUG_LEVEL_VERBOSE," Now : %011u\n",m_handler->getCycleTimerTicks()); 132 return true; 133 } 134 135 bool StreamProcessor::prepareForDisable() { 136 int64_t diff=(int64_t)m_buffer_head_timestamp - (int64_t)m_buffer_tail_timestamp; 137 138 debugOutput(DEBUG_LEVEL_VERBOSE," StreamProcessor::prepareForDisable for (%p)\n",this); 139 debugOutput(DEBUG_LEVEL_VERBOSE," Frame Counter : %05d\n",m_framecounter); 140 debugOutput(DEBUG_LEVEL_VERBOSE," Buffer head timestamp : %011llu\n",m_buffer_head_timestamp); 141 debugOutput(DEBUG_LEVEL_VERBOSE," Buffer tail timestamp : %011llu\n",m_buffer_tail_timestamp); 142 debugOutput(DEBUG_LEVEL_VERBOSE," Head - Tail : %011lld\n",diff); 143 debugOutput(DEBUG_LEVEL_VERBOSE," Now : %011u\n",m_handler->getCycleTimerTicks()); 144 return true; 145 113 146 } 114 147 … … 172 205 bool StreamProcessor::getFrames(unsigned int nbframes, int64_t ts) { 173 206 174 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Getting %d frames from frame buffer ...\n", nbframes);207 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Getting %d frames from frame buffer at (%011lld)...\n", nbframes, ts); 175 208 decrementFrameCounter(nbframes, ts); 176 209 return true; … … 181 214 } 182 215 183 void StreamProcessor::enable() { 184 if(!m_running) { 185 debugWarning("The StreamProcessor is not running yet, enable() might not be a good idea.\n"); 186 } 187 m_disabled=false; 216 bool StreamProcessor::enable() { 217 int cnt=0; 218 219 if(!m_running) { 220 debugWarning("The StreamProcessor is not running yet, enable() might not be a good idea.\n"); 221 } 222 223 m_disabled=false; 224 225 // now wait until it is effectively enabled 226 // time-out at 100ms 227 while(m_is_disabled && cnt++ < 1000) { 228 usleep(100); 229 } 230 231 // check if the operation timed out 232 if(cnt==1000) { 233 debugWarning("Timeout when enabling StreamProcessor (%p)\n",this); 234 return false; 235 } 236 237 return true; 238 } 239 240 bool StreamProcessor::disable() { 241 int cnt=0; 242 243 m_disabled=true; 244 245 // now wait until it is effectively disabled 246 // time-out at 247 while(!m_is_disabled && cnt++ < 1000) { 248 usleep(100); 249 } 250 251 // check if the operation timed out (100ms) 252 if(cnt==1000) { 253 debugWarning("Timeout when disabling StreamProcessor (%p)\n",this); 254 return false; 255 } 256 257 return true; 258 188 259 } 189 260 … … 195 266 /** 196 267 * Decrements the frame counter, in a atomic way. This 197 * also sets the buffer tailtimestamp268 * also sets the buffer head timestamp 198 269 * is thread safe. 199 270 */ 200 271 void StreamProcessor::decrementFrameCounter(int nbframes, uint64_t new_timestamp) { 272 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Setting buffer head timestamp for (%p) to %11llu\n", 273 this, new_timestamp); 274 201 275 pthread_mutex_lock(&m_framecounter_lock); 202 276 m_framecounter -= nbframes; … … 207 281 /** 208 282 * Increments the frame counter, in a atomic way. 209 * also sets the buffer headtimestamp283 * also sets the buffer tail timestamp 210 284 * This is thread safe. 211 285 */ 212 286 void StreamProcessor::incrementFrameCounter(int nbframes, uint64_t new_timestamp) { 287 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Setting buffer tail timestamp for (%p) to %11llu\n", 288 this, new_timestamp); 289 213 290 pthread_mutex_lock(&m_framecounter_lock); 214 291 m_framecounter += nbframes; … … 219 296 220 297 /** 221 * Sets the frame counter, in a atomic way.222 * also sets the buffer head timestamp223 * This is thread safe.224 */225 void StreamProcessor::setFrameCounter(int new_framecounter, uint64_t new_timestamp) {226 pthread_mutex_lock(&m_framecounter_lock);227 m_framecounter = new_framecounter;228 m_buffer_tail_timestamp = new_timestamp;229 pthread_mutex_unlock(&m_framecounter_lock);230 }231 232 /**233 298 * Sets the buffer tail timestamp (in usecs) 234 299 * This is thread safe. 235 300 */ 236 301 void StreamProcessor::setBufferTailTimestamp(uint64_t new_timestamp) { 302 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Setting buffer tail timestamp for (%p) to %11llu\n", 303 this, new_timestamp); 304 237 305 pthread_mutex_lock(&m_framecounter_lock); 238 306 m_buffer_tail_timestamp = new_timestamp; … … 245 313 */ 246 314 void StreamProcessor::setBufferHeadTimestamp(uint64_t new_timestamp) { 315 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Setting buffer head timestamp for (%p) to %11llu\n", 316 this, new_timestamp); 317 247 318 pthread_mutex_lock(&m_framecounter_lock); 248 319 m_buffer_head_timestamp = new_timestamp; … … 256 327 */ 257 328 void StreamProcessor::setBufferTimestamps(uint64_t new_head, uint64_t new_tail) { 329 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Setting buffer head timestamp for (%p) to %11llu\n", 330 this, new_head); 331 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, " and buffer tail timestamp for (%p) to %11llu\n", 332 this, new_tail); 333 258 334 pthread_mutex_lock(&m_framecounter_lock); 259 335 m_buffer_head_timestamp = new_head; branches/streaming-rework/src/libstreaming/StreamProcessor.h
r384 r385 80 80 81 81 bool isRunning(); ///< returns true if there is some stream data processed 82 voidenable(); ///< enable the stream processing83 void disable() {m_disabled=true;}; ///< disable the stream processing84 bool isEnabled() {return !m_ disabled;};82 bool enable(); ///< enable the stream processing 83 bool disable(); ///< disable the stream processing 84 bool isEnabled() {return !m_is_disabled;}; 85 85 86 86 virtual bool putFrames(unsigned int nbframes, int64_t ts); ///< transfer the buffer contents from client … … 100 100 virtual bool prepareForStart() {return true;}; 101 101 102 virtual bool prepareForEnable() {return true;};103 virtual bool prepareForDisable() {return true;};102 virtual bool prepareForEnable(); 103 virtual bool prepareForDisable(); 104 104 105 105 protected: … … 120 120 bool m_running; 121 121 bool m_disabled; 122 122 bool m_is_disabled; 123 123 124 StreamStatistics m_PacketStat; 124 125 StreamStatistics m_PeriodStat; … … 147 148 void decrementFrameCounter(int nbframes, uint64_t new_timestamp); 148 149 void incrementFrameCounter(int nbframes, uint64_t new_timestamp); 149 void setFrameCounter(int new_framecounter, uint64_t new_timestamp);150 150 void resetFrameCounter(); 151 151 … … 193 193 float getTicksPerFrame() {return m_ticks_per_frame;}; 194 194 195 pr otected:195 private: 196 196 // the framecounter gives the number of frames in the buffer 197 197 signed int m_framecounter; … … 205 205 uint64_t m_buffer_head_timestamp; 206 206 207 207 protected: 208 208 StreamProcessor *m_SyncSource; 209 209 branches/streaming-rework/src/libstreaming/StreamProcessorManager.cpp
r384 r385 33 33 #include <assert.h> 34 34 35 #include "libstreaming/cycletimer.h" 36 37 #define CYCLES_TO_SLEEP_AFTER_RUN_SIGNAL 50 35 38 36 39 namespace FreebobStreaming { … … 403 406 } 404 407 408 // we want to make sure that everything is running well, 409 // so wait for a while 410 usleep(USECS_PER_CYCLE * CYCLES_TO_SLEEP_AFTER_RUN_SIGNAL); 411 405 412 debugOutput( DEBUG_LEVEL_VERBOSE, "StreamProcessors running...\n"); 406 debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting framecounters...\n");413 debugOutput( DEBUG_LEVEL_VERBOSE, "Resetting counters...\n"); 407 414 408 415 // now we reset the frame counters … … 411 418 ++it ) { 412 419 420 debugOutput( DEBUG_LEVEL_VERBOSE, "Before:\n"); 421 413 422 if(getDebugLevel()>=DEBUG_LEVEL_VERBOSE) { 414 423 (*it)->dumpInfo(); 415 424 } 416 425 417 (*it)->reset(); 426 (*it)->reset(); 427 428 debugOutput( DEBUG_LEVEL_VERBOSE, "After:\n"); 418 429 419 430 if(getDebugLevel()>=DEBUG_LEVEL_VERBOSE) { … … 427 438 ++it ) { 428 439 440 debugOutput( DEBUG_LEVEL_VERBOSE, "Before:\n"); 441 429 442 if(getDebugLevel()>=DEBUG_LEVEL_VERBOSE) { 430 443 (*it)->dumpInfo(); … … 432 445 433 446 (*it)->reset(); 447 448 debugOutput( DEBUG_LEVEL_VERBOSE, "After:\n"); 434 449 435 450 if(getDebugLevel()>=DEBUG_LEVEL_VERBOSE) { … … 666 681 bool StreamProcessorManager::waitForPeriod() { 667 682 int time_till_next_period; 668 683 bool xrun_occurred=false; 684 669 685 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "enter...\n"); 670 686 … … 679 695 usleep(time_till_next_period); 680 696 681 // check if it is still true 697 // check for underruns on the ISO side, 698 // those should make us bail out of the wait loop 699 for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 700 it != m_ReceiveProcessors.end(); 701 ++it ) { 702 // a xrun has occurred on the Iso side 703 xrun_occurred |= (*it)->xrunOccurred(); 704 } 705 for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 706 it != m_TransmitProcessors.end(); 707 ++it ) { 708 // a xrun has occurred on the Iso side 709 xrun_occurred |= (*it)->xrunOccurred(); 710 } 711 712 // check if we were waked up too soon 682 713 time_till_next_period=m_SyncSource->getTimeUntilNextPeriodUsecs(); 683 714 } 684 715 685 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "delayed for %d usecs...\n", time_till_next_period);716 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "delayed for %d usecs...\n", -time_till_next_period); 686 717 687 718 // this is to notify the client of the delay … … 696 727 // and the receive processors should have done their transfer. 697 728 m_time_of_transfer=m_SyncSource->getTimeAtPeriod(); 698 debugOutput( DEBUG_LEVEL_VER BOSE, "transfer at %llu ticks...\n",729 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "transfer at %llu ticks...\n", 699 730 m_time_of_transfer); 731 732 xrun_occurred=false; 700 733 701 734 // check if xruns occurred on the Iso side. 702 735 // also check if xruns will occur should we transfer() now 703 bool xrun_occurred=false;704 736 705 737 for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); … … 741 773 } 742 774 775 m_nbperiods++; 776 743 777 // now we can signal the client that we are (should be) ready 744 778 return !xrun_occurred; … … 772 806 773 807 bool StreamProcessorManager::transfer(enum StreamProcessor::EProcessorType t) { 774 int64_t time_of_transfer;775 808 debugOutput( DEBUG_LEVEL_VERY_VERBOSE, "Transferring period...\n"); 776 777 // first we should find out on what time this transfer is778 // supposed to be happening. this time will become the time779 // stamp for the transmitted buffer.780 // NOTE: maybe we should include the transfer delay here, that781 // would make it equal for all types of SP's782 time_of_transfer=m_time_of_transfer;783 809 784 810 // a static cast could make sure that there is no performance … … 788 814 it != m_ReceiveProcessors.end(); 789 815 ++it ) { 790 uint64_t buffer_tail_ts;791 uint64_t fc;792 int64_t ts;793 794 (*it)->getBufferTailTimestamp(&buffer_tail_ts,&fc);795 ts = buffer_tail_ts;796 ts += (int64_t)((-(int64_t)fc) * m_SyncSource->getTicksPerFrame());797 // NOTE: ts can be negative due to wraparound, it is the responsability of the798 // SP to deal with that.799 816 800 float tmp=m_SyncSource->getTicksPerFrame(); 801 802 debugOutput(DEBUG_LEVEL_VERBOSE, "=> TS=%11lld, BLT=%11llu, FC=%5d, TPF=%f\n", 803 ts, buffer_tail_ts, fc, tmp 804 ); 805 debugOutput(DEBUG_LEVEL_VERBOSE, " TPF=%f\n", tmp); 806 807 #ifdef DEBUG 817 //#ifdef DEBUG 818 #if 0 808 819 { 809 820 uint64_t ts_tail=0; … … 823 834 } 824 835 825 debugOutput(DEBUG_LEVEL_VERBOSE,"R * HEAD: TS=%llu, FC=%llu | TAIL: TS=%llu, FC=%llu, %d\n",826 ts_ tail, fc_tail, ts_head, fc_head, cnt);836 debugOutput(DEBUG_LEVEL_VERBOSE,"R => HEAD: TS=%11llu, FC=%5llu | TAIL: TS=%11llu, FC=%5llu, %d\n", 837 ts_head, fc_head, ts_tail, fc_tail, cnt); 827 838 } 828 839 #endif 829 840 830 if(!(*it)->getFrames(m_period, ts)) {831 debugOutput(DEBUG_LEVEL_VERBOSE,"could not getFrames(%u ) from stream processor (%p)",832 m_period, *it);841 if(!(*it)->getFrames(m_period, (int64_t)m_time_of_transfer)) { 842 debugOutput(DEBUG_LEVEL_VERBOSE,"could not getFrames(%u, %11llu) from stream processor (%p)", 843 m_period, m_time_of_transfer,*it); 833 844 return false; // buffer underrun 834 845 } 835 846 836 #ifdef DEBUG 847 //#ifdef DEBUG 848 #if 0 837 849 { 838 850 uint64_t ts_tail=0; … … 852 864 } 853 865 854 debugOutput(DEBUG_LEVEL_VERBOSE,"R > HEAD: TS=%llu, FC=%llu | TAIL: TS=%llu, FC=%llu, %d\n",855 ts_ tail, fc_tail, ts_head, fc_head, cnt);866 debugOutput(DEBUG_LEVEL_VERBOSE,"R > HEAD: TS=%11llu, FC=%5llu | TAIL: TS=%11llu, FC=%5llu, %d\n", 867 ts_head, fc_head, ts_tail, fc_tail, cnt); 856 868 } 857 869 #endif … … 863 875 ++it ) { 864 876 865 #ifdef DEBUG 877 //#ifdef DEBUG 878 #if 0 866 879 { 867 880 uint64_t ts_tail=0; … … 881 894 } 882 895 883 debugOutput(DEBUG_LEVEL_VERBOSE,"T * HEAD: TS=%llu, FC=%llu | TAIL: TS=%llu, FC=%llu, %d\n",884 ts_ tail, fc_tail, ts_head, fc_head, cnt);896 debugOutput(DEBUG_LEVEL_VERBOSE,"T => HEAD: TS=%11llu, FC=%5llu | TAIL: TS=%11llu, FC=%5llu, %d\n", 897 ts_head, fc_head, ts_tail, fc_tail, cnt); 885 898 } 886 899 #endif 887 900 888 if(!(*it)->putFrames(m_period, time_of_transfer)) {901 if(!(*it)->putFrames(m_period, (int64_t)m_time_of_transfer)) { 889 902 debugOutput(DEBUG_LEVEL_VERBOSE, "could not putFrames(%u,%llu) to stream processor (%p)", 890 m_period, time_of_transfer, *it);903 m_period, m_time_of_transfer, *it); 891 904 return false; // buffer overrun 892 905 } 893 906 894 #ifdef DEBUG 907 //#ifdef DEBUG 908 #if 0 895 909 { 896 910 uint64_t ts_tail=0; … … 910 924 } 911 925 912 debugOutput(DEBUG_LEVEL_VERBOSE,"T > HEAD: TS=%llu, FC=%llu | TAIL: TS=%llu, FC=%llu, %d\n",913 ts_ tail, fc_tail, ts_head, fc_head, cnt);926 debugOutput(DEBUG_LEVEL_VERBOSE,"T > HEAD: TS=%11llu, FC=%5llu | TAIL: TS=%11llu, FC=%5llu, %d\n", 927 ts_head, fc_head, ts_tail, fc_tail, cnt); 914 928 } 915 929 #endif … … 923 937 debugOutputShort( DEBUG_LEVEL_NORMAL, "----------------------------------------------------\n"); 924 938 debugOutputShort( DEBUG_LEVEL_NORMAL, "Dumping StreamProcessorManager information...\n"); 925 debugOutputShort( DEBUG_LEVEL_NORMAL, "Period count: % d\n", m_nbperiods);939 debugOutputShort( DEBUG_LEVEL_NORMAL, "Period count: %6d\n", m_nbperiods); 926 940 927 941 debugOutputShort( DEBUG_LEVEL_NORMAL, " Receive processors...\n");