IterateFrameFilter ( & SyNewRateControl::InitIterateFrameFilter), mTimeCodeAnchor (kInvalidAESTime) // Set the minimum filter depths and sync lock delays thls- > UpdateForwardFilterLength(mlnForwardFllterLength); this- > UpdateReverseFilterLength(minReverseFilterLength); this- > UpdateForwardSyncLockDelay(forwardSyncLockDelay) his- > UpdateReverseSyncLockDelay (reverseSyncLockDelay); // Initialize the critical section ::SynInitializeCriticalSelection ( & mTransportCS) // Set system timer resolution for SyTimeGetTime() UInt 32 maxResolution; ::SyTimeGetDevCaps( & mTimerResolution, & maxResolution); ::SyTlmeBeginPeriod(mTimerResolution); // Add pipe empty semaphore to the base SyTask wait list and start the task this- > AddObject (((SySemaphoreSemaphore*)mFilterPipe. EmptySemphore ()) > GetHandle()); this- > Start(); //#define~DEBUG~BCD #ifdef~DEBUG~BCD extern UInt32 gBCDSize; extern UInt32 gBCDCount; extern UInt8 gBCD[ ] [4]; extern TimeCode gTimeCode[ Int32 gTimeStamp [1000]; #endif SyNewRateControl::-SyNewRateControl (void) // Shut down the transport control task this - > Kill(); #ifdef DEBUG BCD for (UInt32 i = gBCDCount; i SYRELTRACE(~T("%C%C:%C%C:%C%C:%C%C %164d"), (gBCD[i] [3] 4 & DxF) + ~T('O'), (gBCD[i] [3] & 0xF) + T('O'), (gBCD[i] [2] > 4 & DxF) + (gBCD[i] [2] & 0xF) + T('O'), (gBCD[i] [1] > > 4 & 0xF) + T('O'), (gBCD[1] [1] & 0xF) + ~T('O'), (gBCD[i] (gBCD[i] [0] & 0xF) + ~T('O'), gTimeCode[i]); SYRELTRACE(~T(" %ld\n"), gTimeStamp[i]); for (i = 0; i SYRELTRACE(~T("%C%C:%C%C:%C%C:%C%C %I64d"), (gBCD[i] [3] > > 4 & 0xF) + ~T('O'), (gBCD[i] [3] & 0xF) + ~T('O'), (gBCD[i] [2] > 4 & 0xF) + -T('O'), (gBCD[i] [2] & 0xF) + (gBCD[i] [1] > > 4 & 0xF) + ~T('O'), (gBCD[i] [1] & 0xF) + (gBCD[1] [0] > > 4 & 0xF) + ~T('O'), (gBCD[1] [0] & 0xF) + ~T('O'), gTimeCode[1]; SYRELTRACE(~T(" %ld\n"), gTimeStamp[1]); ) #endif // Undo timer resolution setting SyTimeEndPeriod(mTimerResolution); // Delete the critical section ::SyDeleterCriticalSection( & mTransportCS); // Free up the filter arrays delete [ ] mFilterRate; delete [ ] mFilterArray; UInt32 SyNewRateControl::CalculateRate (void) { // // call functions which perform the first stage (sample the time code) and second stage // (filter the time code) of rate processing, as well as send decimated data to the third stage return (this- > *IterateFrameFilter) (this- > GetFrameNumber ()); UInt32 SyNewRateControl::Iterate(Intl6) // Local variables for the third and fourth stages of the filter SyFilterPipeItem filterPoint; IEEE32 currentRate; IEEE32 newRate; TimeCode position; TimeStamp rateTimeStamp; TimeStamp commandTimeStamp; // Release the empty semaphore because we waited on it in order to Iterate (), thereby artificially decrementing it mFilterPipe.EmptySemaphore() - > Increment(): // Get the decimated data from the second stage and call functions to perform the third stage // (track the time code) and fourth stage (control transport rate and cueing) of rate processing mFilterPipe.GetItem(filterPoint); this- > TrackFrames(filterPoint, currentRate, newRate, position, rateTimeStamp, commandTimeStamp); this- > ControlTransport(filterPoint, currentRate, newRate, position, rateTimeStamp, commandTimeStamp); return 0; SyFilterPoint SyNewRateControl: :GetFrameNumber (void) // // Construct a filter point by reading the reference time, reading the time code, reading the // reference time again and averaging the two reference times SyFilterPoint filterPoint; filterPoint.mSample = this- > ExtendTimeStampXthis- > GetReferenceTime()); #ifdef ~TRACE~CAPTURE~TIME SYRELTRACE(~T("GFN: timeOffsetBefore = %ld\n"), ::SyTimeGetTime() (mLastIterateTime + kFrameSamplePeriod)); endif filterPoint .mFrame = this- > CurrentFrameNumber(); if (filterPoint.mSample ! = kInvalidAESTime) { #ifdef ~TRACE~CAPTURE~TIME SYRELTRACE(~T("GFN: timeOffsetAfter = %ld\n"), ::SyTimeGetTime() (mLastIterateTime + kFrameSamplePeriod)); endif if (kCaptureTimeVaries) TimeStamp timeStamp = this- > GetReferenceTime() if (timeStamp ! = kInvalidAESTime) filterPoint m.Sample += this- > ExtendTimeStamp(timeStamp); filterPoint.mSample =1; filterPoint.mSample -= this- > GetTimeStampleDelay() - kCaptureDelay; #ifdef ~DEBUG~BCD static TimeStamp last - kInvalidAESTime; if (last ! = kInvalidAESTime) gTimeStamp[gBCDCount++] = filterPoint.mSample - laster; if (gBCDCount = = gBCDSize( { /* for (UInt32 i = 0; 0#i SYRELTRACE(~T("%C%C:%C%C:%C%C:%C%C %I64d"), (gBCD[i] [3] > > 4 & 0xF) + T('O'), (gBCD[1] [3] & 0xF) + ~T('O'), (gBCD[i] [2] > > 4 & 0xF) + ~T('O'), (gBCD[i] [2] & 0xF) + ~T('O'), (gBCD[i] [1] > > 4 4 & 0xF) + (gBCD[i] [1] & 0xF) + ~T('O'), (gBCD[1] [0] > > 4 & 0xF) + ~T('O'), (gBCD[i] [0] & 0xF) + ~T('O'), gTimeCode[1]); SYRELTRACE(~T(" %ld\n"), gTimeStamp[i]); gBCDCount = 0; //::DebugBreak(); last = filterPoint.mSample; endif return filterpoint; UInt32 SyNewRateControl::InitInterateFrameFilter(const SyFilterPoint & filterPoint) // Check for valid reference time if (filterPoint.mSample = = kInvalidAESTime) return kFrameSamplePeriod; // Initialize filter variables mLastIterateTime = ::SyTimeGetTime() - kFrameSamplePeriod; mSamplePeriods = 0; mFilterDepthLimit = 1 mPass = 0; mCurrentPosition = 0; mFilterArray [mCurrentPostition].mFrame = 0; mFilterArray [mCurrentPostition].mSample = 0; mFilterArray [mCurrentPostition + (1 for (mCurrentPosition++; mCurrentPosition mCurrentPosition++) mFilterArray[mCurrentPosition] .mFrame mFilterArray[mCurrentPosition - 1].mFrame + filterPoint.mFrame; mFilterArray[mCurrentPosition] .mSample mFilterArray[mCurrentPosition - 1].mSample + filterPolnt.mSample - kFrameSamplePeriod kSamplePerMillisecond * ((1 mCurrentPosition); mFilterArray[mCurrentPosition + (1 kMaxFilterDepth)] = mFilterArray[mCurrentPosition]; // Initialize output stage variables here, also, so the timestamps will at least have reasonable values mCueTimeStamp = mLastActualRateTimeStamp = this - > GetReferenceTime(); mLastActualRate = 0.0; mLastActualLock = FALSE; mActualPosition = mCuePosition = this - > TransportTime(); //SYTRACE(~T("MAP set to %f\n"), (float) mActualPosition); mUnityRateTimer = 0; mCueHint = CUEHINT~BIDIRECTIONAL; // Pass control for this and all future iterations to DoIterateFrame Filter() this- > IterateFrameFilter = sSyNewRateControl: :DolterateFrameFilter; return this- > DoIterateFrameFilter(filterPoint); UInt32 SyNewRateControl::DoIterateFrameFilter(const SyFilterPoint & filterPoint) // Check for valid reference time if (filterPoint.mSample = = kInvalidAESTime) this- > IterateFrameFilter = & SyNewRateControl::InitIterateFrameFilter; return kFrameSamplePeriod; // See how much time there is before the next iteration, and see if we've missed any iterations UInt32 time = ::SyTimeGetTime(); UInt32 newSamplePeriods = (time + (kFrameSamplePeriod > > 1) mLastIterateTime)/ / kFrameSamplePerlod; if (kExternalFrameSampleClock) If (newSamplePeriods > 0) mLastIterateTime = time; else mLastIterateTime += newSamplePeriods + kFrameSamplePeriod; Int32 waitTime = mLastIterateTime + kFrameSamplePeriod - time; *ifdef TRACE ITERATE TIME SYRELTRACE(~T("DIFF: timeErr = %ld\n"), time - (mLastIterateTime + kFrameSamplePeriod)); *endif mSamplePeriods += newSamplePeriods; // If the last iteration was too short or too long, don't use the current filter point #ifdef DEBUG static UInt32 total; static UIntl6 nimber; static UIntl6 period; if (newSamplePeriods > 1) total += newsamplePeriods; number++; if (period = = 0) { if (number = = 1) SYRELTRACE ~T else SYRELTRACE(~T("SyNewRateControl::IterateFrameFilter: total of id newSamplePeriods = %ld\n"), number, total); total = 0; number = 0; period++; if (period ! = 0 & & period++ = = 100) period = 0; If (number ! = 0) If (number = = 1) SYRELTRACE(~T("SyNewRateControl::IterateFrameFilter: newSamplePeriods = %ld\n"), total); else SYRELTRACE(~T("SyNewRateControl::IterateFrameFllter: ~ total of %d newSamplePeriods = %ld\n"), number, total); total = 0; number = 0; endif if (mSamplePeriods = = 0 || (kThrowAwayLateFilterPoints & & newSamplePeriods > 1)) return waitTime; // Put the new filter point into the frame filter (and construct fake filter points if we missed iterations) SyFilterPoint lastPoint = mFilterArray[m.CurrentPosition - 1] mFilterArray[mCurrentPosition - 2]; for (Int32 i = 1; i // This loop should only execute if a previous iteration of getting the frame sample period // took too long.