-- | Discontinous content. Some media streams, like e.g. RTP streams received -- via UDP, have the characteristic, that some times packages are lost. This -- module provides a type that is isomorphic to 'Maybe' to indicate that the -- content for a media frame is missing. -- It might take some effort to detect missing content, like a jitter buffer, or the comparison of sequence numbers. -- -- TODO: Create a gap detection mechanism, a simple stateful monad that knows the next timestamp etc. module Data.MediaBus.Media.Discontinous ( Discontinous(..) , _Missing , _Got ) where import Control.Lens import Control.Parallel.Strategies (NFData) import Data.Default import Data.MediaBus.Media.Media import Data.MediaBus.Media.Channels import Data.MediaBus.Media.Samples import Data.MediaBus.Basics.Ticks import GHC.Generics (Generic) -- | Content that can be 'Missing'. data Discontinous a = Missing -- ^ A place holder for frame content that is missing | Got !a -- ^ Available content deriving (Show, Generic) instance NFData a => NFData (Discontinous a) instance Default (Discontinous a) where def = Missing makePrisms ''Discontinous instance (HasDuration a) => HasDuration (Discontinous a) where getDuration Missing = 0 getDuration (Got !x) = getDuration x instance EachMedia a b => EachMedia (Discontinous a) (Discontinous b) where type MediaFromE (Discontinous a) = MediaFromE a type MediaToE (Discontinous b) = MediaToE b eachMedia = _Got . eachMedia instance EachSample a b => EachSample (Discontinous a) (Discontinous b) where type SamplesFrom (Discontinous a) = SamplesFrom a type SamplesTo (Discontinous b) = SamplesTo b eachSample = _Got . eachSample instance EachChannel a b => EachChannel (Discontinous a) (Discontinous b) where type ChannelsFrom (Discontinous a) = ChannelsFrom a type ChannelsTo (Discontinous b) = ChannelsTo b eachChannel = _Got . eachChannel instance (HasRate c) => HasRate (Discontinous c) where type GetRate (Discontinous c) = GetRate c type SetRate (Discontinous c) r' = Discontinous (SetRate c r') instance ( HasRate i , GetRate i ~ ri , SetRate i rj ~ j , KnownRate rj , CoerceRate i j ri rj ) => CoerceRate (Discontinous i) (Discontinous j) ri rj where coerceRate px = over _Got (coerceRate px)