Changeset 1348
- Timestamp:
- 09/24/08 09:45:50 (15 years ago)
- Files:
-
- trunk/libffado/config.h.in (modified) (2 diffs)
- trunk/libffado/src/libieee1394/CycleTimerHelper.cpp (modified) (3 diffs)
- trunk/libffado/src/libieee1394/CycleTimerHelper.h (modified) (1 diff)
- trunk/libffado/src/libieee1394/ieee1394service.cpp (modified) (1 diff)
- trunk/libffado/src/libieee1394/ieee1394service.h (modified) (1 diff)
- trunk/libffado/src/libieee1394/IsoHandler.cpp (modified) (3 diffs)
- trunk/libffado/src/libieee1394/IsoHandler.h (modified) (1 diff)
- trunk/libffado/src/libieee1394/IsoHandlerManager.cpp (modified) (4 diffs)
- trunk/libffado/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.cpp (modified) (3 diffs)
- trunk/libffado/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.h (modified) (1 diff)
- trunk/libffado/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp (modified) (1 diff)
- trunk/libffado/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.h (modified) (1 diff)
- trunk/libffado/src/libstreaming/generic/StreamProcessor.cpp (modified) (4 diffs)
- trunk/libffado/src/libstreaming/generic/StreamProcessor.h (modified) (2 diffs)
- trunk/libffado/src/libstreaming/motu/MotuReceiveStreamProcessor.cpp (modified) (1 diff)
- trunk/libffado/src/libstreaming/motu/MotuReceiveStreamProcessor.h (modified) (1 diff)
- trunk/libffado/src/libstreaming/motu/MotuTransmitStreamProcessor.cpp (modified) (1 diff)
- trunk/libffado/src/libstreaming/motu/MotuTransmitStreamProcessor.h (modified) (1 diff)
- trunk/libffado/src/libstreaming/StreamProcessorManager.cpp (modified) (10 diffs)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/libffado/config.h.in
r1336 r1348 64 64 #define MAX_XMIT_NB_BUFFERS 200 65 65 66 // should be PAGE_SIZE (4096) for unpatched kernels 67 #define RAW1394_RCV_MIN_BUF_STRIDE 4096 68 66 69 #define ISOHANDLER_FLUSH_BEFORE_ITERATE 0 67 70 … … 94 97 // time to a later time instant also causes the xmit buffer fill to be 95 98 // lower on average. 96 #define STREAMPROCESSORMANAGER_SIGNAL_DELAY_TICKS (3072*6) 99 #define STREAMPROCESSORMANAGER_SIGNAL_DELAY_TICKS (3072*0) 100 101 // causes the waitForPeriod() call to wait until sufficient 102 // data is present in the buffer such that a transfer() will 103 // succeed. Normally we wait for the period of time that theoretically 104 // would mean that his is true. However sometimes the kernel hasn't 105 // flushed everything to userspace (or the card hasn't IRQ'd). 106 // the side-effect of this is some jitter in the return timing 107 // whenever this occurs. 108 #define STREAMPROCESSORMANAGER_ALLOW_DELAYED_PERIOD_SIGNAL 1 97 109 98 110 // startup control trunk/libffado/src/libieee1394/CycleTimerHelper.cpp
r1336 r1348 654 654 } 655 655 656 uint64_t 657 CycleTimerHelper::getSystemTimeForCycleTimerTicks(uint32_t ticks) 658 { 659 uint64_t retval; 660 struct compute_vars *my_vars; 661 662 // get pointer and copy the contents 663 // no locking should be needed since we have more than one 664 // of these vars available, and our use will always be finished before 665 // m_current_shadow_idx changes since this thread's priority should 666 // be higher than the one of the writer thread. Even if not, we only have to ensure 667 // that the used dataset is consistent. We can use an older dataset if it's consistent 668 // since it will also provide a fairly decent extrapolation. 669 my_vars = m_shadow_vars + m_current_shadow_idx; 670 671 // the number of ticks the request is ahead of the current CTR position 672 int64_t ticks_diff = diffTicks(ticks, my_vars->ticks); 673 // to how much time does this correspond? 674 double x_step_in_usec = ((double)ticks_diff) / my_vars->rate; 675 int64_t x_step_in_usec_int = (int64_t)x_step_in_usec; 676 retval = my_vars->usecs + x_step_in_usec_int; 677 678 return retval; 679 } 680 681 uint64_t 682 CycleTimerHelper::getSystemTimeForCycleTimer(uint32_t ctr) 683 { 684 uint32_t ticks = CYCLE_TIMER_TO_TICKS(ctr); 685 return getSystemTimeForCycleTimerTicks(ticks); 686 } 687 656 688 #else 657 689 … … 685 717 CycleTimerHelper::getCycleTimerTicks(uint64_t now) 686 718 { 687 debugWarning("not implemented!\n"); 688 return getCycleTimerTicks(); 719 debugWarning("untested code\n"); 720 #warning Untested code 721 uint32_t cycle_timer; 722 uint64_t local_time; 723 readCycleTimerWithRetry(&cycle_timer, &local_time, 10); 724 int64_t ticks = CYCLE_TIMER_TO_TICKS(cycle_timer); 725 726 int delta_t = now - local_time; // how far ahead is the request? 727 ticks += delta_t * getRate(); // add ticks 728 if (ticks >= TICKS_PER_SECOND * 128) ticks -= TICKS_PER_SECOND * 128; 729 else if (ticks < 0) ticks += TICKS_PER_SECOND * 128; 730 return ticks; 689 731 } 690 732 … … 701 743 CycleTimerHelper::getCycleTimer(uint64_t now) 702 744 { 745 return TICKS_TO_CYCLE_TIMER(getCycleTimerTicks(now)); 746 } 747 748 uint64_t 749 CycleTimerHelper::getSystemTimeForCycleTimerTicks(uint32_t ticks) 750 { 703 751 debugWarning("not implemented!\n"); 704 return getCycleTimer(); 752 return 0; 753 } 754 755 uint64_t 756 CycleTimerHelper::getSystemTimeForCycleTimer(uint32_t ctr) 757 { 758 uint32_t ticks = CYCLE_TIMER_TO_TICKS(ctr); 759 return getSystemTimeForCycleTimerTicks(ticks); 705 760 } 706 761 trunk/libffado/src/libieee1394/CycleTimerHelper.h
r1080 r1348 98 98 uint32_t getCycleTimer(uint64_t now); 99 99 100 /** 101 * @brief get the system time for a specific cycle timer value (in ticks) 102 * @note thread safe 103 */ 104 uint64_t getSystemTimeForCycleTimerTicks(uint32_t ticks); 105 106 /** 107 * @brief get the system time for a specific cycle timer value (in CTR format) 108 * @note thread safe 109 */ 110 uint64_t getSystemTimeForCycleTimer(uint32_t ctr); 111 100 112 float getRate(); 101 113 float getNominalRate(); trunk/libffado/src/libieee1394/ieee1394service.cpp
r1336 r1348 401 401 } 402 402 403 uint64_t 404 Ieee1394Service::getSystemTimeForCycleTimerTicks(uint32_t ticks) { 405 return m_pCTRHelper->getSystemTimeForCycleTimerTicks(ticks); 406 } 407 408 uint64_t 409 Ieee1394Service::getSystemTimeForCycleTimer(uint32_t ctr) { 410 return m_pCTRHelper->getSystemTimeForCycleTimer(ctr); 411 } 412 403 413 bool 404 414 Ieee1394Service::readCycleTimerReg(uint32_t *cycle_timer, uint64_t *local_time) trunk/libffado/src/libieee1394/ieee1394service.h
r1336 r1348 134 134 */ 135 135 uint32_t getCycleTimer(uint64_t t); 136 137 /** 138 * @brief get the system time for a specific cycle timer value (in ticks) 139 * @note thread safe 140 */ 141 uint64_t getSystemTimeForCycleTimerTicks(uint32_t ticks); 142 143 /** 144 * @brief get the system time for a specific cycle timer value (in CTR format) 145 * @note thread safe 146 */ 147 uint64_t getSystemTimeForCycleTimer(uint32_t ctr); 136 148 137 149 /** trunk/libffado/src/libieee1394/IsoHandler.cpp
r1336 r1348 475 475 // leave the offset field (for now?) 476 476 477 debugOutput (DEBUG_LEVEL_ULTRA_VERBOSE,477 debugOutputExtreme(DEBUG_LEVEL_ULTRA_VERBOSE, 478 478 "received packet: length=%d, channel=%d, cycle=%d, at %08X\n", 479 479 length, channel, cycle, pkt_ctr); … … 566 566 m_last_packet_handled_at = pkt_ctr; 567 567 } 568 debugOutput (DEBUG_LEVEL_ULTRA_VERBOSE,568 debugOutputExtreme(DEBUG_LEVEL_ULTRA_VERBOSE, 569 569 "sending packet: length=%d, cycle=%d, at %08X\n", 570 570 *length, cycle, pkt_ctr); … … 670 670 dumpInfo(); 671 671 if (getType() == eHT_Receive) { 672 if(m_irq_interval > 1) { 673 if(raw1394_iso_recv_init(m_handle, 674 iso_receive_handler, 675 m_buf_packets, 676 m_max_packet_size, 677 m_Client->getChannel(), 678 RAW1394_DMA_BUFFERFILL, 679 // RAW1394_DMA_PACKET_PER_BUFFER, 680 m_irq_interval)) { 681 debugFatal("Could not do receive initialisation (DMA_BUFFERFILL)!\n" ); 682 debugFatal(" %s\n",strerror(errno)); 683 return false; 684 } 685 } else { 686 if(raw1394_iso_recv_init(m_handle, 687 iso_receive_handler, 688 m_buf_packets, 689 m_max_packet_size, 690 m_Client->getChannel(), 691 RAW1394_DMA_PACKET_PER_BUFFER, 692 m_irq_interval)) { 693 debugFatal("Could not do receive initialisation (PACKET_PER_BUFFER)!\n" ); 694 debugFatal(" %s\n",strerror(errno)); 695 return false; 696 } 672 if(raw1394_iso_recv_init(m_handle, 673 iso_receive_handler, 674 m_buf_packets, 675 m_max_packet_size, 676 m_Client->getChannel(), 677 RAW1394_DMA_PACKET_PER_BUFFER, 678 m_irq_interval)) { 679 debugFatal("Could not do receive initialisation (DMA_BUFFERFILL)!\n" ); 680 debugFatal(" %s\n",strerror(errno)); 681 return false; 697 682 } 698 683 return true; trunk/libffado/src/libieee1394/IsoHandler.h
r1336 r1348 119 119 unsigned int getMaxPacketSize() { return m_max_packet_size;}; 120 120 unsigned int getNbBuffers() { return m_buf_packets;}; 121 int get PacketLatency() { return m_irq_interval;};121 int getIrqInterval() { return m_irq_interval;}; 122 122 123 123 unsigned int getPreBuffers() {return m_prebuffers;}; trunk/libffado/src/libieee1394/IsoHandlerManager.cpp
r1336 r1348 353 353 #ifdef DEBUG 354 354 if(m_poll_fds_shadow[i].revents) { 355 debugOutput (DEBUG_LEVEL_ULTRA_VERBOSE,355 debugOutputExtreme(DEBUG_LEVEL_VERBOSE, 356 356 "(%p, %s) received events: %08X for (%d/%d, %p, %s)\n", 357 357 this, (m_handlerType == IsoHandler::eHT_Transmit? "Transmit": "Receive"), … … 761 761 // setup the optimal parameters for the raw1394 ISO buffering 762 762 unsigned int packets_per_period = stream->getPacketsPerPeriod(); 763 unsigned int max_packet_size = stream->getMaxPacketSize() ;764 unsigned int page_size = getpagesize() - 2; // for one reason or another this is necessary763 unsigned int max_packet_size = stream->getMaxPacketSize() + 8; // bufferfill takes another 8 bytes for headers 764 unsigned int page_size = getpagesize(); 765 765 766 766 // Ensure we don't request a packet size bigger than the 767 767 // kernel-enforced maximum which is currently 1 page. 768 // NOTE: PP: this is not really true AFAICT 768 769 if (max_packet_size > page_size) { 769 770 debugError("max packet size (%u) > page size (%u)\n", max_packet_size, page_size); … … 771 772 } 772 773 773 unsigned int irq_interval = packets_per_period / MINIMUM_INTERRUPTS_PER_PERIOD; 774 // the interrupt/wakeup interval prediction of raw1394 is a mess... 775 int irq_interval = (packets_per_period-1) / MINIMUM_INTERRUPTS_PER_PERIOD; 774 776 if(irq_interval <= 0) irq_interval=1; 775 777 776 778 // the receive buffer size doesn't matter for the latency, 777 779 // but it has a minimal value in order for libraw to operate correctly (300) … … 977 979 { 978 980 if((*it)->isStreamRegistered(stream)) { 979 return (*it)->get PacketLatency();981 return (*it)->getIrqInterval(); 980 982 } 981 983 } trunk/libffado/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.cpp
r1254 r1348 34 34 #include "libutil/ByteSwap.h" 35 35 #include <assert.h> 36 #include "libutil/SystemTimeSource.h" 36 37 37 38 namespace Streaming { … … 66 67 } 67 68 69 unsigned int 70 AmdtpReceiveStreamProcessor::getAveragePacketSize() 71 { 72 // in one second we have 8000 packets 73 // containing FRAMERATE frames of m_dimension quadlets 74 // so 8000 packet headers + FRAMERATE*m_dimension quadlets 75 unsigned int one_second = 8000 * 2 * sizeof(quadlet_t) + m_StreamProcessorManager.getNominalRate() * m_dimension * sizeof(quadlet_t); 76 return one_second / 8000; 77 } 78 68 79 bool AmdtpReceiveStreamProcessor::prepareChild() { 69 80 debugOutput( DEBUG_LEVEL_VERBOSE, "Preparing (%p)...\n", this); … … 144 155 // later than expected (the real receive time) 145 156 #ifdef DEBUG 157 static int64_t last_t = Util::SystemTimeSource::getCurrentTime(); 158 int64_t now_t = Util::SystemTimeSource::getCurrentTime(); 146 159 if(isRunning()) { 147 160 debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, 148 161 "STMP: %lluticks | syt_interval=%d, tpf=%f\n", 149 162 m_last_timestamp, m_syt_interval, getTicksPerFrame()); 150 } 163 /* debugOutput(DEBUG_LEVEL_NORMAL, 164 "STMP: %12llu ticks | delta_t: %5lld | bufferfill: %5d\n", 165 m_last_timestamp, now_t-last_t, m_data_buffer->getBufferFill());*/ 166 } 167 last_t = now_t; 151 168 152 169 // check whether nevents is a multiple of 8. trunk/libffado/src/libstreaming/amdtp/AmdtpReceiveStreamProcessor.h
r1035 r1348 90 90 virtual unsigned int getMaxPacketSize() 91 91 {return 4 * (2 + getSytInterval() * m_dimension);}; 92 virtual unsigned int getAveragePacketSize(); 92 93 virtual unsigned int getEventsPerFrame() 93 94 { return m_dimension; }; trunk/libffado/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp
r1336 r1348 406 406 } 407 407 } 408 409 unsigned int 410 AmdtpTransmitStreamProcessor::getAveragePacketSize() 411 { 412 // in one second we have 8000 packets 413 // containing FRAMERATE frames of m_dimension quadlets 414 // so 8000 packet headers + FRAMERATE*m_dimension quadlets 415 unsigned int one_second = 8000 * 2 * sizeof(quadlet_t) + m_StreamProcessorManager.getNominalRate() * m_dimension * sizeof(quadlet_t); 416 return one_second / 8000; 417 } 418 408 419 unsigned int 409 420 AmdtpTransmitStreamProcessor::getFDF() { trunk/libffado/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.h
r1347 r1348 105 105 virtual unsigned int getMaxPacketSize() 106 106 {return 4 * (2 + getSytInterval() * m_dimension);}; 107 virtual unsigned int getAveragePacketSize(); 107 108 virtual unsigned int getEventsPerFrame() 108 109 { return m_dimension; }; trunk/libffado/src/libstreaming/generic/StreamProcessor.cpp
r1336 r1348 146 146 StreamProcessor::getNominalPacketsNeeded(unsigned int nframes) 147 147 { 148 unsigned int nominal_frames_per_second 148 unsigned int nominal_frames_per_second 149 149 = m_StreamProcessorManager.getNominalRate(); 150 150 uint64_t nominal_ticks_per_frame = TICKS_PER_SECOND / nominal_frames_per_second; 151 151 uint64_t nominal_ticks = nominal_ticks_per_frame * nframes; 152 uint64_t nominal_packets = nominal_ticks / TICKS_PER_CYCLE; 152 // ensure proper ceiling 153 uint64_t nominal_packets = (nominal_ticks+TICKS_PER_CYCLE-1) / TICKS_PER_CYCLE; 153 154 return nominal_packets; 154 155 } … … 219 220 debugOutput(DEBUG_LEVEL_VERBOSE, "Setting SP %p SyncDelay to %u ticks, %u frames\n", this, d, frames); 220 221 #endif 221 m_sync_delay = d; // FIXME: sync delay not necessary anymore 222 m_sync_delay = d; 223 } 224 225 unsigned int 226 StreamProcessor::getSyncDelayFrames() { 227 unsigned int frames = (unsigned int)((float)m_sync_delay / getTicksPerFrame()); 228 return frames; 222 229 } 223 230 … … 508 515 unsigned int bufferfill = m_data_buffer->getBufferFill(); 509 516 if(bufferfill >= periodsize) { 510 debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "signal activity, %d>%d\n", bufferfill, periodsize); 511 SIGNAL_ACTIVITY_SPM; 512 return RAW1394_ISO_DEFER; 517 debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "signal activity, %d>%d\n", 518 bufferfill, periodsize); 519 //SIGNAL_ACTIVITY_SPM; 520 return RAW1394_ISO_DEFER; // FIXME: might not be needed 513 521 } 514 522 return RAW1394_ISO_OK; … … 1509 1517 if (getType() == ePT_Transmit) { 1510 1518 ringbuffer_size_frames = m_StreamProcessorManager.getNbBuffers() * m_StreamProcessorManager.getPeriodSize(); 1519 1520 // add sync delay 1521 int syncdelay_in_frames = m_StreamProcessorManager.getSyncSource().getSyncDelayFrames(); 1522 ringbuffer_size_frames += syncdelay_in_frames; 1523 1511 1524 debugOutput(DEBUG_LEVEL_VERBOSE, "Prefill transmit SP %p with %u frames\n", this, ringbuffer_size_frames); 1512 1525 // prefill the buffer trunk/libffado/src/libstreaming/generic/StreamProcessor.h
r1336 r1348 290 290 virtual unsigned int getPacketsPerPeriod(); 291 291 virtual unsigned int getMaxPacketSize() = 0; 292 virtual unsigned int getAveragePacketSize() = 0; 292 293 private: 293 294 int m_channel; … … 376 377 * Returns the sync delay. This is the time a syncsource 377 378 * delays a period signal, e.g. to cope with buffering. 378 * @return the sync delay 379 * @return the sync delay (in ticks) 379 380 */ 380 381 unsigned int getSyncDelay() {return m_sync_delay;}; 382 unsigned int getSyncDelayFrames(); 381 383 /** 382 384 * sets the sync delay trunk/libffado/src/libstreaming/motu/MotuReceiveStreamProcessor.cpp
r1254 r1348 96 96 97 97 unsigned int 98 MotuReceiveStreamProcessor::getAveragePacketSize() 99 { 100 // in one second we have 8000 packets 101 // containing FRAMERATE frames 102 // so on average bytes/packet: (8000 packet headers + FRAMERATE * frame_size) / 8000 103 #warning FIXME 104 int framerate = m_Parent.getDeviceManager().getStreamProcessorManager().getNominalRate(); 105 return framerate<=48000?616:(framerate<=96000?1032:1160); 106 } 107 108 unsigned int 98 109 MotuReceiveStreamProcessor::getNominalFramesPerPacket() { 99 110 int framerate = m_Parent.getDeviceManager().getStreamProcessorManager().getNominalRate(); trunk/libffado/src/libstreaming/motu/MotuReceiveStreamProcessor.h
r1035 r1348 152 152 {return m_event_size;}; 153 153 virtual unsigned int getMaxPacketSize(); 154 virtual unsigned int getAveragePacketSize(); 154 155 virtual unsigned int getEventsPerFrame() 155 156 { return 1; }; // FIXME: check trunk/libffado/src/libstreaming/motu/MotuTransmitStreamProcessor.cpp
r1254 r1348 91 91 92 92 unsigned int 93 MotuTransmitStreamProcessor::getAveragePacketSize() 94 { 95 // in one second we have 8000 packets 96 // containing FRAMERATE frames 97 // so on average bytes/packet: (8000 packet headers + FRAMERATE * frame_size) / 8000 98 #warning FIXME 99 int framerate = m_Parent.getDeviceManager().getStreamProcessorManager().getNominalRate(); 100 return framerate<=48000?616:(framerate<=96000?1032:1160); 101 } 102 103 unsigned int 93 104 MotuTransmitStreamProcessor::getNominalFramesPerPacket() { 94 105 int framerate = m_Parent.getDeviceManager().getStreamProcessorManager().getNominalRate(); trunk/libffado/src/libstreaming/motu/MotuTransmitStreamProcessor.h
r1034 r1348 76 76 {return m_event_size;}; 77 77 virtual unsigned int getMaxPacketSize(); 78 virtual unsigned int getAveragePacketSize(); 78 79 virtual unsigned int getEventsPerFrame() 79 80 { return 1; }; // FIXME: check trunk/libffado/src/libstreaming/StreamProcessorManager.cpp
r1336 r1348 462 462 // lower on average. 463 463 max_of_min_delay += STREAMPROCESSORMANAGER_SIGNAL_DELAY_TICKS; 464 debugOutput( DEBUG_LEVEL_VERBOSE, " sync delay = %d ticks (%03us %04uc %04ut)...\n", 465 max_of_min_delay, 466 (unsigned int)TICKS_TO_SECS(max_of_min_delay), 467 (unsigned int)TICKS_TO_CYCLES(max_of_min_delay), 468 (unsigned int)TICKS_TO_OFFSET(max_of_min_delay)); 464 469 465 m_SyncSource->setSyncDelay(max_of_min_delay); 466 unsigned int syncdelay = m_SyncSource->getSyncDelay(); 467 debugOutput( DEBUG_LEVEL_VERBOSE, " sync delay = %d => %d ticks (%03us %04uc %04ut)...\n", 468 max_of_min_delay, syncdelay, 469 (unsigned int)TICKS_TO_SECS(syncdelay), 470 (unsigned int)TICKS_TO_CYCLES(syncdelay), 471 (unsigned int)TICKS_TO_OFFSET(syncdelay)); 470 472 471 473 //STEP X: when we implement such a function, we can wait for a signal from the devices that they … … 477 479 // DLL to have a decent sync (FIXME: does the DLL get updated when dry-running)? 478 480 debugOutput( DEBUG_LEVEL_VERBOSE, "Waiting for sync...\n"); 479 481 480 482 unsigned int nb_sync_runs = (STREAMPROCESSORMANAGER_SYNC_WAIT_TIME_MSEC * getNominalRate()); 481 483 nb_sync_runs /= 1000; … … 600 602 float rate = m_SyncSource->getTicksPerFrame(); 601 603 int64_t delay_in_ticks=(int64_t)(((float)((m_nb_buffers-1) * m_period)) * rate); 604 // also add the sync delay 605 delay_in_ticks += m_SyncSource->getSyncDelay(); 602 606 debugOutput( DEBUG_LEVEL_VERBOSE, " initial time of transfer %010lld, rate %f...\n", 603 607 m_time_of_transfer, rate); … … 930 934 bool xrun_occurred = false; 931 935 bool in_error = false; 932 bool period_not_ready = true;933 936 934 937 // grab the wait lock 935 938 // this ensures that bus reset handling doesn't interfere 936 939 Util::MutexLockHelper lock(*m_WaitLock); 937 940 debugOutputExtreme(DEBUG_LEVEL_VERBOSE, 941 "waiting for period (%d frames in buffer)...\n", 942 m_SyncSource->getBufferFill()); 943 uint64_t ticks_at_period = m_SyncSource->getTimeAtPeriod(); 944 uint64_t ticks_at_period_margin = ticks_at_period + m_SyncSource->getSyncDelay(); 945 uint64_t pred_system_time_at_xfer = m_SyncSource->getParent().get1394Service().getSystemTimeForCycleTimerTicks(ticks_at_period_margin); 946 947 #ifdef DEBUG 948 int64_t now = Util::SystemTimeSource::getCurrentTime(); 949 debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "pred: %lld, now: %lld, wait: %lld\n", pred_system_time_at_xfer, now, pred_system_time_at_xfer-now ); 950 #endif 951 952 // wait until it's time to transfer 953 Util::SystemTimeSource::SleepUsecAbsolute(pred_system_time_at_xfer); 954 955 #ifdef DEBUG 956 now = Util::SystemTimeSource::getCurrentTime(); 957 debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "pred: %lld now: %lld, excess: %lld\n", pred_system_time_at_xfer, now, now-pred_system_time_at_xfer ); 958 #endif 959 960 // the period should be ready now 961 962 #if STREAMPROCESSORMANAGER_ALLOW_DELAYED_PERIOD_SIGNAL 963 // HACK: we force wait until every SP is ready. this is needed 964 // since the raw1394 interface provides no control over interrupts 965 // resulting in very bad predictability on when the data is present. 966 bool period_not_ready = true; 938 967 while(period_not_ready) { 939 debugOutputExtreme(DEBUG_LEVEL_VERBOSE,940 "waiting for period (%d frames in buffer)...\n",941 m_SyncSource->getBufferFill());942 943 // wait for something to happen944 switch(waitForActivity()) {945 case eAR_Error:946 debugError("Error while waiting for activity\n");947 m_shutdown_needed = true;948 return false;949 case eAR_Interrupted:950 // FIXME: what to do here?951 debugWarning("Interrupted while waiting for activity\n");952 break;953 case eAR_Timeout:954 debugWarning("Timeout while waiting for activity\n");955 // ignore this since it can also be due to some other hardware956 // or high-prio software that preempts us. hence only an xrun should957 // be generated (if necessary)958 case eAR_Activity:959 // do nothing960 break;961 }962 debugOutputExtreme(DEBUG_LEVEL_VERBOSE, "got activity...\n");963 964 // HACK: this should be solved more elegantly965 968 period_not_ready = false; 966 969 for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); … … 980 983 } 981 984 } 982 debugOutputExtreme(DEBUG_LEVEL_VERBOSE, " period not ready? %d...\n", period_not_ready); 985 986 if (period_not_ready) { 987 debugOutput(DEBUG_LEVEL_VERBOSE, " wait extended since period not ready...\n"); 988 Util::SystemTimeSource::SleepUsecRelative(125); // one cycle 989 } 983 990 984 991 // check for underruns/errors on the ISO side, … … 1000 1007 if(xrun_occurred | in_error | m_shutdown_needed) break; 1001 1008 } 1009 #else 1010 // check for underruns/errors on the ISO side, 1011 // those should make us bail out of the wait loop 1012 for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 1013 it != m_ReceiveProcessors.end(); 1014 ++it ) { 1015 // xrun on data buffer side 1016 if (!(*it)->canConsumePeriod()) { 1017 xrun_occurred = true; 1018 } 1019 // a xrun has occurred on the Iso side 1020 xrun_occurred |= (*it)->xrunOccurred(); 1021 in_error |= (*it)->inError(); 1022 } 1023 for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 1024 it != m_TransmitProcessors.end(); 1025 ++it ) { 1026 // xrun on data buffer side 1027 if (!(*it)->canProducePeriod()) { 1028 xrun_occurred = true; 1029 } 1030 // a xrun has occurred on the Iso side 1031 xrun_occurred |= (*it)->xrunOccurred(); 1032 in_error |= (*it)->inError(); 1033 } 1034 #endif 1002 1035 1003 1036 if(xrun_occurred) { … … 1032 1065 #endif 1033 1066 1034 debugOutputExtreme( 1067 debugOutputExtreme(DEBUG_LEVEL_VERBOSE, 1035 1068 "transfer period %d at %llu ticks...\n", 1036 1069 m_nbperiods, m_time_of_transfer); … … 1038 1071 // this is to notify the client of the delay that we introduced by waiting 1039 1072 m_delayed_usecs = - m_SyncSource->getTimeUntilNextPeriodSignalUsecs(); 1040 debugOutputExtreme( DEBUG_LEVEL_VERY_VERBOSE,1073 debugOutputExtreme(DEBUG_LEVEL_VERBOSE, 1041 1074 "delayed for %d usecs...\n", 1042 1075 m_delayed_usecs); … … 1146 1179 // the data we are putting into the buffer is intended to be transmitted 1147 1180 // one ringbuffer size after it has been received 1148 int64_t transmit_timestamp = addTicks(m_time_of_transfer, one_ringbuffer_in_ticks); 1181 1182 // we also add one syncdelay as a safety margin, since that's the amount of time we can get 1183 // postponed. 1184 int syncdelay = m_SyncSource->getSyncDelay(); 1185 int64_t transmit_timestamp = addTicks(m_time_of_transfer, one_ringbuffer_in_ticks + syncdelay); 1149 1186 1150 1187 for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); … … 1222 1259 // the data we are putting into the buffer is intended to be transmitted 1223 1260 // one ringbuffer size after it has been received 1224 int64_t transmit_timestamp = addTicks(m_time_of_transfer, one_ringbuffer_in_ticks); 1261 // we also add one syncdelay as a safety margin, since that's the amount of time we can get 1262 // postponed. 1263 int syncdelay = m_SyncSource->getSyncDelay(); 1264 int64_t transmit_timestamp = addTicks(m_time_of_transfer, one_ringbuffer_in_ticks + syncdelay); 1225 1265 1226 1266 for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();