def isControlTimestampChanged(prev, latest):
    """\
    Checks whether a new (latest) Control Timestamp is different when compared to a old (previous) Control Timestamp.
    
    Note that this does not check equivalency (if two Control Timestamps represent the same mapping between Wall clock time and content time)
    but instead checks if the property values comprising the two timestamps are exact matches.
    
    :param prev: :class:`None` or a previous :class:`~dvbcss.protocol.ts.ControlTimestamp` 
    :param latest: A new  :class:`~dvbcss.protocol.ts.ControlTimestamp` 
    
    :returns: True if the previous Control Timestamp is supplied is None, or if any of its properties differ in value to that of the latest Control Timestamp
    
    :throws ValueError: The new Control Timestamp supplied is None instead of a Control Timetamp
    """
    
    # sanity check
    if latest is None:
        raise ValueError("Latest control timestamp cannot be None")

    # if we don't have a previous CT yet, then we always take the latest
    if prev is None:
        return True
    
    # check if timeline remains unavailable, then irrespective of wallClockTime, it is unchanged
    if (prev.timestamp.contentTime is None) and (latest.timestamp.contentTime is None):
        return False
    
    # if values have changed, then it has changed
    if prev.timestamp.contentTime != latest.timestamp.contentTime:
        return True
    if prev.timestamp.wallClockTime != latest.timestamp.wallClockTime:
        return True
    if prev.timelineSpeedMultiplier != latest.timelineSpeedMultiplier:
        return True
    return False