Changeset 1001
- Timestamp:
- 04/19/08 05:18:01 (16 years ago)
- Files:
-
- trunk/libffado/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp (modified) (3 diffs)
- trunk/libffado/src/libstreaming/generic/StreamProcessor.cpp (modified) (9 diffs)
- trunk/libffado/src/libstreaming/generic/StreamProcessor.h (modified) (3 diffs)
- trunk/libffado/src/libstreaming/motu/MotuTransmitStreamProcessor.cpp (modified) (5 diffs)
- trunk/libffado/src/libstreaming/StreamProcessorManager.cpp (modified) (7 diffs)
- trunk/libffado/src/libutil/TimestampedBuffer.cpp (modified) (1 diff)
- trunk/libffado/src/libutil/TimestampedBuffer.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
- Modified
- Copied
- Moved
trunk/libffado/src/libstreaming/amdtp/AmdtpTransmitStreamProcessor.cpp
r979 r1001 95 95 // to be output by the device 96 96 presentation_time = ( uint64_t ) ts_head_tmp; 97 m_last_timestamp = presentation_time;98 97 99 98 // now we calculate the time when we have to transmit the sample block … … 211 210 // // we are not that late and can still try to transmit the packet 212 211 // m_dbc += fillDataPacketHeader(packet, length, m_last_timestamp); 212 // m_last_timestamp = presentation_time; 213 213 // return (fc < (signed)(2*m_syt_interval) ? eCRV_Defer : eCRV_Packet); 214 214 // } … … 222 222 // it's time send the packet 223 223 m_dbc += fillDataPacketHeader(packet, length, m_last_timestamp); 224 m_last_timestamp = presentation_time; 225 226 // FIXME: this should not be multiplied by 2 224 227 return (fc < (signed)(2*m_syt_interval) ? eCRV_Defer : eCRV_Packet); 225 228 } trunk/libffado/src/libstreaming/generic/StreamProcessor.cpp
r1000 r1001 254 254 } 255 255 256 void 257 StreamProcessor::setTicksPerFrame(float tpf) 258 { 259 assert(m_data_buffer != NULL); 260 m_data_buffer->setRate(tpf); 261 } 262 256 263 bool 257 264 StreamProcessor::canClientTransferFrames(unsigned int nbframes) … … 306 313 m_dropped += dropped_cycles; 307 314 m_last_cycle = cycle; 315 m_Parent.showDevice(); 316 // flushDebugOutput(); 317 // assert(0); 308 318 } 309 319 } … … 384 394 if (result == eCRV_OK) { 385 395 #ifdef DEBUG 386 int ticks_per_packet = getTicksPerFrame() * getNominalFramesPerPacket();396 int ticks_per_packet = (int)(getTicksPerFrame() * getNominalFramesPerPacket()); 387 397 int diff=diffTicks(m_last_timestamp, m_last_timestamp2); 388 398 // display message if the difference between two successive tick … … 390 400 // so 50 ticks = 10%, which is a rather large jitter value. 391 401 if(diff-ticks_per_packet > 50 || diff-ticks_per_packet < -50) { 392 debugOutput(DEBUG_LEVEL_VERBOSE, "rather large TSP difference TS=%011llu => TS=%011llu (%d, nom %d)\n", 393 m_last_timestamp2, m_last_timestamp, diff, ticks_per_packet); 394 } 402 debugOutput(DEBUG_LEVEL_VERBOSE, 403 "cy %04u rather large TSP difference TS=%011llu => TS=%011llu (%d, nom %d)\n", 404 cycle, m_last_timestamp2, m_last_timestamp, diff, ticks_per_packet); 405 } 406 debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, 407 "%04u %011llu %011llu %d %d\n", 408 cycle, m_last_timestamp2, m_last_timestamp, 409 diff, ticks_per_packet); 395 410 #endif 396 411 … … 496 511 497 512 unsigned int ctr; 513 uint64_t prev_timestamp; 498 514 int now_cycles; 499 515 int cycle_diff; … … 594 610 595 611 // store the previous timestamp 596 m_last_timestamp2 = m_last_timestamp; 597 612 // keep the old value here, update m_last_timestamp2 only when 613 // a valid packet will be sent 614 prev_timestamp = m_last_timestamp; 615 598 616 // NOTE: synchronized switching is restricted to a 0.5 sec span (4000 cycles) 599 617 // it happens on the first 'good' cycle for the wait condition … … 624 642 generateSilentPacketData(data, length, tag, sy, cycle, dropped_cycles, max_length); 625 643 return RAW1394_ISO_OK; 644 // FIXME: PP: I think this should be possible too 645 //} else if (result == eCRV_EmptyPacket) { 646 // goto send_empty_packet; 626 647 } else { 627 648 debugError("Invalid return value: %d\n", result); … … 672 693 m_last_good_cycle = cycle; 673 694 m_last_dropped = dropped_cycles; 695 696 // valid packet timestamp 697 m_last_timestamp2 = prev_timestamp; 674 698 675 699 // check whether a state change has been requested … … 701 725 goto send_empty_packet; 702 726 } 727 #ifdef DEBUG 728 int ticks_per_packet = (int)(getTicksPerFrame() * getNominalFramesPerPacket()); 729 int diff=diffTicks(m_last_timestamp, m_last_timestamp2); 730 // display message if the difference between two successive tick 731 // values is more than 50 ticks. 1 sample at 48k is 512 ticks 732 // so 50 ticks = 10%, which is a rather large jitter value. 733 if(diff-ticks_per_packet > 50 || diff-ticks_per_packet < -50) { 734 debugOutput(DEBUG_LEVEL_VERBOSE, 735 "cy %04d, rather large TSP difference TS=%011llu => TS=%011llu (%d, nom %d)\n", 736 cycle, m_last_timestamp2, m_last_timestamp, diff, ticks_per_packet); 737 } 738 debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, 739 "%04d %011llu %011llu %d %d\n", 740 cycle, m_last_timestamp2, m_last_timestamp, diff, ticks_per_packet); 741 #endif 742 703 743 // skip queueing packets if we detect that there are not enough frames 704 744 // available 705 if(result2 == eCRV_Defer || result == eCRV_Defer) 745 if(result2 == eCRV_Defer || result == eCRV_Defer) { 706 746 return RAW1394_ISO_DEFER; 707 else747 } else { 708 748 return RAW1394_ISO_OK; 749 } 709 750 } else if (result == eCRV_XRun) { // pick up the possible xruns 710 751 debugWarning("generatePacketHeader xrun\n"); trunk/libffado/src/libstreaming/generic/StreamProcessor.h
r967 r1001 314 314 int m_last_good_cycle; /// FIXME:debug 315 315 uint64_t m_last_timestamp; /// last timestamp (in ticks) 316 private: 316 317 uint64_t m_last_timestamp2; /// last timestamp (in ticks) 318 protected: 317 319 bool m_correct_last_timestamp; 318 320 uint64_t m_last_timestamp_at_period_ticks; // FIXME: still used? … … 420 422 421 423 float getTicksPerFrame(); 424 void setTicksPerFrame(float tpf); 422 425 423 426 int getLastCycle() {return m_last_cycle;}; … … 466 469 */ 467 470 virtual unsigned int getNominalPacketsNeeded(unsigned int nframes); 468 469 /**470 * @brief returns the actual frame rate as calculated by the SP's DLL471 * @return the actual frame rate as detected by the DLL472 */473 float getActualRate()474 {return m_data_buffer->getRate();};475 471 476 472 protected: trunk/libffado/src/libstreaming/motu/MotuTransmitStreamProcessor.cpp
r991 r1001 128 128 // to be output by the device 129 129 presentation_time = ( uint64_t ) ts_head_tmp; 130 m_last_timestamp = presentation_time;131 130 132 131 // now we calculate the time when we have to transmit the sample block … … 224 223 // we are not that late and can still try to transmit the packet 225 224 m_tx_dbc += fillDataPacketHeader((quadlet_t *)data, length, m_last_timestamp); 225 m_last_timestamp = presentation_time; 226 226 if (m_tx_dbc > 0xff) 227 227 m_tx_dbc -= 0x100; … … 237 237 // it's time send the packet 238 238 m_tx_dbc += fillDataPacketHeader((quadlet_t *)data, length, m_last_timestamp); 239 m_last_timestamp = presentation_time; 239 240 if (m_tx_dbc > 0xff) 240 241 m_tx_dbc -= 0x100; … … 284 285 285 286 if (m_data_buffer->readFrames(n_events, (char *)(data + 8))) { 286 float ticks_per_frame = m_Parent.getDeviceManager().getStreamProcessorManager().getSyncSource().get ActualRate();287 float ticks_per_frame = m_Parent.getDeviceManager().getStreamProcessorManager().getSyncSource().getTicksPerFrame(); 287 288 288 289 #if TESTTONE … … 410 411 411 412 memset(quadlet, 0, n_events*m_event_size); 412 float ticks_per_frame = m_Parent.getDeviceManager().getStreamProcessorManager().getSyncSource().get ActualRate();413 float ticks_per_frame = m_Parent.getDeviceManager().getStreamProcessorManager().getSyncSource().getTicksPerFrame(); 413 414 414 415 // Set up each frames's SPH. trunk/libffado/src/libstreaming/StreamProcessorManager.cpp
r967 r1001 428 428 } 429 429 430 // STEP X: switch SP's over to the running state 430 // switch syncsource to running state 431 uint64_t time_to_start_sync; 432 // FIXME: this is most likely not going to work for transmit sync sources 433 // but those are unsupported in this version 434 if(m_SyncSource->getType() == StreamProcessor::ePT_Receive ) { 435 time_to_start_sync = time_to_start_recv; 436 } else { 437 time_to_start_sync = time_to_start_xmit; 438 } 439 if(!m_SyncSource->scheduleStartRunning(time_to_start_sync)) { 440 debugError("m_SyncSource->scheduleStartRunning(%11llu) failed\n", time_to_start_sync); 441 return false; 442 } 443 444 // STEP X: switch all non-syncsource SP's over to the running state 431 445 for ( StreamProcessorVectorIterator it = m_ReceiveProcessors.begin(); 432 446 it != m_ReceiveProcessors.end(); 433 447 ++it ) { 434 if(!(*it)->scheduleStartRunning(time_to_start_recv)) { 435 debugError("%p->scheduleStartRunning(%11llu) failed\n", *it, time_to_start_recv); 436 return false; 448 if(*it != m_SyncSource) { 449 if(!(*it)->scheduleStartRunning(time_to_start_recv)) { 450 debugError("%p->scheduleStartRunning(%11llu) failed\n", *it, time_to_start_recv); 451 return false; 452 } 437 453 } 438 454 } … … 440 456 it != m_TransmitProcessors.end(); 441 457 ++it ) { 442 if(!(*it)->scheduleStartRunning(time_to_start_xmit)) { 443 debugError("%p->scheduleStartRunning(%11llu) failed\n", *it, time_to_start_xmit); 444 return false; 458 if(*it != m_SyncSource) { 459 if(!(*it)->scheduleStartRunning(time_to_start_xmit)) { 460 debugError("%p->scheduleStartRunning(%11llu) failed\n", *it, time_to_start_xmit); 461 return false; 462 } 445 463 } 446 464 } 447 465 // wait for the syncsource to start running. 448 466 // that will block the waitForPeriod call until everyone has started (theoretically) 467 // note: the SP's are scheduled to start in STREAMPROCESSORMANAGER_CYCLES_FOR_STARTUP cycles, 468 // so a 20 times this value should be a good timeout 449 469 int cnt = STREAMPROCESSORMANAGER_CYCLES_FOR_STARTUP * 20; // by then it should have started 450 470 while (!m_SyncSource->isRunning() && cnt) { … … 457 477 } 458 478 479 // the sync source is running, we can now read a decent received timestamp from it 480 m_time_of_transfer = m_SyncSource->getTimeAtPeriod(); 481 482 // and a (still very rough) approximation of the rate 483 float rate = m_SyncSource->getTicksPerFrame(); 484 int64_t delay_in_ticks=(int64_t)(((float)((m_nb_buffers-1) * m_period)) * rate); 485 debugOutput( DEBUG_LEVEL_VERBOSE, " initial time of transfer %010lld, rate %f...\n", 486 m_time_of_transfer, rate); 487 488 // then use this information to initialize the xmit handlers 489 490 // we now set the buffer tail timestamp of the transmit buffer 491 // to the period transfer time instant plus what's nb_buffers - 1 492 // in ticks. This due to the fact that we (should) have received one period 493 // worth of ticks at t=m_time_of_transfer 494 // hence one period of frames should also have been transmitted, which means 495 // that there should be (nb_buffers - 1) * periodsize of frames in the xmit buffer 496 // that allows us to calculate the tail timestamp for the buffer. 497 498 int64_t transmit_tail_timestamp = addTicks(m_time_of_transfer, delay_in_ticks); 499 500 debugOutput( DEBUG_LEVEL_VERBOSE, " preset transmit tail TS %010lld, rate %f...\n", 501 transmit_tail_timestamp, rate); 502 503 for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin(); 504 it != m_TransmitProcessors.end(); 505 ++it ) { 506 (*it)->setBufferTailTimestamp(transmit_tail_timestamp); 507 (*it)->setTicksPerFrame(rate); 508 } 509 510 // align the received streams to be phase aligned 459 511 if(!alignReceivedStreams()) { 460 512 debugError("Could not align streams...\n"); … … 506 558 } 507 559 508 // we now set the buffer tail timestamp of the transmit buffer509 // to the period transfer time instant plus what's nb_buffers - 1510 // in ticks. This due to the fact that we (should) have received one period511 // worth of ticks at t=m_time_of_transfer512 // hence one period of frames should also have been transmitted, which means513 // that there should be (nb_buffers - 1) * periodsize of frames in the xmit buffer514 // that allows us to calculate the tail timestamp for the buffer.515 float rate = m_SyncSource->getTicksPerFrame();516 int64_t delay_in_ticks=(int64_t)(((float)((m_nb_buffers-1) * m_period)) * rate);517 int64_t transmit_tail_timestamp = addTicks(m_time_of_transfer, delay_in_ticks);518 519 for ( StreamProcessorVectorIterator it = m_TransmitProcessors.begin();520 it != m_TransmitProcessors.end();521 ++it ) {522 // m_time_of_transfer is set by waitForPeriod()523 (*it)->setBufferTailTimestamp(transmit_tail_timestamp);524 }525 526 560 if(!transferSilence()) { 527 561 debugError("Could not transfer silence\n"); … … 840 874 static uint64_t m_time_of_transfer2 = m_time_of_transfer; 841 875 842 int ticks_per_period = m_SyncSource->getTicksPerFrame() * m_period;876 int ticks_per_period = (int)(m_SyncSource->getTicksPerFrame() * m_period); 843 877 int diff=diffTicks(m_time_of_transfer, m_time_of_transfer2); 844 878 // display message if the difference between two successive tick … … 961 995 // 1394 time 962 996 float rate = m_SyncSource->getTicksPerFrame(); 963 int64_t one_ringbuffer_in_ticks=(int64_t)(((float)( m_nb_buffers * m_period)) * rate);997 int64_t one_ringbuffer_in_ticks=(int64_t)(((float)((m_nb_buffers * m_period))) * rate); 964 998 965 999 // the data we are putting into the buffer is intended to be transmitted … … 991 1025 */ 992 1026 bool StreamProcessorManager::transferSilence() { 993 debugOutput( 1027 debugOutput(DEBUG_LEVEL_VERY_VERBOSE, "Transferring silent period...\n"); 994 1028 bool retval=true; 995 1029 retval &= transferSilence(StreamProcessor::ePT_Receive); trunk/libffado/src/libutil/TimestampedBuffer.cpp
r918 r1001 147 147 148 148 /** 149 * \brief presets the effective rate 150 * 151 * Presets the DLL such that the effective rate is as given 152 * @param rate rate (in timeunits/frame) 153 */ 154 void TimestampedBuffer::setRate(float rate) { 155 // we take the current tail timestamp and update the head timestamp 156 // to ensure the rate is ok 157 158 ENTER_CRITICAL_SECTION; 159 160 m_dll_e2 = m_update_period * (double)rate; 161 m_buffer_next_tail_timestamp = (ffado_timestamp_t)((double)m_buffer_tail_timestamp + m_dll_e2); 162 163 EXIT_CRITICAL_SECTION; 164 165 debugOutputExtreme(DEBUG_LEVEL_VERY_VERBOSE, 166 "for (%p) to "TIMESTAMP_FORMAT_SPEC" => "TIMESTAMP_FORMAT_SPEC", " 167 "NTS="TIMESTAMP_FORMAT_SPEC", DLL2=%f, RATE=%f\n", 168 this, new_timestamp, ts, m_buffer_next_tail_timestamp, m_dll_e2, getRate()); 169 } 170 171 /** 149 172 * \brief calculate the effective rate 150 173 * trunk/libffado/src/libutil/TimestampedBuffer.h
r907 r1001 139 139 float getNominalRate() {return m_nominal_rate;}; 140 140 float getRate(); 141 void setRate(float rate); 141 142 142 143 bool setUpdatePeriod ( unsigned int t );