示例#1
0
    def test_noCommonAncestor(self):
        a = self.newSysClock()
        b = self.newSysClock()
        a1 = CorrelatedClock(a, tickRate=1000, correlation=Correlation(0, 0))
        b1 = CorrelatedClock(b, tickRate=1000, correlation=Correlation(0, 0))
        a2 = CorrelatedClock(a1, tickRate=1000, correlation=Correlation(0, 0))
        b2 = CorrelatedClock(b1, tickRate=1000, correlation=Correlation(0, 0))

        self.assertRaises(NoCommonClock, lambda: a.toOtherClockTicks(b, 5))
        self.assertRaises(NoCommonClock, lambda: a.toOtherClockTicks(b1, 5))
        self.assertRaises(NoCommonClock, lambda: a.toOtherClockTicks(b2, 5))

        self.assertRaises(NoCommonClock, lambda: a1.toOtherClockTicks(b, 5))
        self.assertRaises(NoCommonClock, lambda: a1.toOtherClockTicks(b1, 5))
        self.assertRaises(NoCommonClock, lambda: a1.toOtherClockTicks(b2, 5))

        self.assertRaises(NoCommonClock, lambda: a2.toOtherClockTicks(b, 5))
        self.assertRaises(NoCommonClock, lambda: a2.toOtherClockTicks(b1, 5))
        self.assertRaises(NoCommonClock, lambda: a2.toOtherClockTicks(b2, 5))

        self.assertRaises(NoCommonClock, lambda: b.toOtherClockTicks(a, 5))
        self.assertRaises(NoCommonClock, lambda: b.toOtherClockTicks(a1, 5))
        self.assertRaises(NoCommonClock, lambda: b.toOtherClockTicks(a2, 5))

        self.assertRaises(NoCommonClock, lambda: b1.toOtherClockTicks(a, 5))
        self.assertRaises(NoCommonClock, lambda: b1.toOtherClockTicks(a1, 5))
        self.assertRaises(NoCommonClock, lambda: b1.toOtherClockTicks(a2, 5))

        self.assertRaises(NoCommonClock, lambda: b2.toOtherClockTicks(a, 5))
        self.assertRaises(NoCommonClock, lambda: b2.toOtherClockTicks(a1, 5))
        self.assertRaises(NoCommonClock, lambda: b2.toOtherClockTicks(a2, 5))
示例#2
0
    def test_quantifyChange(self):
        a = self.newSysClock()
        b = CorrelatedClock(a, 1000, correlation=Correlation(0, 0))

        self.assertEquals(float('inf'),
                          b.quantifyChange(Correlation(0, 0), 1.01))
        self.assertEquals(1.0, b.quantifyChange(Correlation(0, 1000), 1.0))

        b.speed = 0.0
        self.assertEquals(0.005, b.quantifyChange(Correlation(0, 5), 0.0))
示例#3
0
 def test_distantParentMidHierarchy(self):
     a = self.newSysClock(tickRate=1000000)
     a1 = CorrelatedClock(a, tickRate=100, correlation=Correlation(50, 0))
     a2 = CorrelatedClock(a1, tickRate=78, correlation=Correlation(28, 999))
     a3 = CorrelatedClock(a2,
                          tickRate=178,
                          correlation=Correlation(5, 1003))
     a4 = CorrelatedClock(a3, tickRate=28, correlation=Correlation(17, 9))
     self.assertEquals(a3.toOtherClockTicks(a1, 500),
                       a2.toParentTicks(a3.toParentTicks(500)))
示例#4
0
    def test_setCorrelationAndSpeed(self):
        a = self.newSysClock(tickRate=1000000)
        b = CorrelatedClock(a, 1000, correlation=Correlation(0, 0))
        b.speed = 1.0

        db = MockDependent()
        b.bind(db)

        b.setCorrelationAndSpeed(Correlation(5, 0), 2)
        db.assertNotificationsEqual([b])
        self.assertEqual(b.toParentTicks(10), 5005)
示例#5
0
    def test_setParent(self):
        a = self.newSysClock(tickRate=1000)
        b = CorrelatedClock(a, 1000, correlation=Correlation(0, 0))
        c = CorrelatedClock(a, 1000, correlation=Correlation(10, 0))
        d = MockDependent()
        b.bind(d)

        d.assertNotNotified()
        b.setParent(c)
        d.assertNotificationsEqual([b])
        self.assertEquals(b.getParent(), c)
示例#6
0
    def test_setParentNoChangeNoNotify(self):
        a = self.newSysClock(tickRate=1000)
        b = CorrelatedClock(a, 1000, correlation=Correlation(0, 0))
        c = CorrelatedClock(a, 1000, correlation=Correlation(10, 0))
        d = MockDependent()
        b.bind(d)

        d.assertNotNotified()
        b.setParent(a)
        d.assertNotNotified()
        self.assertEquals(b.getParent(), a)
示例#7
0
    def test_changeCorrelation(self):
        mockTime = self.mockTime

        b = self.newSysClock()
        mockTime.timeNow = 5020.8
        c = CorrelatedClock(b, 1000, correlation=Correlation(0, 300))
        self.assertAlmostEqual(c.ticks, 5020.8 * 1000 + 300, places=5)

        c.correlation = Correlation(50000, 320)
        self.assertEqual(c.correlation, Correlation(50000, 320))
        self.assertAlmostEqual(c.ticks,
                               (int(5020.8 * 1000000) - 50000) / 1000 + 320,
                               places=5)
示例#8
0
    def test_fromParentTicks(self):
        mockTime = self.mockTime

        b = self.newSysClock(tickRate=2000000)

        mockTime.timeNow = 1000.0

        c = CorrelatedClock(b, 1000, correlation=Correlation(50, 300))
        self.assertAlmostEqual(c.fromParentTicks(50 + (400 - 300) * 2000),
                               400,
                               places=5)

        c = CorrelatedClock(b, 1000, correlation=Correlation(50, 300), speed=0)
        self.assertEquals(c.fromParentTicks(50), 300)
        self.assertEquals(c.fromParentTicks(100), 300)
示例#9
0
    def test_toParentTicks(self):
        mockTime = self.mockTime

        b = self.newSysClock(tickRate=2000000)

        mockTime.timeNow = 1000.0

        c = CorrelatedClock(b, 1000, correlation=Correlation(50, 300))
        self.assertAlmostEqual(c.toParentTicks(400),
                               50 + (400 - 300) * 2000,
                               places=5)

        c = CorrelatedClock(b, 1000, correlation=Correlation(50, 300), speed=0)
        self.assertEquals(c.toParentTicks(300), 50)
        self.assertTrue(math.isnan(c.toParentTicks(400)))
示例#10
0
 def __init__(self, clock):
     """\
     :param clock: The :class:`~dvbcss.clock.CorrelatedClock` that is to be set.
     
     Note that this predictor does not actually set the clock. It just needs it in order to calculate the correct correlation for it.
     """
     self.clock = clock
     self.correlation = Correlation(0, 0, 0, float("+inf"))
示例#11
0
 def threadrun():
     # separate thread in which we'll use sleepUntil on a clock that uses tClock as its parent
     cClock = CorrelatedClock(tClock,
                              tickRate=10,
                              correlation=Correlation(tClock.ticks, 0))
     for i in range(0, 10):
         sleepUntil(cClock, i * 10)
         print "Tick", cClock.ticks
示例#12
0
    def test_changeCorrelationNotifies(self):
        """Check a change to the correlation propagates notifications to dependents of this clock"""
        b = self.newSysClock()
        c = CorrelatedClock(b, 1000, correlation=Correlation(0, 300))
        cc = CorrelatedClock(c, 50)

        d1 = MockDependent()
        d2 = MockDependent()
        d3 = MockDependent()

        b.bind(d1)
        c.bind(d2)
        cc.bind(d3)

        c.correlation = Correlation(50, 20)

        d1.assertNotNotified()
        d2.assertNotificationsEqual([c])
        d3.assertNotificationsEqual([cc])
示例#13
0
    def test_rangeConversion(self):
        mockTime = self.mockTime

        b = self.newSysClock(tickRate=1000)

        mockTime.timeNow = 0.0
        c = RangeCorrelatedClock(b,
                                 1000,
                                 correlation1=Correlation(100, 1000),
                                 correlation2=Correlation(200, 1110))

        mockTime.timeNow = b.calcWhen(100)
        self.assertEqual(c.ticks, 1000)

        mockTime.timeNow = b.calcWhen(200)
        self.assertEqual(c.ticks, 1110)

        mockTime.timeNow = b.calcWhen(150)
        self.assertEqual(c.ticks, 1055)
示例#14
0
    def test_ticking(self):
        mockTime = self.mockTime

        b = self.newSysClock()

        mockTime.timeNow = 5020.8

        c = CorrelatedClock(b, 1000, correlation=Correlation(0, 300))
        self.assertAlmostEqual(c.ticks, 5020.8 * 1000 + 300, places=5)

        mockTime.timeNow += 22.7
        self.assertAlmostEqual(c.ticks, (5020.8 + 22.7) * 1000 + 300, places=5)
示例#15
0
文件: wc.py 项目: bbc/pydvbcss
    def calcCorrelationFor(self, clock, localMaxFreqErrorPpm=None):
        r"""\
        Calculates and returns the :class:`~dvbcss.clock.Correlation` for a
        :class:`~dvbcss.clock.CorrelatedClock` that is equivalent to this candidate.
        
        The returned correlation can then be applied to the clock to model the time
        at the server. This includes the error bounds information needed to
        enable the clock to correctly calculate dispersion.

        :param clock: :class:`~dvbcss.clock.CorrelatedClock` that will model the server clock. Its parent must be the one that was measured for `t1` and `t4` this candidate.
        :param localMaxFreqErrorPpm: Optional. By defeault the :func:`~dvbcss.clock.ClockBase.getRootMaxFreqError` of the `clock` is used. Provide this value to override that.
        
        :returns: :class:`~dvbcss.clock.Correlation` representing this `candidate`, and that can be used with the :class:`~dvbcss.clock.CorrelatedClock`.
        
        .. note::
            The parameters of the correlation are calculated by this function
            as follows:
            
            * **parentTicks** = (t1' + t4') / 2
            * **childTicks** = (t2' + t3') / 2
            * **initialError** = precision + ( rtt/2 + mfeC * (t4 - t1) + mfeS * (t3 - t2) ) / 10\ :sup:`9`
            * **errorGrowthRate** = mfeC + mfeS
            
            Where:
            
            * **t1**, **t2**, **t3** and **t4** are in units of nanoseconds
            * **t1'** and **t4'** are the same as t1 and t4 but converted to ticks of the parent of the specified clock
            * **t2'** and **t3'** are the same as t2 and t3 but converted to ticks of the specified clock
            * **mfeC** is the clock's :func:`~dvbcss.clock.ClockBase.getRootMaxFreqError`, converted from ppm to a fraction by dividing by 10\ :sup:`6`
            * **mfeS** is the max freq error reported by the server, converted from ppm to a fraction by dividing by 10\ :sup:`6`
        
        .. versionadded:: 0.4
        """
        # convert to units of the clock
        t1 = clock.getParent().nanosToTicks(self.t1)
        t4 = clock.getParent().nanosToTicks(self.t4)
        t2 = clock.nanosToTicks(self.t2)
        t3 = clock.nanosToTicks(self.t3)

        if localMaxFreqErrorPpm is None:
            localMaxFreqErrorPpm = clock.getRootMaxFreqError()

        mfeC = localMaxFreqErrorPpm / 1000000.0  # ppm to fraction
        mfeS = self.maxFreqError / 1000000.0  # ppm to fraction

        return Correlation(
            parentTicks=(t1 + t4) / 2.0,
            childTicks=(t2 + t3) / 2.0,
            initialError=self.precision
            +  # server precision. does not include local clock precision since this is already accounted for
            (self.rtt / 2.0 + mfeC * (self.t4 - self.t1) + mfeS *
             (self.t3 - self.t2)) / 1000000000.0,  # nanos to seconds
            errorGrowthRate=(mfeC + mfeS))
示例#16
0
 def test_dispersionCalcForError(self):
     """With non-zero error contribution, the dispersion at different times is additional to that of the parent clock, both before and after the correlation time"""
     a = self.newSysClock(tickRate=1000)
     b = CorrelatedClock(a, 1000, correlation=Correlation(0, 0, 0.5, 0.1))
     self.assertEquals(
         a.dispersionAtTime(10) + 0.5 + 0.1 * 10 / 1000,
         b.dispersionAtTime(10))
     self.assertEquals(
         a.dispersionAtTime(20) + 0.5 + 0.1 * 20 / 1000,
         b.dispersionAtTime(20))
     self.assertEquals(
         a.dispersionAtTime(-10) + 0.5 + 0.1 * 10 / 1000,
         b.dispersionAtTime(-10))
示例#17
0
 def test_tupleEquivEquality(self):
     """Correlations can be compared with 2-tuples for equality of the parentTicks and childTicks"""
     self.assertEqual(Correlation(1, 2, 3, 4), (1, 2))
     self.assertEqual((1, 2), Correlation(1, 2, 3, 4))
     self.assertNotEqual(Correlation(9, 2, 3, 4), (1, 2))
     self.assertNotEqual(Correlation(1, 9, 3, 4), (1, 2))
     self.assertNotEqual((1, 2), Correlation(9, 2, 3, 4))
     self.assertNotEqual((1, 2), Correlation(1, 9, 3, 4))
示例#18
0
    def test_withTuples(self):
        mockTime = self.mockTime

        b = self.newSysClock(tickRate=1000)

        mockTime.timeNow = 0.0
        c = RangeCorrelatedClock(b,
                                 1000,
                                 correlation1=(100, 1000),
                                 correlation2=(200, 1110))
        self.assertEqual(Correlation(100, 1000), c.correlation1)
        self.assertEqual(Correlation(200, 1110), c.correlation2)

        mockTime.timeNow = b.calcWhen(100)
        self.assertEqual(c.ticks, 1000)

        mockTime.timeNow = b.calcWhen(200)
        self.assertEqual(c.ticks, 1110)

        c.correlation1 = (100, 2000)
        c.correlation2 = (200, 2110)
        self.assertEqual(Correlation(100, 2000), c.correlation1)
        self.assertEqual(Correlation(200, 2110), c.correlation2)
        self.assertEqual(c.ticks, 2110)
示例#19
0
    def test_clockDiff(self):
        a = self.newSysClock()
        self.mockTime.timeNow = 1
        b = CorrelatedClock(a, 1000, correlation=Correlation(0, 0))
        c = CorrelatedClock(b, 2000, correlation=Correlation(0, 0))
        d = CorrelatedClock(c, 3000, correlation=Correlation(0, 0))
        e = RangeCorrelatedClock(d, 1000, Correlation(5, 0),
                                 Correlation(15005, 5000))

        self.assertEquals(float('inf'), b.clockDiff(c))
        self.assertEquals(float('inf'), b.clockDiff(d))
        self.assertAlmostEquals(0.001666667, b.clockDiff(e), delta=0.000001)

        self.mockTime.timeNow += 10000000

        self.assertEquals(float('inf'), b.clockDiff(c))
        self.assertEquals(float('inf'), b.clockDiff(d))
        self.assertAlmostEquals(0.001666667, b.clockDiff(e), delta=0.000001)

        c.tickRate = 1000
        self.assertEquals(0, b.clockDiff(c))

        c.speed = 1.01
        self.assertEquals(float('inf'), b.clockDiff(c))
示例#20
0
    def test_speedChangePropagates(self):
        mockTime = self.mockTime

        a = self.newSysClock(tickRate=1000)

        mockTime.timeNow = 5

        a1 = CorrelatedClock(a, tickRate=1000, correlation=Correlation(50, 0))
        a2 = CorrelatedClock(a1,
                             tickRate=100,
                             correlation=Correlation(28, 999))
        a3 = CorrelatedClock(a2, tickRate=50, correlation=Correlation(5, 1003))
        a4 = CorrelatedClock(a3, tickRate=25, correlation=Correlation(1000, 9))
        b3 = CorrelatedClock(a2,
                             tickRate=1000,
                             correlation=Correlation(500, 20))
        b4 = CorrelatedClock(b3,
                             tickRate=2000,
                             correlation=Correlation(15, 90))

        at1, a1t1, a2t1, a3t1, a4t1, b3t1, b4t1 = [
            x.ticks for x in [a, a1, a2, a3, a4, b3, b4]
        ]
        a3.speed = 0.5
        a4.speed = 0.2
        self.assertEquals(1.0, a.getEffectiveSpeed())
        self.assertEquals(1.0, a1.getEffectiveSpeed())
        self.assertEquals(1.0, a2.getEffectiveSpeed())
        self.assertEquals(0.5, a3.getEffectiveSpeed())
        self.assertEquals(0.1, a4.getEffectiveSpeed())

        a3.speed = 0
        a4.speed = 1.0
        self.assertEquals(1.0, a.getEffectiveSpeed())
        self.assertEquals(1.0, a1.getEffectiveSpeed())
        self.assertEquals(1.0, a2.getEffectiveSpeed())
        self.assertEquals(0.0, a3.getEffectiveSpeed())
        self.assertEquals(0.0, a4.getEffectiveSpeed())

        mockTime.timeNow = 6  # advance time 1 second

        at2, a1t2, a2t2, a3t2, a4t2, b3t2, b4t2 = [
            x.ticks for x in [a, a1, a2, a3, a4, b3, b4]
        ]

        self.assertEquals(at2, at1 + 1000)  # a  still advances
        self.assertEquals(a1t2, a1t1 + 1000)  # a1 still advances
        self.assertEquals(a2t2, a2t1 + 100)  # a2 still advances
        self.assertEquals(
            a3t2, 1003)  # a3 is speed zero, is now at the correlation point
        self.assertEquals(
            a4t2, 10.5
        )  # a4 is speed zero, a3.ticks is 3 ticks from correlation point for a4, translating to 1.5 ticks from a4 correlation point at its tickRate
        self.assertEquals(b3t2, b3t1 + 1000)  # b3 still advances
        self.assertEquals(b4t2, b4t1 + 2000)  # b4 is paused
示例#21
0
    def test_changeFreq(self):
        mockTime = self.mockTime

        b = self.newSysClock()

        mockTime.timeNow = 5020.8

        c = CorrelatedClock(b, 1000, correlation=Correlation(50, 300))
        self.assertAlmostEqual(c.ticks, (5020.8 * 1000000 - 50) /
                               (1000000 / 1000) + 300,
                               places=5)

        self.assertEqual(c.tickRate, 1000)
        c.tickRate = 500
        self.assertEqual(c.tickRate, 500)
        self.assertAlmostEqual(c.ticks,
                               (5020.8 * 1000000 - 50) / (1000000 / 500) + 300,
                               places=5)
示例#22
0
文件: ts.py 项目: bbc/pydvbcss
    def _onControlTimestamp(self, ct):
        self.latestCt = ct
        self.log.debug("New Control Timestamp: "+str(ct))

        available = ct.timestamp.contentTime is not None
        availChanged = bool(available) != bool(self.timelineClock.isAvailable())
        
        # only extract new corelation and and compare to existing clock 
        # if the control timestamp indicates that the timeline is actually available
        
        if available:
            speed = float(ct.timelineSpeedMultiplier)
            corr = Correlation(ct.timestamp.wallClockTime, ct.timestamp.contentTime)
            corrSpeedChanged = self.timelineClock.isChangeSignificant(corr, speed, self._changeThreshold)
            speedChanged = self.timelineClock.speed != speed
        else:
            corrSpeedChanged = False

        # update correlation and speed, then update availability, to
        # ensure a correlation is not changed immediately *after* the clock
        # becomes available. Better it happens before, so downstream processing
        # can ignore while unavailable.

        if corrSpeedChanged:
            self.timelineClock.setCorrelationAndSpeed(corr, speed)
        
        if availChanged:
            self.timelineClock.setAvailability(available)

        # notification calls
        if available and corrSpeedChanged:
            self.log.debug("Speed has changed and/or correlation has changed by more than threshold amount")
            self.onTimingChange(speedChanged=speedChanged)

        if availChanged:
            if available:
                self.log.debug("Timeline has become available.")
                self.onTimelineAvailable()
            else:
                self.log.debug("Timeline has become unavailable.")
                self.onTimelineUnavailable()
示例#23
0
    def test_changeFreqNotifies(self):
        mockTime = self.mockTime

        b = self.newSysClock()

        mockTime.timeNow = 5020.8

        c = CorrelatedClock(b, 1000, correlation=Correlation(50, 300))
        cc = CorrelatedClock(c, 50)

        d1 = MockDependent()
        d2 = MockDependent()
        d3 = MockDependent()

        b.bind(d1)
        c.bind(d2)
        cc.bind(d3)

        c.tickRate = 500

        d1.assertNotNotified()
        d2.assertNotificationsEqual([c])
        d3.assertNotificationsEqual([cc])
示例#24
0
    def test_differentBranches(self):
        a = self.newSysClock(tickRate=1000000)
        a1 = CorrelatedClock(a, tickRate=100, correlation=Correlation(50, 0))
        a2 = CorrelatedClock(a1, tickRate=78, correlation=Correlation(28, 999))
        a3 = CorrelatedClock(a2,
                             tickRate=178,
                             correlation=Correlation(5, 1003))
        a4 = CorrelatedClock(a3, tickRate=28, correlation=Correlation(17, 9))
        b3 = CorrelatedClock(a2,
                             tickRate=1000,
                             correlation=Correlation(10, 20))
        b4 = CorrelatedClock(b3,
                             tickRate=2000,
                             correlation=Correlation(15, 90))

        v = a4.toParentTicks(500)
        v = a3.toParentTicks(v)
        v = b3.fromParentTicks(v)
        v = b4.fromParentTicks(v)

        self.assertEquals(a4.toOtherClockTicks(b4, 500), v)
示例#25
0
 def test_immutable(self):
     c = Correlation(1, 2, 3, 4)
     try:
         c.parentTicks = 5
         self.fail(msg="Assignment of parentTicks property")
     except:
         pass
     try:
         c.childTicks = 5
         self.fail(msg="Assignment of childTicks property")
     except:
         pass
     try:
         c.initialError = 5
         self.fail(msg="Assignment of initialError property")
     except:
         pass
     try:
         c.errorGrowthRate = 5
         self.fail(msg="Assignment of errorGrowthRate property")
     except:
         pass
示例#26
0
 def test_distantParent(self):
     a = self.newSysClock(tickRate=1000000)
     a1 = CorrelatedClock(a, tickRate=100, correlation=Correlation(50, 0))
     a2 = CorrelatedClock(a1, tickRate=78, correlation=Correlation(28, 999))
     self.assertEquals(a2.toOtherClockTicks(a, 500),
                       a1.toParentTicks(a2.toParentTicks(500)))
示例#27
0
 def test_dispersionCalcForZeroError(self):
     """With zero error contribution, the dispersion at different times is the same as for the parent clock"""
     a = self.newSysClock(tickRate=1000)
     b = CorrelatedClock(a, 1000, correlation=Correlation(0, 0))
     self.assertEquals(a.dispersionAtTime(10), b.dispersionAtTime(10))
     self.assertEquals(a.dispersionAtTime(20), b.dispersionAtTime(20))
示例#28
0
 def test_correlationAndFreqPropertiesInitialised(self):
     b = self.newSysClock()
     c = CorrelatedClock(b, 1000, correlation=Correlation(0, 300))
     self.assertEqual(c.correlation, Correlation(0, 300))
     self.assertEqual(c.tickRate, 1000)
示例#29
0
 def test_getParent(self):
     b = self.newSysClock()
     c = CorrelatedClock(b, 1000, correlation=Correlation(50, 300))
     self.assertEqual(c.getParent(), b)
示例#30
0
 def test_rebase(self):
     b = self.newSysClock(tickRate=1000)
     c = CorrelatedClock(b, 1000, correlation=Correlation(50, 300))
     c.rebaseCorrelationAtTicks(400)
     self.assertEquals(c.correlation, Correlation(150, 400))