isobmff-builder 0.10.5.0 → 0.11.2.0
raw patch · 104 files changed
+5831/−1620 lines, 104 filesdep +QuickCheckdep +criteriondep +mtldep −vector-sizeddep ~bytestringdep ~hspecdep ~type-specPVP ok
version bump matches the API change (PVP)
Dependencies added: QuickCheck, criterion, mtl, pretty-types, template-haskell, vector
Dependencies removed: vector-sized
Dependency ranges changed: bytestring, hspec, type-spec
API changes (from Hackage documentation)
- Data.ByteString.IsoBaseFileFormat.Boxes.AudioSampleEntry: audioSampleEntry :: (KnownSymbol (BoxTypeSymbol (SampleEntry AudioTrack (AudioCoding c)))) => AudioCoding c -> U16 "data_reference_index" -> SampleEntry AudioTrack (AudioCoding c) -> Box (SampleEntry AudioTrack (AudioCoding c))
- Data.ByteString.IsoBaseFileFormat.Boxes.AudioSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry.SampleEntry 'Data.ByteString.IsoBaseFileFormat.Boxes.Handler.AudioTrack (Data.ByteString.IsoBaseFileFormat.Boxes.AudioSampleEntry.AudioCoding c))
- Data.ByteString.IsoBaseFileFormat.Boxes.AudioSampleEntry: instance Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry.SampleEntry 'Data.ByteString.IsoBaseFileFormat.Boxes.Handler.AudioTrack (Data.ByteString.IsoBaseFileFormat.Boxes.AudioSampleEntry.AudioCoding c))
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: ($:) :: IsBox l => (Boxes '[Box l] -> r) -> Box l -> r
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: (:+) :: !a -> !b -> (:+) a b
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: BoxSize :: !Word64 -> BoxSize
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: BoxSizeExtension :: BoxSize -> BoxSizeExtension
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: BoxTypeExtension :: BoxType -> BoxTypeExtension
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: CustomBoxType :: !String -> BoxType
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: FourCc :: (Char, Char, Char, Char) -> FourCc
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: ListContent :: [contentType] -> ListContent sizeType contentType
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: StdType :: !FourCc -> BoxType
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: UnlimitedSize :: BoxSize
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: [:.] :: IsBox l => !(Box l) -> !(Boxes r) -> Boxes (Box l : r)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: [:<>] :: !(Boxes l) -> !(Boxes r) -> Boxes (l :++ r)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: [:|] :: (IsBox l, IsBox r) => !(Box l) -> !(Box r) -> Boxes '[Box l, Box r]
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: [Box] :: !(BoxContent b) -> Box b
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: [ContainerBox] :: IsBox b => !(BoxContent b) -> !(Boxes bs) -> ContainerBox b bs
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: [NoBoxes] :: Boxes '[]
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: boxBuilder :: IsBoxContent a => a -> Builder
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: boxSize :: IsBoxContent a => a -> BoxSize
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: class (KnownSymbol (BoxTypeSymbol t), IsBoxContent (BoxContent t)) => IsBox (t :: Type) where type BoxContent t type BoxContent t = t toBoxType _ = parseBoxType (Proxy :: Proxy (BoxTypeSymbol t)) where {
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: class IsBoxContent a
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: containerBox :: (IsBox t) => BoxContent t -> Boxes ts -> Box (ContainerBox t ts)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: data (:+) a b
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: data Box b
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: data BoxSize
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: data BoxType
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: data Boxes (boxTypes :: [Type])
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: data ContainerBox b (bs :: [Type])
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: infixr 3 $:
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance (Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent p, Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent c) => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (p Data.ByteString.IsoBaseFileFormat.Boxes.Box.:+ c)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance (Data.Default.Class.Default a, Data.Default.Class.Default b) => Data.Default.Class.Default (a Data.ByteString.IsoBaseFileFormat.Boxes.Box.:+ b)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance (GHC.Num.Num sizeType, Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent sizeType, Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent contentType) => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.Box.ListContent sizeType contentType)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox b => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox (Data.ByteString.IsoBaseFileFormat.Boxes.Box.Box b)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox b => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox (Data.ByteString.IsoBaseFileFormat.Boxes.Box.ContainerBox b bs)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox cnt => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.Box.Box cnt)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent ()
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.Box.Boxes bs)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.Box.ContainerBox b bs)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.Internal.ByteString
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.Box.BoxSize
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.Box.BoxSizeExtension
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.Box.BoxType
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.Box.BoxTypeExtension
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.Box.FourCc
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.Text.Internal.Text
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent a => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (GHC.Base.Maybe a)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Boxes.Box.BoxContent b) => Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Boxes.Box.Box b)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance Data.Default.Class.Default Data.ByteString.Internal.ByteString
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance Data.Default.Class.Default Data.Text.Internal.Text
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance Data.String.IsString Data.ByteString.IsoBaseFileFormat.Boxes.Box.FourCc
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance GHC.Classes.Eq Data.ByteString.IsoBaseFileFormat.Boxes.Box.BoxSize
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance GHC.Classes.Eq Data.ByteString.IsoBaseFileFormat.Boxes.Box.BoxType
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance GHC.Classes.Eq Data.ByteString.IsoBaseFileFormat.Boxes.Box.FourCc
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance GHC.Num.Num Data.ByteString.IsoBaseFileFormat.Boxes.Box.BoxSize
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance GHC.Show.Show Data.ByteString.IsoBaseFileFormat.Boxes.Box.BoxSize
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance GHC.Show.Show Data.ByteString.IsoBaseFileFormat.Boxes.Box.BoxType
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance GHC.Show.Show Data.ByteString.IsoBaseFileFormat.Boxes.Box.FourCc
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance forall k (sizeTupe :: k) contentType. Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Boxes.Box.ListContent sizeTupe contentType)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance forall k c (s :: k). Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent c => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.Tagged.Tagged s c)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: instance forall k c (s :: k). Data.Default.Class.Default c => Data.Default.Class.Default (Data.Tagged.Tagged s c)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: newtype BoxSizeExtension
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: newtype BoxTypeExtension
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: newtype FourCc
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: newtype ListContent sizeType contentType
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: parseBoxType :: KnownSymbol t => proxy t -> BoxType
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: singletonBox :: IsBox l => Box l -> Boxes '[Box l]
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: toBoxType :: IsBox t => proxy t -> BoxType
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: type BoxContent t = t;
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: type OM b bs = ContainerBox b bs
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: type OM_ b = Box b
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: type OO b bs = OnceOptionalX (ContainerBox b bs)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: type OO_ b = OnceOptionalX (Box b)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: type SM b bs = SomeMandatoryX (ContainerBox b bs)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: type SM_ b = SomeMandatoryX (Box b)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: type SO b bs = SomeOptionalX (ContainerBox b bs)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: type SO_ b = SomeOptionalX (Box b)
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: type family BoxContent t;
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: typeListLength :: forall a proxy (ts :: [k]). (KnownNat (Length ts), Num a) => proxy ts -> a
- Data.ByteString.IsoBaseFileFormat.Boxes.Box: }
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: Scalar :: scalartype -> Scalar scalartype
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: [Constant] :: Constant o v
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: [Custom] :: o -> Template o v
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: [FixSizeText] :: Text -> FixSizeText len label
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: [ScalarArray] :: Vector n o -> ScalarArray label n o
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: [Template] :: Template o v
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: [U32Text] :: Word32 -> U32Text label
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: [fromScalar] :: Scalar scalartype -> scalartype
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: class FromTypeLit o v
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: data Constant o v
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: data Template o v
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: fromList :: forall label n o. (KnownSymbol label, KnownNat n) => [o] -> ScalarArray label n o
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: fromTypeLit :: FromTypeLit o v => proxy o v -> o
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: i16 :: Int16 -> I16 label
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: i16Arr :: (KnownNat size, KnownSymbol label) => [Int16] -> I16Arr label size
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: i32 :: Int32 -> I32 label
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: i32Arr :: (KnownNat size, KnownSymbol label) => [Int32] -> I32Arr label size
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: i64 :: Int64 -> I64 label
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: i64Arr :: (KnownNat size, KnownSymbol label) => [Int64] -> I64Arr label size
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: i8 :: Int8 -> I8 label
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: i8Arr :: (KnownNat size, KnownSymbol label) => [Int8] -> I8Arr label size
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.U32Text label)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.IsTextSize len => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.FixSizeText len label)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.IsTextSize len => Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.FixSizeText len label)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.U32Text label)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance Data.String.IsString (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.U32Text label)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance GHC.TypeLits.KnownSymbol str => Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.FromTypeLit (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.U32Text label) str
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance GHC.TypeLits.KnownSymbol str => Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.FromTypeLit Data.Text.Internal.Text str
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall k (arr :: [GHC.Types.Nat]) o (len :: GHC.Types.Nat) (label :: k). (Data.Singletons.SingI arr, GHC.Num.Num o, Data.Singletons.SingKind [GHC.Types.Nat], GHC.TypeLits.KnownNat len, len ~ Data.Singletons.Prelude.List.Length arr) => Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.FromTypeLit (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.ScalarArray label len o) arr
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall k (label :: k) (len :: GHC.Types.Nat) o. GHC.Classes.Eq o => GHC.Classes.Eq (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.ScalarArray label len o)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall k (label :: k) (len :: GHC.Types.Nat) o. GHC.Show.Show o => GHC.Show.Show (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.ScalarArray label len o)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall k (label :: k). Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.Scalar GHC.Int.Int16 label)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall k (label :: k). Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.Scalar GHC.Int.Int32 label)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall k (label :: k). Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.Scalar GHC.Int.Int64 label)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall k (label :: k). Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.Scalar GHC.Int.Int8 label)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall k (label :: k). Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.Scalar GHC.Word.Word16 label)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall k (label :: k). Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.Scalar GHC.Word.Word32 label)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall k (label :: k). Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.Scalar GHC.Word.Word64 label)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall k (label :: k). Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.Scalar GHC.Word.Word8 label)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall k (scalar :: GHC.Types.Nat) o (label :: k). (GHC.TypeLits.KnownNat scalar, GHC.Num.Num o) => Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.FromTypeLit (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.Scalar o label) scalar
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall k k1 (o :: k) (v :: k1). Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.Constant o v)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall k o (label :: k) (len :: GHC.Types.Nat). (GHC.Num.Num o, Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.Scalar o label), GHC.TypeLits.KnownNat len) => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.ScalarArray label len o)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall k o (len :: GHC.Types.Nat) (label :: k). (Data.Default.Class.Default o, GHC.TypeLits.KnownNat len) => Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.ScalarArray label len o)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall k o (v :: k). (Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent o, Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.FromTypeLit o v) => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.Constant o v)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall k o (v :: k). (Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent o, Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.FromTypeLit o v) => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.Template o v)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall k o (v :: k). Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.Template o v)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall scalartype k (label :: k). Data.Default.Class.Default scalartype => Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.Scalar scalartype label)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall scalartype k (label :: k). GHC.Classes.Eq scalartype => GHC.Classes.Eq (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.Scalar scalartype label)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall scalartype k (label :: k). GHC.Classes.Ord scalartype => GHC.Classes.Ord (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.Scalar scalartype label)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall scalartype k (label :: k). GHC.Num.Num scalartype => GHC.Num.Num (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.Scalar scalartype label)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall scalartype k (label :: k). GHC.Read.Read scalartype => GHC.Read.Read (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.Scalar scalartype label)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: instance forall scalartype k (label :: k). GHC.Show.Show scalartype => GHC.Show.Show (Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields.Scalar scalartype label)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: newtype FixSizeText (len :: Nat) (label :: Symbol)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: newtype Scalar scalartype (label :: k)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: newtype ScalarArray (label :: k) (len :: Nat) o
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: newtype U32Text (label :: Symbol)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: relabelScalar :: Scalar t l -> Scalar t l'
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: templateValue :: FromTypeLit o v => Template o v -> o
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: type I16 label = Scalar Int16 label
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: type I16Arr label size = ScalarArray label size Int16
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: type I32 label = Scalar Int32 label
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: type I32Arr label size = ScalarArray label size Int32
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: type I64 label = Scalar Int64 label
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: type I64Arr label size = ScalarArray label size Int64
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: type I8 label = Scalar Int8 label
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: type I8Arr label size = ScalarArray label size Int8
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: type IsTextSize len = (KnownNat len, 1 <= len, len <= 255)
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: type U16 label = Scalar Word16 label
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: type U16Arr label size = ScalarArray label size Word16
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: type U32 label = Scalar Word32 label
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: type U32Arr label size = ScalarArray label size Word32
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: type U64 label = Scalar Word64 label
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: type U64Arr label size = ScalarArray label size Word64
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: type U8 label = Scalar Word8 label
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: type U8Arr label size = ScalarArray label size Word8
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: u16 :: Word16 -> U16 label
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: u16Arr :: (KnownNat size, KnownSymbol label) => [Word16] -> U16Arr label size
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: u32 :: Word32 -> U32 label
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: u32Arr :: (KnownNat size, KnownSymbol label) => [Word32] -> U32Arr label size
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: u64 :: Word64 -> U64 label
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: u64Arr :: (KnownNat size, KnownSymbol label) => [Word64] -> U64Arr label size
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: u8 :: Word8 -> U8 label
- Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields: u8Arr :: (KnownNat size, KnownSymbol label) => [Word8] -> U8Arr label size
- Data.ByteString.IsoBaseFileFormat.Boxes.DataEntryUrl: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.DataEntryUrl.DataEntryUrl
- Data.ByteString.IsoBaseFileFormat.Boxes.DataEntryUrl: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.DataEntryUrl.DataEntryUrl
- Data.ByteString.IsoBaseFileFormat.Boxes.DataEntryUrn: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.DataEntryUrn.DataEntryUrn
- Data.ByteString.IsoBaseFileFormat.Boxes.DataEntryUrn: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.DataEntryUrn.DataEntryUrn
- Data.ByteString.IsoBaseFileFormat.Boxes.DataInformation: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.DataInformation.DataInformation
- Data.ByteString.IsoBaseFileFormat.Boxes.DataReference: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.DataReference.DataReference
- Data.ByteString.IsoBaseFileFormat.Boxes.DataReference: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.DataReference.DataReference
- Data.ByteString.IsoBaseFileFormat.Boxes.FileType: [compatibleBrands] :: FileType -> [FourCc]
- Data.ByteString.IsoBaseFileFormat.Boxes.FileType: [majorBrand] :: FileType -> FourCc
- Data.ByteString.IsoBaseFileFormat.Boxes.FileType: [minorVersion] :: FileType -> Word32
- Data.ByteString.IsoBaseFileFormat.Boxes.FileType: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.FileType.FileType
- Data.ByteString.IsoBaseFileFormat.Boxes.FileType: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.FileType.FileType
- Data.ByteString.IsoBaseFileFormat.Boxes.FullBox: BoxFlags :: Integer -> BoxFlags bits
- Data.ByteString.IsoBaseFileFormat.Boxes.FullBox: [FullBox] :: (KnownNat version, IsBox t) => BoxFlags 24 -> BoxContent t -> FullBox t version
- Data.ByteString.IsoBaseFileFormat.Boxes.FullBox: data FullBox t (version :: Nat)
- Data.ByteString.IsoBaseFileFormat.Boxes.FullBox: fullBox :: (KnownNat v, IsBox t) => BoxFlags 24 -> BoxContent t -> Box (FullBox t v)
- Data.ByteString.IsoBaseFileFormat.Boxes.FullBox: instance (Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox t, GHC.TypeLits.KnownNat v) => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.FullBox.FullBox t v)
- Data.ByteString.IsoBaseFileFormat.Boxes.FullBox: instance (GHC.TypeLits.KnownNat v, Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox t) => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox (Data.ByteString.IsoBaseFileFormat.Boxes.FullBox.FullBox t v)
- Data.ByteString.IsoBaseFileFormat.Boxes.FullBox: instance (GHC.TypeLits.KnownNat version, Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox t, Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Boxes.Box.BoxContent t)) => Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Boxes.FullBox.FullBox t version)
- Data.ByteString.IsoBaseFileFormat.Boxes.FullBox: instance GHC.TypeLits.KnownNat bits => Data.Bits.Bits (Data.ByteString.IsoBaseFileFormat.Boxes.FullBox.BoxFlags bits)
- Data.ByteString.IsoBaseFileFormat.Boxes.FullBox: instance GHC.TypeLits.KnownNat bits => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.FullBox.BoxFlags bits)
- Data.ByteString.IsoBaseFileFormat.Boxes.FullBox: instance forall k (bits :: k). GHC.Classes.Eq (Data.ByteString.IsoBaseFileFormat.Boxes.FullBox.BoxFlags bits)
- Data.ByteString.IsoBaseFileFormat.Boxes.FullBox: instance forall k (bits :: k). GHC.Num.Num (Data.ByteString.IsoBaseFileFormat.Boxes.FullBox.BoxFlags bits)
- Data.ByteString.IsoBaseFileFormat.Boxes.FullBox: instance forall k (bits :: k). GHC.Show.Show (Data.ByteString.IsoBaseFileFormat.Boxes.FullBox.BoxFlags bits)
- Data.ByteString.IsoBaseFileFormat.Boxes.FullBox: newtype BoxFlags bits
- Data.ByteString.IsoBaseFileFormat.Boxes.Handler: instance GHC.TypeLits.KnownSymbol (Data.ByteString.IsoBaseFileFormat.Boxes.Handler.HandlerTypeCode t) => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox (Data.ByteString.IsoBaseFileFormat.Boxes.Handler.Handler t)
- Data.ByteString.IsoBaseFileFormat.Boxes.Handler: instance GHC.TypeLits.KnownSymbol (Data.ByteString.IsoBaseFileFormat.Boxes.Handler.HandlerTypeCode t) => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.Handler.Handler t)
- Data.ByteString.IsoBaseFileFormat.Boxes.HintMediaHeader: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.HintMediaHeader.HintMediaHeader
- Data.ByteString.IsoBaseFileFormat.Boxes.HintMediaHeader: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.HintMediaHeader.HintMediaHeader
- Data.ByteString.IsoBaseFileFormat.Boxes.Language: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.Language.Language
- Data.ByteString.IsoBaseFileFormat.Boxes.Media: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.Media.Media
- Data.ByteString.IsoBaseFileFormat.Boxes.MediaData: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.MediaData.MediaData
- Data.ByteString.IsoBaseFileFormat.Boxes.MediaData: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.MediaData.MediaData
- Data.ByteString.IsoBaseFileFormat.Boxes.MediaHeader: data MediaHeader (v :: Nat)
- Data.ByteString.IsoBaseFileFormat.Boxes.MediaHeader: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox (Data.ByteString.IsoBaseFileFormat.Boxes.MediaHeader.MediaHeader v)
- Data.ByteString.IsoBaseFileFormat.Boxes.MediaHeader: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.MediaHeader.MediaHeader v)
- Data.ByteString.IsoBaseFileFormat.Boxes.MediaInformation: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.MediaInformation.MediaInformation
- Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry.BitRate
- Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry.UriField
- Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry.UriInitField
- Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry.MetaDataCoding "mett")
- Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry.MetaDataCoding "metx")
- Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry.MetaDataCoding "urim")
- Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry.BitRate
- Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry.UriField
- Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry.UriInitField
- Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry: metaDataSampleEntry :: MetaDataCoding c -> U16 "data_reference_index" -> SampleEntry TimedMetaDataTrack (MetaDataCoding c) -> Box (SampleEntry TimedMetaDataTrack (MetaDataCoding c))
- Data.ByteString.IsoBaseFileFormat.Boxes.Movie: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.Movie.Movie
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader: data MovieHeader (version :: Nat)
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox (Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader.MovieHeader version)
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader.MovieHeader version)
- Data.ByteString.IsoBaseFileFormat.Boxes.NullMediaHeader: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.NullMediaHeader.NullMediaHeader
- Data.ByteString.IsoBaseFileFormat.Boxes.NullMediaHeader: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.NullMediaHeader.NullMediaHeader
- Data.ByteString.IsoBaseFileFormat.Boxes.ProgressiveDownloadInformation: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.ProgressiveDownloadInformation.ProgressiveDownload
- Data.ByteString.IsoBaseFileFormat.Boxes.SampleDescription: instance forall k (h :: k). Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox (Data.ByteString.IsoBaseFileFormat.Boxes.SampleDescription.SampleDescription h)
- Data.ByteString.IsoBaseFileFormat.Boxes.SampleDescription: instance forall k (handlerType :: k). Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.SampleDescription.SampleDescription handlerType)
- Data.ByteString.IsoBaseFileFormat.Boxes.SampleDescription: instance forall k (handlerType :: k). Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Boxes.SampleDescription.SampleDescription handlerType)
- Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry: [SampleEntryFields] :: Constant (U8Arr "reserved" 6) '[0, 0, 0, 0, 0, 0] :+ (U16 "data_reference_index" :+ a) -> SampleEntryFields a
- Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent a => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry.SampleEntryFields a)
- Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry: instance Data.Default.Class.Default a => Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry.SampleEntryFields a)
- Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry: instance forall k (handlertype :: Data.ByteString.IsoBaseFileFormat.Boxes.Handler.HandlerType) (format :: k). (Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry.SampleEntry handlertype format), GHC.TypeLits.KnownSymbol (Data.ByteString.IsoBaseFileFormat.Boxes.Box.BoxTypeSymbol (Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry.SampleEntry handlertype format))) => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox (Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry.SampleEntry handlertype format)
- Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry: newtype SampleEntryFields a
- Data.ByteString.IsoBaseFileFormat.Boxes.SampleTable: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.SampleTable.SampleTable
- Data.ByteString.IsoBaseFileFormat.Boxes.Skip: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.Skip.Skip
- Data.ByteString.IsoBaseFileFormat.Boxes.Skip: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.Skip.Skip
- Data.ByteString.IsoBaseFileFormat.Boxes.SoundMediaHeader: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.SoundMediaHeader.SoundMediaHeader
- Data.ByteString.IsoBaseFileFormat.Boxes.SoundMediaHeader: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.SoundMediaHeader.SoundMediaHeader
- Data.ByteString.IsoBaseFileFormat.Boxes.Time: durationFromSeconds :: Num t => TimeScale -> Integer -> t
- Data.ByteString.IsoBaseFileFormat.Boxes.Time: mp4CurrentTime :: Num t => IO t
- Data.ByteString.IsoBaseFileFormat.Boxes.Time: referenceTime :: UTCTime
- Data.ByteString.IsoBaseFileFormat.Boxes.Time: type TimeScale = Template (U32 "timescale") 90000
- Data.ByteString.IsoBaseFileFormat.Boxes.Time: type Timing (version :: Nat) = Versioned TimingV0 TimingV1 version
- Data.ByteString.IsoBaseFileFormat.Boxes.Time: utcToMp4 :: Num t => UTCTime -> t
- Data.ByteString.IsoBaseFileFormat.Boxes.TimeToSample: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.TimeToSample.TimeToSampleTable
- Data.ByteString.IsoBaseFileFormat.Boxes.TimeToSample: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.TimeToSample.TimeToSampleTable
- Data.ByteString.IsoBaseFileFormat.Boxes.Track: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.Track.Track
- Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: data TrackHeader (version :: Nat)
- Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox (Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader.TrackHeader version)
- Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader.TrackHeader version)
- Data.ByteString.IsoBaseFileFormat.Boxes.Versioned: [V0] :: IsBoxContent v0 => v0 -> Versioned v0 v1 0
- Data.ByteString.IsoBaseFileFormat.Boxes.Versioned: [V1] :: IsBoxContent v1 => v1 -> Versioned v0 v1 1
- Data.ByteString.IsoBaseFileFormat.Boxes.Versioned: data Versioned v0 v1 (version :: Nat)
- Data.ByteString.IsoBaseFileFormat.Boxes.Versioned: instance (version ~ 0, Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent v0, Data.Default.Class.Default v0) => Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Boxes.Versioned.Versioned v0 v1 version)
- Data.ByteString.IsoBaseFileFormat.Boxes.Versioned: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.Versioned.Versioned v0 v1 version)
- Data.ByteString.IsoBaseFileFormat.Boxes.VideoMediaHeader: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.VideoMediaHeader.VideoMediaHeader
- Data.ByteString.IsoBaseFileFormat.Boxes.VideoMediaHeader: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.VideoMediaHeader.VideoMediaHeader
- Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: instance (GHC.TypeLits.KnownSymbol (Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.ColourTypeCode profile), Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.ColourType profile)) => Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.ColourInformation profile)
- Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.CleanAperture
- Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.PixelAspectRatio
- Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.SomeColourInformation
- Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry.SampleEntry 'Data.ByteString.IsoBaseFileFormat.Boxes.Handler.VideoTrack (Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.VideoCoding c))
- Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.CleanAperture
- Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.FullRangeFlag
- Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.PixelAspectRatio
- Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.SomeColourInformation
- Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Boxes.Box.IsBoxContent [Data.ByteString.IsoBaseFileFormat.Boxes.Box.Box Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.SomeColourInformation]
- Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: instance Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry.SampleEntry 'Data.ByteString.IsoBaseFileFormat.Boxes.Handler.VideoTrack (Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.VideoCoding c))
- Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: visualSampleEntry :: (KnownSymbol (BoxTypeSymbol (SampleEntry VideoTrack (VideoCoding codec)))) => VideoCoding codec -> U16 "data_reference_index" -> SampleEntry VideoTrack (VideoCoding codec) -> Box (SampleEntry VideoTrack (VideoCoding codec))
- Data.ByteString.IsoBaseFileFormat.Brands.Dash: SingleAudioTrackInit :: MovieHeader 0 -> TrackHeader 0 -> MediaHeader 0 -> Handler AudioTrack -> SoundMediaHeader -> SingleAudioTrackInit
- Data.ByteString.IsoBaseFileFormat.Brands.Dash: [hdlr] :: SingleAudioTrackInit -> Handler AudioTrack
- Data.ByteString.IsoBaseFileFormat.Brands.Dash: [mdhd] :: SingleAudioTrackInit -> MediaHeader 0
- Data.ByteString.IsoBaseFileFormat.Brands.Dash: [mvhd] :: SingleAudioTrackInit -> MovieHeader 0
- Data.ByteString.IsoBaseFileFormat.Brands.Dash: [smhd] :: SingleAudioTrackInit -> SoundMediaHeader
- Data.ByteString.IsoBaseFileFormat.Brands.Dash: [tkhd] :: SingleAudioTrackInit -> TrackHeader 0
- Data.ByteString.IsoBaseFileFormat.Brands.Dash: data SingleAudioTrackInit
- Data.ByteString.IsoBaseFileFormat.Brands.Dash: instance Data.ByteString.IsoBaseFileFormat.Brands.Types.IsMediaFileFormat (Data.ByteString.IsoBaseFileFormat.Brands.Dash.Dash v)
- Data.ByteString.IsoBaseFileFormat.Brands.Dash: mkSingleTrackInit :: SingleAudioTrackInit -> Builder
- Data.ByteString.IsoBaseFileFormat.Brands.Types: class IsMediaFileFormat brand where type BoxLayout brand mediaBuilder _ t = boxBuilder t where {
- Data.ByteString.IsoBaseFileFormat.Brands.Types: mediaBuilder :: forall t proxy. (IsMediaFileFormat brand, IsBoxContent t, IsRuleConform t (BoxLayout brand) ~ True) => proxy brand -> t -> Builder
- Data.ByteString.IsoBaseFileFormat.Brands.Types: type family BoxLayout brand;
- Data.ByteString.IsoBaseFileFormat.Brands.Types: }
- Data.ByteString.IsoBaseFileFormat.Util.BitRecords: data (:/) :: Symbol -> k -> Type
- Data.ByteString.IsoBaseFileFormat.Util.BitRecords: data Field :: Nat -> Type
- Data.ByteString.IsoBaseFileFormat.Util.BitRecords: getField :: forall a b (path :: k) (first :: Nat) (last :: Nat) field pxy1 pxy2. (IsFieldC path field first last, Integral a, Bits a, Num b) => pxy1 path -> pxy2 field -> a -> b
- Data.ByteString.IsoBaseFileFormat.Util.BitRecords: getFlag :: forall a (path :: k) (first :: Nat) field p1 p2. (IsFieldC path field first first, Bits a) => p1 path -> p2 field -> a -> Bool
- Data.ByteString.IsoBaseFileFormat.Util.BitRecords: getFooField :: IsFieldC name Foo first last => proxy name -> Word64 -> Word64
- Data.ByteString.IsoBaseFileFormat.Util.BitRecords: setField :: forall a b (path :: k) (first :: Nat) (last :: Nat) field pxy1 pxy2. (IsFieldC path field first last, Num a, Bits a, Integral b) => pxy1 path -> pxy2 field -> b -> a -> a
- Data.ByteString.IsoBaseFileFormat.Util.BitRecords: setFlag :: forall a (path :: k) (first :: Nat) field p1 p2. (IsFieldC path field first first, Bits a) => p1 path -> p2 field -> Bool -> a -> a
- Data.ByteString.IsoBaseFileFormat.Util.BitRecords: type FieldPosition = (Nat, Nat)
- Data.ByteString.IsoBaseFileFormat.Util.BitRecords: type Flag = Field 1
- Data.ByteString.IsoBaseFileFormat.Util.BitRecords: type Foo = (((("foo" :=> Flag) :*: Field 4) :*: ("bar" :=> Field 2)) :*: Field 4) :*: ("baz" :=> Field 17)
- Data.ByteString.IsoBaseFileFormat.Util.BitRecords: type IsFieldC name field first last = (name `HasFieldConstraint` field, KnownNat first, KnownNat last, Right '(first, last) ~ (GetFieldPosition field name))
- Data.ByteString.IsoBaseFileFormat.Util.BitRecords: type Rem (x :: Nat) (y :: Nat) = RemImpl x y 0
+ Data.ByteString.IsoBaseFileFormat.Box: ($:) :: IsBox l => (Boxes '[Box l] -> r) -> Box l -> r
+ Data.ByteString.IsoBaseFileFormat.Box: (:+) :: !a -> !b -> (:+) a b
+ Data.ByteString.IsoBaseFileFormat.Box: BoxSize :: !Word64 -> BoxSize
+ Data.ByteString.IsoBaseFileFormat.Box: BoxSizeExtension :: BoxSize -> BoxSizeExtension
+ Data.ByteString.IsoBaseFileFormat.Box: BoxTypeExtension :: BoxType -> BoxTypeExtension
+ Data.ByteString.IsoBaseFileFormat.Box: CustomBoxType :: !String -> BoxType
+ Data.ByteString.IsoBaseFileFormat.Box: FourCc :: (Char, Char, Char, Char) -> FourCc
+ Data.ByteString.IsoBaseFileFormat.Box: ListContent :: [contentType] -> ListContent sizeType contentType
+ Data.ByteString.IsoBaseFileFormat.Box: StdType :: !FourCc -> BoxType
+ Data.ByteString.IsoBaseFileFormat.Box: UnlimitedSize :: BoxSize
+ Data.ByteString.IsoBaseFileFormat.Box: [:.] :: IsBox l => !(Box l) -> !(Boxes r) -> Boxes (Box l : r)
+ Data.ByteString.IsoBaseFileFormat.Box: [:<>] :: !(Boxes l) -> !(Boxes r) -> Boxes (l :++ r)
+ Data.ByteString.IsoBaseFileFormat.Box: [:|] :: (IsBox l, IsBox r) => !(Box l) -> !(Box r) -> Boxes '[Box l, Box r]
+ Data.ByteString.IsoBaseFileFormat.Box: [Box] :: !(BoxContent b) -> Box b
+ Data.ByteString.IsoBaseFileFormat.Box: [ContainerBox] :: IsBox b => !(BoxContent b) -> !(Boxes bs) -> ContainerBox b bs
+ Data.ByteString.IsoBaseFileFormat.Box: [NoBoxes] :: Boxes '[]
+ Data.ByteString.IsoBaseFileFormat.Box: boxBuilder :: IsBoxContent a => a -> Builder
+ Data.ByteString.IsoBaseFileFormat.Box: boxSize :: IsBoxContent a => a -> BoxSize
+ Data.ByteString.IsoBaseFileFormat.Box: class (KnownSymbol (BoxTypeSymbol t), IsBoxContent (BoxContent t)) => IsBox (t :: Type) where type BoxContent t type BoxContent t = t toBoxType _ = parseBoxType (Proxy :: Proxy (BoxTypeSymbol t)) where {
+ Data.ByteString.IsoBaseFileFormat.Box: class IsBoxContent a
+ Data.ByteString.IsoBaseFileFormat.Box: containerBox :: (IsBox t) => BoxContent t -> Boxes ts -> Box (ContainerBox t ts)
+ Data.ByteString.IsoBaseFileFormat.Box: data (:+) a b
+ Data.ByteString.IsoBaseFileFormat.Box: data Box b
+ Data.ByteString.IsoBaseFileFormat.Box: data BoxSize
+ Data.ByteString.IsoBaseFileFormat.Box: data BoxType
+ Data.ByteString.IsoBaseFileFormat.Box: data Boxes (boxTypes :: [Type])
+ Data.ByteString.IsoBaseFileFormat.Box: data ContainerBox b (bs :: [Type])
+ Data.ByteString.IsoBaseFileFormat.Box: fromBoxSize :: Num a => a -> BoxSize -> a
+ Data.ByteString.IsoBaseFileFormat.Box: infixr 3 $:
+ Data.ByteString.IsoBaseFileFormat.Box: instance (Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent p, Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent c) => Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (p Data.ByteString.IsoBaseFileFormat.Box.:+ c)
+ Data.ByteString.IsoBaseFileFormat.Box: instance (Data.Default.Class.Default a, Data.Default.Class.Default b) => Data.Default.Class.Default (a Data.ByteString.IsoBaseFileFormat.Box.:+ b)
+ Data.ByteString.IsoBaseFileFormat.Box: instance (GHC.Num.Num sizeType, Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent sizeType, Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent contentType) => Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Box.ListContent * sizeType contentType)
+ Data.ByteString.IsoBaseFileFormat.Box: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox b => Data.ByteString.IsoBaseFileFormat.Box.IsBox (Data.ByteString.IsoBaseFileFormat.Box.Box b)
+ Data.ByteString.IsoBaseFileFormat.Box: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox b => Data.ByteString.IsoBaseFileFormat.Box.IsBox (Data.ByteString.IsoBaseFileFormat.Box.ContainerBox b bs)
+ Data.ByteString.IsoBaseFileFormat.Box: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox cnt => Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Box.Box cnt)
+ Data.ByteString.IsoBaseFileFormat.Box: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent ()
+ Data.ByteString.IsoBaseFileFormat.Box: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Box.Boxes bs)
+ Data.ByteString.IsoBaseFileFormat.Box: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Box.ContainerBox b bs)
+ Data.ByteString.IsoBaseFileFormat.Box: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.Internal.ByteString
+ Data.ByteString.IsoBaseFileFormat.Box: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Box.BoxSize
+ Data.ByteString.IsoBaseFileFormat.Box: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Box.BoxSizeExtension
+ Data.ByteString.IsoBaseFileFormat.Box: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Box.BoxType
+ Data.ByteString.IsoBaseFileFormat.Box: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Box.BoxTypeExtension
+ Data.ByteString.IsoBaseFileFormat.Box: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Box.FourCc
+ Data.ByteString.IsoBaseFileFormat.Box: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.Text.Internal.Text
+ Data.ByteString.IsoBaseFileFormat.Box: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.Type.BitRecords.Builder.LazyByteStringBuilder.BuilderBox
+ Data.ByteString.IsoBaseFileFormat.Box: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent GHC.Int.Int16
+ Data.ByteString.IsoBaseFileFormat.Box: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent GHC.Int.Int32
+ Data.ByteString.IsoBaseFileFormat.Box: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent GHC.Int.Int64
+ Data.ByteString.IsoBaseFileFormat.Box: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent GHC.Int.Int8
+ Data.ByteString.IsoBaseFileFormat.Box: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent GHC.Word.Word16
+ Data.ByteString.IsoBaseFileFormat.Box: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent GHC.Word.Word32
+ Data.ByteString.IsoBaseFileFormat.Box: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent GHC.Word.Word64
+ Data.ByteString.IsoBaseFileFormat.Box: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent GHC.Word.Word8
+ Data.ByteString.IsoBaseFileFormat.Box: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent a => Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (GHC.Base.Maybe a)
+ Data.ByteString.IsoBaseFileFormat.Box: instance Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Box.BoxContent b) => Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Box.Box b)
+ Data.ByteString.IsoBaseFileFormat.Box: instance Data.String.IsString Data.ByteString.IsoBaseFileFormat.Box.FourCc
+ Data.ByteString.IsoBaseFileFormat.Box: instance GHC.Classes.Eq Data.ByteString.IsoBaseFileFormat.Box.BoxSize
+ Data.ByteString.IsoBaseFileFormat.Box: instance GHC.Classes.Eq Data.ByteString.IsoBaseFileFormat.Box.BoxType
+ Data.ByteString.IsoBaseFileFormat.Box: instance GHC.Classes.Eq Data.ByteString.IsoBaseFileFormat.Box.FourCc
+ Data.ByteString.IsoBaseFileFormat.Box: instance GHC.Num.Num Data.ByteString.IsoBaseFileFormat.Box.BoxSize
+ Data.ByteString.IsoBaseFileFormat.Box: instance GHC.Show.Show Data.ByteString.IsoBaseFileFormat.Box.BoxSize
+ Data.ByteString.IsoBaseFileFormat.Box: instance GHC.Show.Show Data.ByteString.IsoBaseFileFormat.Box.BoxType
+ Data.ByteString.IsoBaseFileFormat.Box: instance GHC.Show.Show Data.ByteString.IsoBaseFileFormat.Box.FourCc
+ Data.ByteString.IsoBaseFileFormat.Box: instance forall k (sizeTupe :: k) contentType. Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Box.ListContent k sizeTupe contentType)
+ Data.ByteString.IsoBaseFileFormat.Box: instance forall k c (s :: k). Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent c => Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.Tagged.Tagged k s c)
+ Data.ByteString.IsoBaseFileFormat.Box: newtype BoxSizeExtension
+ Data.ByteString.IsoBaseFileFormat.Box: newtype BoxTypeExtension
+ Data.ByteString.IsoBaseFileFormat.Box: newtype FourCc
+ Data.ByteString.IsoBaseFileFormat.Box: newtype ListContent sizeType contentType
+ Data.ByteString.IsoBaseFileFormat.Box: parseBoxType :: KnownSymbol t => proxy t -> BoxType
+ Data.ByteString.IsoBaseFileFormat.Box: singletonBox :: IsBox l => Box l -> Boxes '[Box l]
+ Data.ByteString.IsoBaseFileFormat.Box: toBoxType :: IsBox t => proxy t -> BoxType
+ Data.ByteString.IsoBaseFileFormat.Box: type BoxContent t = t;
+ Data.ByteString.IsoBaseFileFormat.Box: type OM b bs = ContainerBox b bs
+ Data.ByteString.IsoBaseFileFormat.Box: type OM_ b = Box b
+ Data.ByteString.IsoBaseFileFormat.Box: type OO b bs = OnceOptionalX (ContainerBox b bs)
+ Data.ByteString.IsoBaseFileFormat.Box: type OO_ b = OnceOptionalX (Box b)
+ Data.ByteString.IsoBaseFileFormat.Box: type SM b bs = SomeMandatoryX (ContainerBox b bs)
+ Data.ByteString.IsoBaseFileFormat.Box: type SM_ b = SomeMandatoryX (Box b)
+ Data.ByteString.IsoBaseFileFormat.Box: type SO b bs = SomeOptionalX (ContainerBox b bs)
+ Data.ByteString.IsoBaseFileFormat.Box: type SO_ b = SomeOptionalX (Box b)
+ Data.ByteString.IsoBaseFileFormat.Box: type family BoxContent t;
+ Data.ByteString.IsoBaseFileFormat.Box: typeListLength :: forall a proxy (ts :: [k]). (KnownNat (Length ts), Num a) => proxy ts -> a
+ Data.ByteString.IsoBaseFileFormat.Box: }
+ Data.ByteString.IsoBaseFileFormat.Boxes.AudioSampleEntry: [AudioSampleEntry] :: Constant (U32Arr "reserved" 2) '[0, 0] :+ (Template (U16 "channelcount") 2 :+ (Template (U16 "samplesize") 16 :+ (U16 "pre_defined" :+ (Constant (U16 "reserved") 0 :+ (Template (U32 "samplerate") (DefaultSoundSamplerate * 65536) :+ b))))) -> AudioSampleEntry b
+ Data.ByteString.IsoBaseFileFormat.Boxes.AudioSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent b => Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.AudioSampleEntry.AudioSampleEntry b)
+ Data.ByteString.IsoBaseFileFormat.Boxes.AudioSampleEntry: instance Data.Default.Class.Default b => Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Boxes.AudioSampleEntry.AudioSampleEntry b)
+ Data.ByteString.IsoBaseFileFormat.Boxes.AudioSampleEntry: instance GHC.Base.Functor Data.ByteString.IsoBaseFileFormat.Boxes.AudioSampleEntry.AudioSampleEntry
+ Data.ByteString.IsoBaseFileFormat.Boxes.AudioSampleEntry: newtype AudioSampleEntry b
+ Data.ByteString.IsoBaseFileFormat.Boxes.ChunkOffset: ChunkOffsetTable :: (ListContent (U32 "entry_count") stcoEntry) -> ChunkOffsetTable stcoEntry
+ Data.ByteString.IsoBaseFileFormat.Boxes.ChunkOffset: chunkOffset32 :: [StcoEntry32] -> Box ChunkOffset32
+ Data.ByteString.IsoBaseFileFormat.Boxes.ChunkOffset: chunkOffset64 :: [StcoEntry64] -> Box ChunkOffset64
+ Data.ByteString.IsoBaseFileFormat.Boxes.ChunkOffset: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.ChunkOffset.ChunkOffsetTable32
+ Data.ByteString.IsoBaseFileFormat.Boxes.ChunkOffset: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.ChunkOffset.ChunkOffsetTable64
+ Data.ByteString.IsoBaseFileFormat.Boxes.ChunkOffset: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent stcoEntry => Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.ChunkOffset.ChunkOffsetTable stcoEntry)
+ Data.ByteString.IsoBaseFileFormat.Boxes.ChunkOffset: instance Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Boxes.ChunkOffset.ChunkOffsetTable stcoEntry)
+ Data.ByteString.IsoBaseFileFormat.Boxes.ChunkOffset: newtype ChunkOffsetTable stcoEntry
+ Data.ByteString.IsoBaseFileFormat.Boxes.ChunkOffset: type ChunkOffset32 = FullBox ChunkOffsetTable32 0
+ Data.ByteString.IsoBaseFileFormat.Boxes.ChunkOffset: type ChunkOffset64 = FullBox ChunkOffsetTable64 0
+ Data.ByteString.IsoBaseFileFormat.Boxes.ChunkOffset: type ChunkOffsetTable32 = ChunkOffsetTable StcoEntry32
+ Data.ByteString.IsoBaseFileFormat.Boxes.ChunkOffset: type ChunkOffsetTable64 = ChunkOffsetTable StcoEntry64
+ Data.ByteString.IsoBaseFileFormat.Boxes.ChunkOffset: type StcoEntry32 = U32 "chunk_offset"
+ Data.ByteString.IsoBaseFileFormat.Boxes.ChunkOffset: type StcoEntry64 = U64 "chunk_offset"
+ Data.ByteString.IsoBaseFileFormat.Boxes.DataEntryUrl: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.DataEntryUrl.DataEntryUrl
+ Data.ByteString.IsoBaseFileFormat.Boxes.DataEntryUrl: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.DataEntryUrl.DataEntryUrl
+ Data.ByteString.IsoBaseFileFormat.Boxes.DataEntryUrn: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.DataEntryUrn.DataEntryUrn
+ Data.ByteString.IsoBaseFileFormat.Boxes.DataEntryUrn: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.DataEntryUrn.DataEntryUrn
+ Data.ByteString.IsoBaseFileFormat.Boxes.DataInformation: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.DataInformation.DataInformation
+ Data.ByteString.IsoBaseFileFormat.Boxes.DataReference: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.DataReference.DataReference
+ Data.ByteString.IsoBaseFileFormat.Boxes.DataReference: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.DataReference.DataReference
+ Data.ByteString.IsoBaseFileFormat.Boxes.FileType: [$sel:compatibleBrands:FileType] :: FileType -> ![FourCc]
+ Data.ByteString.IsoBaseFileFormat.Boxes.FileType: [$sel:majorBrand:FileType] :: FileType -> !FourCc
+ Data.ByteString.IsoBaseFileFormat.Boxes.FileType: [$sel:minorVersion:FileType] :: FileType -> !Word32
+ Data.ByteString.IsoBaseFileFormat.Boxes.FileType: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.FileType.FileType
+ Data.ByteString.IsoBaseFileFormat.Boxes.FileType: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.FileType.FileType
+ Data.ByteString.IsoBaseFileFormat.Boxes.Handler: instance GHC.TypeLits.KnownSymbol (Data.ByteString.IsoBaseFileFormat.Boxes.Handler.HandlerTypeCode t) => Data.ByteString.IsoBaseFileFormat.Box.IsBox (Data.ByteString.IsoBaseFileFormat.Boxes.Handler.Handler t)
+ Data.ByteString.IsoBaseFileFormat.Boxes.Handler: instance GHC.TypeLits.KnownSymbol (Data.ByteString.IsoBaseFileFormat.Boxes.Handler.HandlerTypeCode t) => Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.Handler.Handler t)
+ Data.ByteString.IsoBaseFileFormat.Boxes.HintMediaHeader: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.HintMediaHeader.HintMediaHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.HintMediaHeader: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.HintMediaHeader.HintMediaHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.HintSampleEntry: [HintSampleEntry] :: protocol -> HintSampleEntry protocol
+ Data.ByteString.IsoBaseFileFormat.Boxes.HintSampleEntry: newtype HintSampleEntry protocol
+ Data.ByteString.IsoBaseFileFormat.Boxes.Language: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.Language.Language
+ Data.ByteString.IsoBaseFileFormat.Boxes.Media: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.Media.Media
+ Data.ByteString.IsoBaseFileFormat.Boxes.MediaData: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.MediaData.MediaData
+ Data.ByteString.IsoBaseFileFormat.Boxes.MediaData: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.MediaData.MediaData
+ Data.ByteString.IsoBaseFileFormat.Boxes.MediaHeader: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox (Data.ByteString.IsoBaseFileFormat.Boxes.MediaHeader.MediaHeader v)
+ Data.ByteString.IsoBaseFileFormat.Boxes.MediaHeader: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.MediaHeader.MediaHeader v)
+ Data.ByteString.IsoBaseFileFormat.Boxes.MediaHeader: newtype MediaHeader (v :: Nat)
+ Data.ByteString.IsoBaseFileFormat.Boxes.MediaInformation: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.MediaInformation.MediaInformation
+ Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry.BitRate
+ Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry.UriField
+ Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry.UriInitField
+ Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry.MetaDataCoding "mett")
+ Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry.MetaDataCoding "metx")
+ Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry.MetaDataCoding "urim")
+ Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry.BitRate
+ Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry.UriField
+ Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry.UriInitField
+ Data.ByteString.IsoBaseFileFormat.Boxes.Movie: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.Movie.Movie
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieExtends: data MovieExtends
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieExtends: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.MovieExtends.MovieExtends
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieExtends: movieExtends :: Boxes ts -> Box (ContainerBox MovieExtends ts)
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieExtendsHeader: [MovieExtendsHeader] :: Versioned (U32 "fragment_duration") (U64 "fragment_duration") version -> MovieExtendsHeader version
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieExtendsHeader: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox (Data.ByteString.IsoBaseFileFormat.Boxes.MovieExtendsHeader.MovieExtendsHeader version)
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieExtendsHeader: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.MovieExtendsHeader.MovieExtendsHeader version)
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieExtendsHeader: movieExtendsHeader :: (KnownNat version) => MovieExtendsHeader version -> Box (FullBox (MovieExtendsHeader version) version)
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieExtendsHeader: newtype MovieExtendsHeader (version :: Nat)
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieFragment: data MovieFragment
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieFragment: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.MovieFragment.MovieFragment
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieFragment: movieFragment :: Boxes ts -> Box (ContainerBox MovieFragment ts)
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieFragment: movieFragmentStaticSize :: Num a => a
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieFragmentHeader: [MovieFragmentHeader] :: U32 "sequence_number" -> MovieFragmentHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieFragmentHeader: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.MovieFragmentHeader.MovieFragmentHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieFragmentHeader: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.MovieFragmentHeader.MovieFragmentHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieFragmentHeader: instance Data.Default.Class.Default Data.ByteString.IsoBaseFileFormat.Boxes.MovieFragmentHeader.MovieFragmentHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieFragmentHeader: movieFragmentHeader :: MovieFragmentHeader -> Box (FullBox MovieFragmentHeader 0)
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieFragmentHeader: movieFragmentHeaderStaticSize :: Num a => a
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieFragmentHeader: newtype MovieFragmentHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox (Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader.MovieHeader version)
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader.MovieHeader version)
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader: newtype MovieHeader (version :: Nat)
+ Data.ByteString.IsoBaseFileFormat.Boxes.NullMediaHeader: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.NullMediaHeader.NullMediaHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.NullMediaHeader: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.NullMediaHeader.NullMediaHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.ProgressiveDownloadInformation: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.ProgressiveDownloadInformation.ProgressiveDownload
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleDescription: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.SampleDescription.SampleDescription
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleDescription: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.SampleDescription.SampleDescription
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleDescription: instance Data.Default.Class.Default Data.ByteString.IsoBaseFileFormat.Boxes.SampleDescription.SampleDescription
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry: [SampleEntry] :: Constant (U8Arr "reserved" 6) '[0, 0, 0, 0, 0, 0] :+ (U16 "data_reference_index" :+ handlerSpecific) -> SampleEntry handlerSpecific
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry: instance (Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent handlertype, GHC.TypeLits.KnownSymbol (Data.ByteString.IsoBaseFileFormat.Box.BoxTypeSymbol * handlertype)) => Data.ByteString.IsoBaseFileFormat.Box.IsBox (Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry.SampleEntry handlertype)
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent handlerSpecific => Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry.SampleEntry handlerSpecific)
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry: instance Data.Default.Class.Default handlerSpecific => Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry.SampleEntry handlerSpecific)
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry: newtype SampleEntry handlerSpecific
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleSize: FixedSampleSize :: !Word32 -> !Word32 -> SampleSizeTable
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleSize: SampleSizeTable :: !(ListContent Word32 Word32) -> SampleSizeTable
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleSize: [$sel:sampleCount:FixedSampleSize] :: SampleSizeTable -> !Word32
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleSize: [$sel:sampleSize:FixedSampleSize] :: SampleSizeTable -> !Word32
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleSize: data SampleSizeTable
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleSize: fixedSampleSize :: Word32 -> Word32 -> Box SampleSize
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleSize: individualSampleSizes :: [Word32] -> Box SampleSize
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleSize: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.SampleSize.SampleSizeTable
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleSize: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.SampleSize.SampleSizeTable
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleSize: type SampleSize = FullBox SampleSizeTable 0
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleTable: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.SampleTable.SampleTable
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleToChunk: SampleToChunkTable :: (ListContent (U32 "entry_count") StscEntry) -> SampleToChunkTable
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleToChunk: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.SampleToChunk.SampleToChunkTable
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleToChunk: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.SampleToChunk.SampleToChunkTable
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleToChunk: instance Data.Default.Class.Default Data.ByteString.IsoBaseFileFormat.Boxes.SampleToChunk.SampleToChunkTable
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleToChunk: newtype SampleToChunkTable
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleToChunk: sampleToChunk :: [StscEntry] -> Box SampleToChunk
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleToChunk: type SampleToChunk = FullBox SampleToChunkTable 0
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleToChunk: type StscEntry = U32 "first_chunk" :+ (U32 "samples_per_chunk" :+ U32 "sample_description_index")
+ Data.ByteString.IsoBaseFileFormat.Boxes.SegmentType: SegmentType :: !FourCc -> !Word32 -> ![FourCc] -> SegmentType
+ Data.ByteString.IsoBaseFileFormat.Boxes.SegmentType: [$sel:compatibleBrands:SegmentType] :: SegmentType -> ![FourCc]
+ Data.ByteString.IsoBaseFileFormat.Boxes.SegmentType: [$sel:majorBrand:SegmentType] :: SegmentType -> !FourCc
+ Data.ByteString.IsoBaseFileFormat.Boxes.SegmentType: [$sel:minorVersion:SegmentType] :: SegmentType -> !Word32
+ Data.ByteString.IsoBaseFileFormat.Boxes.SegmentType: data SegmentType
+ Data.ByteString.IsoBaseFileFormat.Boxes.SegmentType: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.SegmentType.SegmentType
+ Data.ByteString.IsoBaseFileFormat.Boxes.SegmentType: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.SegmentType.SegmentType
+ Data.ByteString.IsoBaseFileFormat.Boxes.SegmentType: segmentTypeBox :: SegmentType -> Box SegmentType
+ Data.ByteString.IsoBaseFileFormat.Boxes.Skip: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.Skip.Skip
+ Data.ByteString.IsoBaseFileFormat.Boxes.Skip: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.Skip.Skip
+ Data.ByteString.IsoBaseFileFormat.Boxes.SoundMediaHeader: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.SoundMediaHeader.SoundMediaHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.SoundMediaHeader: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.SoundMediaHeader.SoundMediaHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.TimeToSample: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.TimeToSample.TimeToSampleTable
+ Data.ByteString.IsoBaseFileFormat.Boxes.TimeToSample: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.TimeToSample.TimeToSampleTable
+ Data.ByteString.IsoBaseFileFormat.Boxes.Track: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.Track.Track
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackExtends: [MkTrackExtends] :: BuilderBox -> TrackExtends
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackExtends: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.TrackExtends.TrackExtends
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackExtends: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.TrackExtends.TrackExtends
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackExtends: newtype TrackExtends
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackExtends: trackExtends :: Word32 -> Word32 -> Word32 -> Word32 -> B 2 -> B 2 -> B 2 -> B 2 -> B 3 -> Bool -> Word16 -> Box (FullBox TrackExtends 0)
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackExtends: trackExtendsUnknownDuration :: Word32 -> Word32 -> Box (FullBox TrackExtends 0)
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackExtends: type TrackExtendsBody = ("track_ID" @: FieldU32) .+: (("default_sample_description_index" @: FieldU32) .+: (("default_sample_duration" @: FieldU32) .+: (("default_sample_size" @: FieldU32) .+: TrackExtendsDefaultSampleFlags)))
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackExtends: type TrackExtendsDefaultSampleFlags = (("reserved" @: Field 4) := 0) .+: (("is_leading" @: Field 2) .+: (("sample_depends_on" @: Field 2) .+: (("sample_is_depended_on" @: Field 2) .+: (("sample_has_redundancy" @: Field 2) .+: (("sample_padding_value" @: Field 3) .+: (("sample_is_non_sync_sample" @: Flag) .+: (("sample_degradation_priority" @: FieldU16) .+: EmptyBitRecord)))))))
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragBaseMediaDecodeTime: [TrackFragBaseMediaDecodeTime] :: TS version "track-fragment-base-media-decode-time" -> TrackFragBaseMediaDecodeTime version
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragBaseMediaDecodeTime: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox (Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragBaseMediaDecodeTime.TrackFragBaseMediaDecodeTime v)
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragBaseMediaDecodeTime: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragBaseMediaDecodeTime.TrackFragBaseMediaDecodeTime version)
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragBaseMediaDecodeTime: newtype TrackFragBaseMediaDecodeTime (version :: Nat)
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragBaseMediaDecodeTime: trackFragBaseMediaDecodeTime :: KnownNat version => TS version "track-fragment-base-media-decode-time" -> Box (FullBox (TrackFragBaseMediaDecodeTime version) version)
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragBaseMediaDecodeTime: trackFragBaseMediaDecodeTimeStaticSize64 :: Num a => a
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragment: data TrackFragment
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragment: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragment.TrackFragment
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragment: trackFragment :: Boxes ts -> Box (ContainerBox TrackFragment ts)
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragment: trackFragmentStaticSize :: Num a => a
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragmentHeader: [TrackFragmentHeader] :: Template (U32 "track_ID") 1 -> TrackFragmentHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragmentHeader: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragmentHeader.TrackFragmentHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragmentHeader: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragmentHeader.TrackFragmentHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragmentHeader: instance Data.Default.Class.Default Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragmentHeader.TrackFragmentHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragmentHeader: newtype TrackFragmentHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragmentHeader: trackFragmentHeader :: TrackFragmentHeader -> Box (FullBox TrackFragmentHeader 0)
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragmentHeader: trackFragmentHeaderStaticSize :: Num a => a
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: TrackDisabled :: TrackHeaderFlags
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: TrackEnabled :: TrackHeaderFlags
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: TrackInMovie :: TrackHeaderFlags
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: TrackInMovieAndPreview :: TrackHeaderFlags
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: data TrackHeaderFlags
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox (Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader.TrackHeader v)
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader.TrackHeader version)
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: newtype TrackHeader (version :: Nat)
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackRun: data TrackRun
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackRun: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.TrackRun.TrackRun
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackRun: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.TrackRun.TrackRun
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackRun: trackRunIso5 :: Int32 -> [(Word32, ByteString)] -> Box TrackRun
+ Data.ByteString.IsoBaseFileFormat.Boxes.VideoMediaHeader: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.VideoMediaHeader.VideoMediaHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.VideoMediaHeader: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.VideoMediaHeader.VideoMediaHeader
+ Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: [VideoSampleEntry] :: U16 "pre_defined" :+ (Constant (U16 "reserved") 0 :+ (U16 "width" :+ (U16 "height" :+ (Template (U32 "horizresolution") 4718592 :+ (Template (U32 "vertresolution") 4718592 :+ (Constant (U32 "reserved") 0 :+ (Template (U16 "frame_count") 1 :+ (FixSizeText 32 "compressorname" :+ (Template (U16 "depth") 24 :+ (Template (I16 "pre_defined") 65535 :+ (Maybe (Box CleanAperture) :+ (Maybe (Box PixelAspectRatio) :+ ([Box SomeColourInformation] :+ c))))))))))))) -> VideoSampleEntry c
+ Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: instance (GHC.TypeLits.KnownSymbol (Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.ColourTypeCode profile), Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.ColourType profile)) => Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.ColourInformation profile)
+ Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.CleanAperture
+ Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.PixelAspectRatio
+ Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.SomeColourInformation
+ Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.CleanAperture
+ Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.FullRangeFlag
+ Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.PixelAspectRatio
+ Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.SomeColourInformation
+ Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent [Data.ByteString.IsoBaseFileFormat.Box.Box Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.SomeColourInformation]
+ Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent c => Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.VideoSampleEntry c)
+ Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: instance Data.Default.Class.Default c => Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry.VideoSampleEntry c)
+ Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: newtype VideoSampleEntry c
+ Data.ByteString.IsoBaseFileFormat.Brands.Dash: dash :: Proxy (Dash 0)
+ Data.ByteString.IsoBaseFileFormat.Brands.Dash: instance Data.ByteString.IsoBaseFileFormat.MediaFile.IsMediaFileFormat * (Data.ByteString.IsoBaseFileFormat.Brands.Dash.Dash v)
+ Data.ByteString.IsoBaseFileFormat.MediaFile: class IsMediaFileFormat brand where type BoxLayout brand mediaBuilder _ t = boxBuilder t where {
+ Data.ByteString.IsoBaseFileFormat.MediaFile: mediaBuilder :: forall t proxy. (IsMediaFileFormat brand, IsBoxContent t, IsRuleConform t (BoxLayout brand) ~ True) => proxy brand -> t -> Builder
+ Data.ByteString.IsoBaseFileFormat.MediaFile: type family BoxLayout brand;
+ Data.ByteString.IsoBaseFileFormat.MediaFile: }
+ Data.ByteString.IsoBaseFileFormat.ReExports: instance Data.Default.Class.Default Data.ByteString.Internal.ByteString
+ Data.ByteString.IsoBaseFileFormat.ReExports: instance Data.Default.Class.Default Data.Text.Internal.Text
+ Data.ByteString.IsoBaseFileFormat.ReExports: instance forall k c (s :: k). Data.Default.Class.Default c => Data.Default.Class.Default (Data.Tagged.Tagged k s c)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: Scalar :: scalartype -> Scalar scalartype
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: [$sel:fromScalar:Scalar] :: Scalar scalartype -> scalartype
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: [Constant] :: Constant o v
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: [Custom] :: !o -> Template o v
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: [FixSizeText] :: Text -> FixSizeText len label
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: [ScalarArray] :: Vector o -> ScalarArray label n o
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: [Template] :: Template o v
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: [U32Text] :: Word32 -> U32Text label
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: class FromTypeLit o v
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: data Constant o v
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: data Template o v
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: fromList :: forall label n o. (KnownSymbol label, KnownNat n) => [o] -> ScalarArray label n o
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: fromTypeLit :: FromTypeLit o v => proxy o v -> o
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: i16 :: Int16 -> I16 label
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: i16Arr :: (KnownNat size, KnownSymbol label) => [Int16] -> I16Arr label size
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: i32 :: Int32 -> I32 label
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: i32Arr :: (KnownNat size, KnownSymbol label) => [Int32] -> I32Arr label size
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: i64 :: Int64 -> I64 label
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: i64Arr :: (KnownNat size, KnownSymbol label) => [Int64] -> I64Arr label size
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: i8 :: Int8 -> I8 label
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: i8Arr :: (KnownNat size, KnownSymbol label) => [Int8] -> I8Arr label size
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance (GHC.TypeLits.KnownSymbol label, Data.Singletons.SingI [GHC.Types.Nat] arr, GHC.Num.Num o, Data.Singletons.SingKind [GHC.Types.Nat], GHC.TypeLits.KnownNat len, len ~ Data.Singletons.Prelude.List.Length GHC.Types.Nat arr) => Data.ByteString.IsoBaseFileFormat.Util.BoxFields.FromTypeLit [GHC.Types.Nat] (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.ScalarArray GHC.Types.Symbol label len o) arr
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.U32Text label)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance Data.ByteString.IsoBaseFileFormat.Util.BoxFields.IsTextSize len => Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.FixSizeText len label)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance Data.ByteString.IsoBaseFileFormat.Util.BoxFields.IsTextSize len => Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.FixSizeText len label)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.U32Text label)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance Data.String.IsString (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.U32Text label)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance GHC.TypeLits.KnownSymbol str => Data.ByteString.IsoBaseFileFormat.Util.BoxFields.FromTypeLit GHC.Types.Symbol (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.U32Text label) str
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance GHC.TypeLits.KnownSymbol str => Data.ByteString.IsoBaseFileFormat.Util.BoxFields.FromTypeLit GHC.Types.Symbol Data.Text.Internal.Text str
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance forall k (label :: k) (len :: GHC.Types.Nat) o. GHC.Classes.Eq o => GHC.Classes.Eq (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.ScalarArray k label len o)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance forall k (label :: k) (len :: GHC.Types.Nat) o. GHC.Show.Show o => GHC.Show.Show (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.ScalarArray k label len o)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance forall k (label :: k). Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.Scalar k GHC.Int.Int16 label)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance forall k (label :: k). Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.Scalar k GHC.Int.Int32 label)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance forall k (label :: k). Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.Scalar k GHC.Int.Int64 label)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance forall k (label :: k). Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.Scalar k GHC.Int.Int8 label)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance forall k (label :: k). Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.Scalar k GHC.Word.Word16 label)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance forall k (label :: k). Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.Scalar k GHC.Word.Word32 label)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance forall k (label :: k). Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.Scalar k GHC.Word.Word64 label)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance forall k (label :: k). Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.Scalar k GHC.Word.Word8 label)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance forall k (scalar :: GHC.Types.Nat) o (label :: k). (GHC.TypeLits.KnownNat scalar, GHC.Num.Num o) => Data.ByteString.IsoBaseFileFormat.Util.BoxFields.FromTypeLit GHC.Types.Nat (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.Scalar k o label) scalar
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance forall k k1 (o :: k1) (v :: k). Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.Constant k k1 o v)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance forall k o (label :: k) (len :: GHC.Types.Nat). (GHC.Num.Num o, Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.Scalar k o label)) => Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.ScalarArray k label len o)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance forall k o (len :: GHC.Types.Nat) (label :: k). (Data.Default.Class.Default o, GHC.TypeLits.KnownNat len) => Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.ScalarArray k label len o)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance forall k o (v :: k). (Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent o, Data.ByteString.IsoBaseFileFormat.Util.BoxFields.FromTypeLit k o v) => Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.Constant k * o v)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance forall k o (v :: k). (Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent o, Data.ByteString.IsoBaseFileFormat.Util.BoxFields.FromTypeLit k o v) => Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.Template k o v)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance forall k o (v :: k). Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.Template k o v)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance forall scalartype k (label :: k). Data.Default.Class.Default scalartype => Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.Scalar k scalartype label)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance forall scalartype k (label :: k). GHC.Classes.Eq scalartype => GHC.Classes.Eq (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.Scalar k scalartype label)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance forall scalartype k (label :: k). GHC.Classes.Ord scalartype => GHC.Classes.Ord (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.Scalar k scalartype label)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance forall scalartype k (label :: k). GHC.Num.Num scalartype => GHC.Num.Num (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.Scalar k scalartype label)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance forall scalartype k (label :: k). GHC.Read.Read scalartype => GHC.Read.Read (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.Scalar k scalartype label)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: instance forall scalartype k (label :: k). GHC.Show.Show scalartype => GHC.Show.Show (Data.ByteString.IsoBaseFileFormat.Util.BoxFields.Scalar k scalartype label)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: newtype FixSizeText (len :: Nat) (label :: Symbol)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: newtype Scalar scalartype (label :: k)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: newtype ScalarArray (label :: k) (len :: Nat) o
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: newtype U32Text (label :: Symbol)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: relabelScalar :: Scalar t l -> Scalar t l'
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: templateValue :: FromTypeLit o v => Template o v -> o
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: type I16 label = Scalar Int16 label
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: type I16Arr label size = ScalarArray label size Int16
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: type I32 label = Scalar Int32 label
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: type I32Arr label size = ScalarArray label size Int32
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: type I64 label = Scalar Int64 label
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: type I64Arr label size = ScalarArray label size Int64
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: type I8 label = Scalar Int8 label
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: type I8Arr label size = ScalarArray label size Int8
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: type IsTextSize len = (KnownNat len, 1 <= len, len <= 255)
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: type U16 label = Scalar Word16 label
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: type U16Arr label size = ScalarArray label size Word16
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: type U32 label = Scalar Word32 label
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: type U32Arr label size = ScalarArray label size Word32
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: type U64 label = Scalar Word64 label
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: type U64Arr label size = ScalarArray label size Word64
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: type U8 label = Scalar Word8 label
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: type U8Arr label size = ScalarArray label size Word8
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: u16 :: Word16 -> U16 label
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: u16Arr :: (KnownNat size, KnownSymbol label) => [Word16] -> U16Arr label size
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: u32 :: Word32 -> U32 label
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: u32Arr :: (KnownNat size, KnownSymbol label) => [Word32] -> U32Arr label size
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: u64 :: Word64 -> U64 label
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: u64Arr :: (KnownNat size, KnownSymbol label) => [Word64] -> U64Arr label size
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: u8 :: Word8 -> U8 label
+ Data.ByteString.IsoBaseFileFormat.Util.BoxFields: u8Arr :: (KnownNat size, KnownSymbol label) => [Word8] -> U8Arr label size
+ Data.ByteString.IsoBaseFileFormat.Util.FullBox: BoxFlags :: Integer -> BoxFlags bits
+ Data.ByteString.IsoBaseFileFormat.Util.FullBox: [FullBox] :: (KnownNat version, IsBox t) => !(BoxFlags 24) -> !(BoxContent t) -> FullBox t version
+ Data.ByteString.IsoBaseFileFormat.Util.FullBox: data FullBox t (version :: Nat)
+ Data.ByteString.IsoBaseFileFormat.Util.FullBox: fullBox :: (KnownNat v, IsBox t) => BoxFlags 24 -> BoxContent t -> Box (FullBox t v)
+ Data.ByteString.IsoBaseFileFormat.Util.FullBox: instance (Data.ByteString.IsoBaseFileFormat.Box.IsBox t, GHC.TypeLits.KnownNat v) => Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Util.FullBox.FullBox t v)
+ Data.ByteString.IsoBaseFileFormat.Util.FullBox: instance (GHC.TypeLits.KnownNat v, Data.ByteString.IsoBaseFileFormat.Box.IsBox t) => Data.ByteString.IsoBaseFileFormat.Box.IsBox (Data.ByteString.IsoBaseFileFormat.Util.FullBox.FullBox t v)
+ Data.ByteString.IsoBaseFileFormat.Util.FullBox: instance (GHC.TypeLits.KnownNat version, Data.ByteString.IsoBaseFileFormat.Box.IsBox t, Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Box.BoxContent t)) => Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Util.FullBox.FullBox t version)
+ Data.ByteString.IsoBaseFileFormat.Util.FullBox: instance GHC.TypeLits.KnownNat bits => Data.Bits.Bits (Data.ByteString.IsoBaseFileFormat.Util.FullBox.BoxFlags GHC.Types.Nat bits)
+ Data.ByteString.IsoBaseFileFormat.Util.FullBox: instance GHC.TypeLits.KnownNat bits => Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Util.FullBox.BoxFlags GHC.Types.Nat bits)
+ Data.ByteString.IsoBaseFileFormat.Util.FullBox: instance forall k (bits :: k). GHC.Classes.Eq (Data.ByteString.IsoBaseFileFormat.Util.FullBox.BoxFlags k bits)
+ Data.ByteString.IsoBaseFileFormat.Util.FullBox: instance forall k (bits :: k). GHC.Num.Num (Data.ByteString.IsoBaseFileFormat.Util.FullBox.BoxFlags k bits)
+ Data.ByteString.IsoBaseFileFormat.Util.FullBox: instance forall k (bits :: k). GHC.Show.Show (Data.ByteString.IsoBaseFileFormat.Util.FullBox.BoxFlags k bits)
+ Data.ByteString.IsoBaseFileFormat.Util.FullBox: newtype BoxFlags bits
+ Data.ByteString.IsoBaseFileFormat.Util.Time: MkTicks :: Word64 -> Ticks
+ Data.ByteString.IsoBaseFileFormat.Util.Time: MkTicks32 :: Word32 -> Ticks32
+ Data.ByteString.IsoBaseFileFormat.Util.Time: TimeScale :: Word32 -> TimeScale
+ Data.ByteString.IsoBaseFileFormat.Util.Time: [TSv0] :: !Word32 -> TS 0 label
+ Data.ByteString.IsoBaseFileFormat.Util.Time: [TSv1] :: !Word64 -> TS 1 label
+ Data.ByteString.IsoBaseFileFormat.Util.Time: data TS (version :: Nat) (label :: Symbol)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: diffTimeToTicks :: Integral t => NominalDiffTime -> TimeScale -> t
+ Data.ByteString.IsoBaseFileFormat.Util.Time: durationFromSeconds :: Num t => TimeScale -> Integer -> t
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance Data.Bits.Bits (Data.ByteString.IsoBaseFileFormat.Util.Time.Ticks timeScale)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance Data.Bits.Bits (Data.ByteString.IsoBaseFileFormat.Util.Time.Ticks32 timeScale)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance Data.Bits.Bits Data.ByteString.IsoBaseFileFormat.Util.Time.TimeScale
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Util.Time.TS v n)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Util.Time.Ticks n)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Util.Time.Ticks32 n)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.IsoBaseFileFormat.Util.Time.TimeScale
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance Data.Default.Class.Default Data.ByteString.IsoBaseFileFormat.Util.Time.TimeScale
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance Foreign.Storable.Storable (Data.ByteString.IsoBaseFileFormat.Util.Time.Ticks timeScale)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance Foreign.Storable.Storable (Data.ByteString.IsoBaseFileFormat.Util.Time.Ticks32 timeScale)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance Foreign.Storable.Storable Data.ByteString.IsoBaseFileFormat.Util.Time.TimeScale
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance GHC.Classes.Eq (Data.ByteString.IsoBaseFileFormat.Util.Time.Ticks timeScale)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance GHC.Classes.Eq (Data.ByteString.IsoBaseFileFormat.Util.Time.Ticks32 timeScale)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance GHC.Classes.Eq Data.ByteString.IsoBaseFileFormat.Util.Time.TimeScale
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance GHC.Classes.Ord (Data.ByteString.IsoBaseFileFormat.Util.Time.Ticks timeScale)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance GHC.Classes.Ord (Data.ByteString.IsoBaseFileFormat.Util.Time.Ticks32 timeScale)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance GHC.Classes.Ord Data.ByteString.IsoBaseFileFormat.Util.Time.TimeScale
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance GHC.Enum.Bounded (Data.ByteString.IsoBaseFileFormat.Util.Time.Ticks timeScale)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance GHC.Enum.Bounded (Data.ByteString.IsoBaseFileFormat.Util.Time.Ticks32 timeScale)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance GHC.Enum.Bounded Data.ByteString.IsoBaseFileFormat.Util.Time.TimeScale
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance GHC.Enum.Enum (Data.ByteString.IsoBaseFileFormat.Util.Time.Ticks timeScale)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance GHC.Enum.Enum (Data.ByteString.IsoBaseFileFormat.Util.Time.Ticks32 timeScale)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance GHC.Enum.Enum Data.ByteString.IsoBaseFileFormat.Util.Time.TimeScale
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance GHC.Num.Num (Data.ByteString.IsoBaseFileFormat.Util.Time.Ticks timeScale)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance GHC.Num.Num (Data.ByteString.IsoBaseFileFormat.Util.Time.Ticks32 timeScale)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance GHC.Num.Num Data.ByteString.IsoBaseFileFormat.Util.Time.TimeScale
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance GHC.Real.Integral (Data.ByteString.IsoBaseFileFormat.Util.Time.Ticks timeScale)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance GHC.Real.Integral (Data.ByteString.IsoBaseFileFormat.Util.Time.Ticks32 timeScale)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance GHC.Real.Integral Data.ByteString.IsoBaseFileFormat.Util.Time.TimeScale
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance GHC.Real.Real (Data.ByteString.IsoBaseFileFormat.Util.Time.Ticks timeScale)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance GHC.Real.Real (Data.ByteString.IsoBaseFileFormat.Util.Time.Ticks32 timeScale)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance GHC.Real.Real Data.ByteString.IsoBaseFileFormat.Util.Time.TimeScale
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance GHC.Show.Show (Data.ByteString.IsoBaseFileFormat.Util.Time.Ticks timeScale)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance GHC.Show.Show (Data.ByteString.IsoBaseFileFormat.Util.Time.Ticks32 timeScale)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: instance GHC.Show.Show Data.ByteString.IsoBaseFileFormat.Util.Time.TimeScale
+ Data.ByteString.IsoBaseFileFormat.Util.Time: mp4CurrentTime :: Num t => IO t
+ Data.ByteString.IsoBaseFileFormat.Util.Time: newtype Ticks (timeScale :: Nat)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: newtype Ticks32 (timeScale :: Nat)
+ Data.ByteString.IsoBaseFileFormat.Util.Time: newtype TimeScale
+ Data.ByteString.IsoBaseFileFormat.Util.Time: oneSecond32 :: TimeScale -> TS32 label
+ Data.ByteString.IsoBaseFileFormat.Util.Time: oneSecond64 :: TimeScale -> TS64 label
+ Data.ByteString.IsoBaseFileFormat.Util.Time: referenceTime :: UTCTime
+ Data.ByteString.IsoBaseFileFormat.Util.Time: ticksToDiffTime :: Integral t => t -> TimeScale -> NominalDiffTime
+ Data.ByteString.IsoBaseFileFormat.Util.Time: type TS32 = Scalar Word32
+ Data.ByteString.IsoBaseFileFormat.Util.Time: type TS64 = Scalar Word64
+ Data.ByteString.IsoBaseFileFormat.Util.Time: type Timing (version :: Nat) = Versioned TimingV0 TimingV1 version
+ Data.ByteString.IsoBaseFileFormat.Util.Time: utcToMp4 :: Num t => UTCTime -> t
+ Data.ByteString.IsoBaseFileFormat.Util.Versioned: [V0] :: IsBoxContent v0 => !v0 -> Versioned v0 v1 0
+ Data.ByteString.IsoBaseFileFormat.Util.Versioned: [V1] :: IsBoxContent v1 => !v1 -> Versioned v0 v1 1
+ Data.ByteString.IsoBaseFileFormat.Util.Versioned: data Versioned v0 v1 (version :: Nat)
+ Data.ByteString.IsoBaseFileFormat.Util.Versioned: instance (version ~ 0, Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent v0, Data.Default.Class.Default v0) => Data.Default.Class.Default (Data.ByteString.IsoBaseFileFormat.Util.Versioned.Versioned v0 v1 version)
+ Data.ByteString.IsoBaseFileFormat.Util.Versioned: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.IsoBaseFileFormat.Util.Versioned.Versioned v0 v1 version)
+ Data.ByteString.Mp4.AudioStreaming: AacMp4StreamConfig :: !(TS32 "creation_time") -> !String -> !Bool -> !SamplingFreqTable -> !ChannelConfigTable -> AacMp4StreamConfig
+ Data.ByteString.Mp4.AudioStreaming: AacMp4TrackFragment :: !Word32 -> !Word64 -> ![(Word32, ByteString)] -> AacMp4TrackFragment
+ Data.ByteString.Mp4.AudioStreaming: InitSegment :: ByteString -> InitSegment
+ Data.ByteString.Mp4.AudioStreaming: Segment :: !Word32 -> !Word64 -> !ByteString -> Segment
+ Data.ByteString.Mp4.AudioStreaming: addToBaseTime :: StreamingContext -> NominalDiffTime -> StreamingContext
+ Data.ByteString.Mp4.AudioStreaming: buildAacMp4StreamInit :: AacMp4StreamConfig -> Builder
+ Data.ByteString.Mp4.AudioStreaming: buildAacMp4TrackFragment :: AacMp4TrackFragment -> Builder
+ Data.ByteString.Mp4.AudioStreaming: data AacMp4StreamConfig
+ Data.ByteString.Mp4.AudioStreaming: data AacMp4TrackFragment
+ Data.ByteString.Mp4.AudioStreaming: data Segment
+ Data.ByteString.Mp4.AudioStreaming: data StreamingContext
+ Data.ByteString.Mp4.AudioStreaming: getSegmentDuration :: StreamingContext -> NominalDiffTime
+ Data.ByteString.Mp4.AudioStreaming: getStreamBaseTime :: StreamingContext -> Word64
+ Data.ByteString.Mp4.AudioStreaming: getStreamConfig :: StreamingContext -> AacMp4StreamConfig
+ Data.ByteString.Mp4.AudioStreaming: getStreamSequence :: StreamingContext -> Word32
+ Data.ByteString.Mp4.AudioStreaming: instance GHC.Show.Show Data.ByteString.Mp4.AudioStreaming.InitSegment
+ Data.ByteString.Mp4.AudioStreaming: instance GHC.Show.Show Data.ByteString.Mp4.AudioStreaming.Segment
+ Data.ByteString.Mp4.AudioStreaming: newtype InitSegment
+ Data.ByteString.Mp4.AudioStreaming: numberOfChannels :: Num a => StreamingContext -> a
+ Data.ByteString.Mp4.AudioStreaming: streamFlush :: StreamingContext -> (Maybe Segment, StreamingContext)
+ Data.ByteString.Mp4.AudioStreaming: streamInitINTERNAL_TESTING :: String -> NominalDiffTime -> Bool -> SamplingFreqTable -> ChannelConfigTable -> IO (InitSegment, StreamingContext)
+ Data.ByteString.Mp4.AudioStreaming: streamInitUtc :: String -> UTCTime -> UTCTime -> NominalDiffTime -> Bool -> SamplingFreqTable -> ChannelConfigTable -> (InitSegment, StreamingContext)
+ Data.ByteString.Mp4.AudioStreaming: streamNextSample :: Word32 -> ByteString -> StreamingContext -> (Maybe Segment, StreamingContext)
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: AacLc :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: AacLtp :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: AacMain :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: AacScalable :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: AacSsr :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: AlgorithmicSynthesisAndAudioFx :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: AoCustom :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: AoDst :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: AoLayer1 :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: AoLayer2 :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: AoLayer3 :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: AoReserved1 :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: AoReserved2 :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: AoReserved3 :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: AoReserved4 :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: AoReserved5 :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: AotInvalid :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: Celp :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: ChannelPair :: ChannelConfigTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: ErAacLc :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: ErAacLd :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: ErAacLtp :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: ErAacScalable :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: ErBsac :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: ErCelp :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: ErHiln :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: ErHvxc :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: ErParametric :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: ErTwinVq :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: GasChannelConfig :: ChannelConfigTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: GeneralMidi :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: Hvxc :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: MainSunthetic :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: SF11025 :: SamplingFreqTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: SF12000 :: SamplingFreqTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: SF16000 :: SamplingFreqTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: SF22050 :: SamplingFreqTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: SF24000 :: SamplingFreqTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: SF32000 :: SamplingFreqTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: SF44100 :: SamplingFreqTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: SF48000 :: SamplingFreqTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: SF64000 :: SamplingFreqTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: SF7350 :: SamplingFreqTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: SF8000 :: SamplingFreqTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: SF88200 :: SamplingFreqTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: SF96000 :: SamplingFreqTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: SFCustom :: SamplingFreqTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: SFReserved1 :: SamplingFreqTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: SFReserved2 :: SamplingFreqTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: Sbr :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: SingleChannel :: ChannelConfigTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: SinglePair :: ChannelConfigTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: SinglePairPair :: ChannelConfigTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: SinglePairPairLfe :: ChannelConfigTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: SinglePairPairPairLfe :: ChannelConfigTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: SinglePairSingle :: ChannelConfigTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: Ssc :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: Ttsi :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: TwinVq :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: WavetableSynthesis :: AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: channelConfigToEnum :: ChannelConfigTable -> EnumValue ChannelConfigTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: channelConfigToNumber :: Num a => ChannelConfigTable -> a
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: data AudioConfigAacMinimal :: AudioObjectTypeId -> IsAn AudioSubConfig -> IsAn (EnumOf SamplingFreqTable) -> IsAn (EnumOf ChannelConfigTable) -> IsA (DecoderSpecificInfo AudioIso14496_3 AudioStream)
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: data AudioConfigSbrExplicitHierachical :: AudioObjectTypeId -> IsAn AudioSubConfig -> IsAn (EnumOf SamplingFreqTable) -> IsAn (EnumOf ChannelConfigTable) -> IsAn (EnumOf SamplingFreqTable) -> IsA (DecoderSpecificInfo AudioIso14496_3 AudioStream)
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: data AudioObjectTypeId
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: data AudioSubConfig :: Type
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: data ChannelConfigTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: data GASExtension
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: data GASpecificConfig (frameLenFlag :: IsA (FieldValue "frameLenFlag" Bool)) (coreCoderDelay :: Maybe (IsA (FieldValue "coreCoderDelay" Nat))) (extension :: IsA GASExtension) :: IsA AudioSubConfig
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: data MkGASExtension :: IsA GASExtension
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: data SamplingFreqTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: sampleRateToEnum :: SamplingFreqTable -> EnumValue SamplingFreqTable
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: sampleRateToNumber :: Num a => SamplingFreqTable -> a
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: type AudioConfigAacLc freq channels = AudioConfigAacMinimal AacLc DefaultGASpecificConfig freq channels
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: type AudioConfigCommon aoId samplingFrequencyIndex channels rest = ("audio-specific-config" <:> PutHex8 (FromEnum AudioObjectTypeId aoId)) #+$ (((AudioObjectTypeRec aoId :+: BitRecordOfEnum samplingFrequencyIndex) :+: BitRecordOfEnum channels) :+: rest)
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: type AudioConfigHeAac freq channels = AudioConfigSbrExplicitHierachical AacLc DefaultGASpecificConfig freq channels freq
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: type AudioObjectTypeRec n = ((If ((FromEnum AudioObjectTypeId n) <=? 30) "AudioObjectType" "ExtAudioObjectType") <:> PutHex8 (FromEnum AudioObjectTypeId n)) #+$ (AudioObjectTypeField1 (FromEnum AudioObjectTypeId n) .+: AudioObjectTypeField2 (FromEnum AudioObjectTypeId n))
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: type BitRecordOfGASExtension (x :: IsA GASExtension) = BitRecordMember (("has-gas-extension" @: Flag) := False)
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: type ChannelConfig = FixedEnum ChannelConfigTable 4
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: type DefaultGASpecificConfig = GASpecificConfig (StaticFieldValue "frameLenFlag" False) Nothing MkGASExtension
+ Data.ByteString.Mp4.Boxes.AudioSpecificConfig: type SamplingFreq = ExtEnum SamplingFreqTable 4 SFCustom (Field 24)
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [ContentClassificationDescr] :: ClassTag 64
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [ContentCreationDateDescr] :: ClassTag 71
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [ContentCreatorNameDescr] :: ClassTag 70
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [ContentIdentDescr] :: ClassTag 7
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [DecSpecificInfo] :: ClassTag 5
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [DecoderConfigDescr] :: ClassTag 4
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [DependencyMarker] :: ClassTag 104
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [DependencyPointer] :: ClassTag 103
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [ES_Descr] :: ClassTag 3
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [ES_ID_Ref] :: ClassTag 15
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [ExpandedTextualDescr] :: ClassTag 69
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [ExtDescrTag] :: forall (n :: Nat). (106 <= n, n <= 254) => ClassTag n
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [ExtSLConfigDescr] :: ClassTag 100
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [ExtensionProfileLevelDescr] :: ClassTag 19
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [IPI_DescrPointer] :: ClassTag 9
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [IPL_DescrPointerRef] :: ClassTag 18
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [IPMP_DescrPointer] :: ClassTag 10
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [IPMP_Descr] :: ClassTag 11
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [IPMP_Tool] :: ClassTag 97
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [IPMP_ToolsListDescr] :: ClassTag 96
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [InitialObjectDescr] :: ClassTag 2
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [KeyWordDescr] :: ClassTag 65
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [LanguageDescr] :: ClassTag 67
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [M4MuxBufferSizeDescr] :: ClassTag 101
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [M4MuxChannelDescr] :: ClassTag 105
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [M4MuxCodeTableDescr] :: ClassTag 99
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [M4MuxIdentDescr] :: ClassTag 102
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [M4MuxTimingDescr] :: ClassTag 98
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [MP4_IOD_] :: ClassTag 16
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [MP4_OD_] :: ClassTag 17
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [MediaTimeDescr] :: ClassTag 76
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [MkDescriptor] :: BitRecord -> Descriptor tag
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [OCICreationDateDescr] :: ClassTag 73
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [OCICreatorNameDescr] :: ClassTag 72
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [OCIDescrTag] :: forall (n :: Nat). (64 <= n, n <= 95) => ClassTag n
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [ObjectDescr] :: ClassTag 1
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [ProfileLevelIndicationIndexDescr] :: ClassTag 20
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [QoS_Descr] :: ClassTag 12
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [RatingDescr] :: ClassTag 66
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [RegistrationDescr] :: ClassTag 13
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [SLConfigDescr] :: ClassTag 6
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [SegmentDescr] :: ClassTag 75
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [ShortTextualDescr] :: ClassTag 68
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [SmpteCameraPositionDescr] :: ClassTag 74
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: [SupplContentIdentDescr] :: ClassTag 8
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: data BitRecordOfDescriptor :: IsA (Descriptor c :-> BitRecord)
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: data ClassTag (tag :: Nat)
+ Data.ByteString.Mp4.Boxes.BaseDescriptor: data Descriptor :: ClassTag n -> Type
+ Data.ByteString.Mp4.Boxes.DecoderConfigDescriptor: data DecoderConfigDescriptor (ot :: ObjectTypeIndication) (st :: StreamType) :: [IsA (DecoderSpecificInfo ot st)] -> [IsA (Descriptor ProfileLevelIndicationIndexDescr)] -> IsA (Descriptor DecoderConfigDescr)
+ Data.ByteString.Mp4.Boxes.DecoderConfigDescriptor: data ProfileLevelIndicationIndexDescriptor :: IsA (FieldValue "profileLevelIndicationIndex" Nat) -> IsA (Descriptor ProfileLevelIndicationIndexDescr)
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: AudioIso11172_3 :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: AudioIso13818_3 :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: AudioIso13818_7_LowComplexityProfile :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: AudioIso13818_7_MainProfile :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: AudioIso13818_7_ScalableSamplingRateProfile :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: AudioIso14496_3 :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: AudioStream :: StreamType
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: ClockReferenceStream :: StreamType
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: FontDataStream :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: InteractionStream :: StreamType
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: InteractionStreamObjInd :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: IpmpStream :: StreamType
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: IpmpToolStream_Iso14496_13 :: StreamType
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: Mpeg7Stream :: StreamType
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: MpegJStream :: StreamType
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: NoObjectTypeSpecified :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: ObjectContentInfoStream :: StreamType
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: ObjectDescriptorStream :: StreamType
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: SceneDescriptionStream_Iso14496_11 :: StreamType
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: StreamingTextStream :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: SynthesizedTextureStream :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: SystemsIso14496_1_Afx :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: SystemsIso14496_1_ExtendedBifs :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: SystemsIso14496_1_a :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: SystemsIso14496_1_b :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: VisualH264 :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: VisualH264ParameterSets :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: VisualIso10918_1 :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: VisualIso11172_2 :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: VisualIso13818_2_422Profile :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: VisualIso13818_2_HighProfile :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: VisualIso13818_2_MainProfile :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: VisualIso13818_2_SimpleProfile :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: VisualIso13818_2_SnrProfile :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: VisualIso13818_2_SpatialProfile :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: VisualIso14496_2 :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: VisualIso15444_1 :: ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: VisualStream :: StreamType
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: [MkDecoderSpecificInfo] :: BitRecord -> DecoderSpecificInfo o s
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: data DecoderSpecificInfo :: ObjectTypeIndication -> StreamType -> Type
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: data DescriptorOfDecoderSpecificInfo :: IsA (DecoderSpecificInfo ot st :-> Descriptor DecSpecificInfo)
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: data ObjectTypeIndication
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: data StreamType
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: type ObjectTypeIndicationEnum = FixedEnum ObjectTypeIndication 8
+ Data.ByteString.Mp4.Boxes.DecoderSpecificInfo: type StreamTypeEnum = FixedEnum StreamType 6
+ Data.ByteString.Mp4.Boxes.ElementaryStreamDescriptor: Esd :: BuilderBox -> Esd
+ Data.ByteString.Mp4.Boxes.ElementaryStreamDescriptor: data ESDescriptor :: IsA (FieldValue "esId" Nat) -> Maybe (IsA (FieldValue "depEsId" Nat)) -> Maybe (IsA (BitRecordField (MkFieldCustom :: BitField ASizedString ASizedString (urlSize :: Nat)))) -> Maybe (IsA (FieldValue "ocrEsId" Nat)) -> IsA (FieldValue "streamPrio" Nat) -> IsA (Descriptor DecoderConfigDescr) -> IsA (Descriptor SLConfigDescr) -> IsA (Descriptor ES_Descr)
+ Data.ByteString.Mp4.Boxes.ElementaryStreamDescriptor: esdBox :: forall (record :: IsA (Descriptor ES_Descr)) (rendered :: BitRecord). (BitStringBuilderHoley (Proxy rendered) EsdBox, rendered ~ (RenderEsDescr record)) => Proxy record -> ToBitStringBuilder (Proxy rendered) EsdBox
+ Data.ByteString.Mp4.Boxes.ElementaryStreamDescriptor: esdBoxHoley :: forall (record :: IsA (Descriptor ES_Descr)) r (rendered :: BitRecord). (BitStringBuilderHoley (Proxy rendered) r, rendered ~ (RenderEsDescr record)) => Proxy record -> Holey EsdBox r (ToBitStringBuilder (Proxy rendered) r)
+ Data.ByteString.Mp4.Boxes.ElementaryStreamDescriptor: instance Data.ByteString.IsoBaseFileFormat.Box.IsBox Data.ByteString.Mp4.Boxes.ElementaryStreamDescriptor.Esd
+ Data.ByteString.Mp4.Boxes.ElementaryStreamDescriptor: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.Mp4.Boxes.ElementaryStreamDescriptor.Esd
+ Data.ByteString.Mp4.Boxes.ElementaryStreamDescriptor: newtype Esd
+ Data.ByteString.Mp4.Boxes.ElementaryStreamDescriptor: type DefaultEsId = StaticFieldValue "esId" 1
+ Data.ByteString.Mp4.Boxes.ElementaryStreamDescriptor: type DefaultStreamPrio = StaticFieldValue "streamPrio" 0
+ Data.ByteString.Mp4.Boxes.ElementaryStreamDescriptor: type ESDescriptorMp4File esId decConfigDescr = ESDescriptor esId Nothing Nothing Nothing DefaultStreamPrio decConfigDescr Mp4SyncLayerDescriptor
+ Data.ByteString.Mp4.Boxes.ElementaryStreamDescriptor: type EsdBox = Box (FullBox Esd 0)
+ Data.ByteString.Mp4.Boxes.ElementaryStreamDescriptor: type RenderEsDescr (d :: IsA (Descriptor ES_Descr)) = BitRecordOfDescriptor $~ (Eval d)
+ Data.ByteString.Mp4.Boxes.Expandable: [Expandable] :: t -> Expandable t
+ Data.ByteString.Mp4.Boxes.Expandable: data StaticExpandableContent :: BitRecord -> IsA BitRecord
+ Data.ByteString.Mp4.Boxes.Expandable: expandableSizeBuilder :: BoxSize -> Builder
+ Data.ByteString.Mp4.Boxes.Expandable: expandableSizeSize :: BoxSize -> BoxSize
+ Data.ByteString.Mp4.Boxes.Expandable: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent t => Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent (Data.ByteString.Mp4.Boxes.Expandable.Expandable t)
+ Data.ByteString.Mp4.Boxes.Expandable: newtype Expandable t
+ Data.ByteString.Mp4.Boxes.Expandable: type ExpandableSizeLastChunk (s :: Nat) = (Field 1 := 0) .+. (Field 7 := s)
+ Data.ByteString.Mp4.Boxes.Expandable: type ExpandableSizeNextChunk (s :: Nat) = (Field 1 := 1) .+. (Field 7 := s)
+ Data.ByteString.Mp4.Boxes.Expandable: type StaticExpandableContentMaxBits = 32
+ Data.ByteString.Mp4.Boxes.Mp4AudioSampleEntry: AudioEsd :: EsdBox -> AudioEsd
+ Data.ByteString.Mp4.Boxes.Mp4AudioSampleEntry: aacAudioSampleEntrySimple :: Bool -> SamplingFreqTable -> ChannelConfigTable -> U16 "samplesize" -> AudioSampleEntry AudioEsd
+ Data.ByteString.Mp4.Boxes.Mp4AudioSampleEntry: audioSampleEntry :: U16 "data_reference_index" -> AudioSampleEntry AudioEsd -> Box (SampleEntry (AudioSampleEntry AudioEsd))
+ Data.ByteString.Mp4.Boxes.Mp4AudioSampleEntry: instance Data.ByteString.IsoBaseFileFormat.Box.IsBoxContent Data.ByteString.Mp4.Boxes.Mp4AudioSampleEntry.AudioEsd
+ Data.ByteString.Mp4.Boxes.Mp4AudioSampleEntry: mkAudioEsdAacLcOrHeAac :: Bool -> SamplingFreqTable -> ChannelConfigTable -> AudioEsd
+ Data.ByteString.Mp4.Boxes.Mp4AudioSampleEntry: newtype AudioEsd
+ Data.ByteString.Mp4.Boxes.Mp4AudioSampleEntry: type Mp4AacAudioDecoderConfigDescriptor cfg = DecoderConfigDescriptor AudioIso14496_3 AudioStream '[cfg] '[]
+ Data.ByteString.Mp4.Boxes.Mp4AudioSampleEntry: type Mp4AacLcEsDescriptor = ESDescriptorMp4File DefaultEsId (Mp4AacAudioDecoderConfigDescriptor (AudioConfigAacLc (EnumParam "samplingFreq" SamplingFreq) (EnumParam "channelConfig" ChannelConfig)))
+ Data.ByteString.Mp4.Boxes.Mp4AudioSampleEntry: type Mp4HeAacEsDescriptor = ESDescriptorMp4File DefaultEsId (Mp4AacAudioDecoderConfigDescriptor (AudioConfigHeAac (EnumParam "samplingFreq" SamplingFreq) (EnumParam "channelConfig" ChannelConfig)))
+ Data.ByteString.Mp4.Boxes.SyncLayerConfigDescriptor: data Mp4SyncLayerDescriptor :: IsA (Descriptor SLConfigDescr)
+ Data.Kind.Extra: [MkA] :: A foo
+ Data.Kind.Extra: data (:^>>>^:) :: IsA (good :-> better) -> IsA (better :-> best) -> IsA (IsA good :-> IsA best)
+ Data.Kind.Extra: data A :: forall foo. foo -> Type
+ Data.Kind.Extra: data Extract :: IsA (IsA x :-> x)
+ Data.Kind.Extra: data Fun1 :: (a -> IsA b) -> IsA (a :-> IsA b)
+ Data.Kind.Extra: data Fun2 :: (a -> b -> IsA c) -> IsA (a :-> IsA (b :-> IsA c))
+ Data.Kind.Extra: data Fun3 :: (a -> b -> c -> IsA d) -> IsA (a :-> IsA (b :-> IsA (c :-> IsA d)))
+ Data.Kind.Extra: data Fun4 :: (a -> b -> c -> d -> IsAn e) -> IsA (a :-> IsA (b :-> IsA (c :-> IsA (d :-> IsAn e))))
+ Data.Kind.Extra: data Id :: IsA (foo :-> foo)
+ Data.Kind.Extra: data Optional :: IsA t -> IsA (s :-> IsA t) -> IsA (Maybe s :-> IsA t)
+ Data.Kind.Extra: data Pure (f :: o) :: IsAn o
+ Data.Kind.Extra: type (^*^) (f :: IsA (foo :-> bar)) (x :: IsA foo) = f $~ (Eval x)
+ Data.Kind.Extra: type Apply f x = f $~ x
+ Data.Kind.Extra: type IsA (foo :: k) = (A foo -> Type :: Type)
+ Data.Kind.Extra: type IsAn (oo :: k) = (IsA oo :: Type)
+ Data.Kind.Extra: type Return f = Pure f
+ Data.Type.BitRecords.Arithmetic: type Div (x :: Nat) (y :: Nat) = DivImpl (x - (x `Rem` y)) y 0
+ Data.Type.BitRecords.Arithmetic: type FromBits bits = FromBits_ bits 0
+ Data.Type.BitRecords.Arithmetic: type RemPow2 x p = FromBits (TakeLastN p (ToBits x RemPow2Bits))
+ Data.Type.BitRecords.Arithmetic: type RemPow2Bits = 32
+ Data.Type.BitRecords.Arithmetic: type TakeLastN n xs = TakeLastNImplRev n xs '[]
+ Data.Type.BitRecords.Arithmetic: type ToBits x n = ToBits_ x n False
+ Data.Type.BitRecords.Assert: data (@&&) :: Assertion a -> Assertion a -> Assertion a
+ Data.Type.BitRecords.Assert: data LengthIn :: Nat -> Nat -> Assertion a
+ Data.Type.BitRecords.Assert: data NatGE :: Nat -> Assertion Nat
+ Data.Type.BitRecords.Assert: data NatIn :: Nat -> Nat -> Assertion Nat
+ Data.Type.BitRecords.Assert: data NatLE :: Nat -> Assertion Nat
+ Data.Type.BitRecords.Assert: type (?::) x cond = Assert cond x
+ Data.Type.BitRecords.Assert: type Assertion a = TyFun a (Maybe ErrorMessage) -> Type
+ Data.Type.BitRecords.Builder.BitBuffer: bitString :: Int -> Word64 -> BitString
+ Data.Type.BitRecords.Builder.BitBuffer: bitStringBuilderChunk :: Word64 -> Int -> BitStringBuilderChunk
+ Data.Type.BitRecords.Builder.BitBuffer: bitStringBuilderChunkContent :: BitStringBuilderChunk -> Word64
+ Data.Type.BitRecords.Builder.BitBuffer: bitStringBuilderChunkLength :: BitStringBuilderChunk -> Int
+ Data.Type.BitRecords.Builder.BitBuffer: bitStringBuilderChunkSpaceLeft :: BitStringBuilderChunk -> Int
+ Data.Type.BitRecords.Builder.BitBuffer: bitStringContent :: BitString -> Word64
+ Data.Type.BitRecords.Builder.BitBuffer: bitStringLength :: BitString -> Int
+ Data.Type.BitRecords.Builder.BitBuffer: bitStringMaxLength :: Num a => a
+ Data.Type.BitRecords.Builder.BitBuffer: bitStringMaxLengthBytes :: Word64
+ Data.Type.BitRecords.Builder.BitBuffer: bitStringProxyLength :: (KnownChunkSize n) => Proxy n -> Word64 -> BitString
+ Data.Type.BitRecords.Builder.BitBuffer: bitStringSpaceLeft :: BitString -> Int
+ Data.Type.BitRecords.Builder.BitBuffer: bufferBits :: BitString -> BitStringBuilderChunk -> (BitString, BitStringBuilderChunk)
+ Data.Type.BitRecords.Builder.BitBuffer: data BitString
+ Data.Type.BitRecords.Builder.BitBuffer: data BitStringBuilderChunk
+ Data.Type.BitRecords.Builder.BitBuffer: emptyBitString :: BitString
+ Data.Type.BitRecords.Builder.BitBuffer: emptyBitStringBuilderChunk :: BitStringBuilderChunk
+ Data.Type.BitRecords.Builder.BitBuffer: isBitStringBuilderChunkEmpty :: BitStringBuilderChunk -> Bool
+ Data.Type.BitRecords.Builder.BitBuffer: isBitStringEmpty :: BitString -> Bool
+ Data.Type.BitRecords.Builder.BitBuffer: type BitStringMaxLength = 64
+ Data.Type.BitRecords.Builder.Holey: HM :: ((m -> r) -> a) -> Holey m r a
+ Data.Type.BitRecords.Builder.Holey: [$sel:runHM:HM] :: Holey m r a -> (m -> r) -> a
+ Data.Type.BitRecords.Builder.Holey: applyHoley :: Holey m r (a -> b) -> a -> Holey m r b
+ Data.Type.BitRecords.Builder.Holey: bind :: Holey m b c -> (m -> Holey n a b) -> Holey n a c
+ Data.Type.BitRecords.Builder.Holey: hoistM :: (m -> n) -> Holey m a b -> Holey n a b
+ Data.Type.BitRecords.Builder.Holey: hoistR :: (s -> r) -> Holey m r a -> Holey m s a
+ Data.Type.BitRecords.Builder.Holey: immediate :: m -> Holey m r r
+ Data.Type.BitRecords.Builder.Holey: indirect :: (a -> m) -> Holey m r (a -> r)
+ Data.Type.BitRecords.Builder.Holey: instance GHC.Base.Monoid m => Control.Category.Category * (Data.Type.BitRecords.Builder.Holey.Holey m)
+ Data.Type.BitRecords.Builder.Holey: instance GHC.Base.Monoid m => GHC.Base.Monoid (Data.Type.BitRecords.Builder.Holey.Holey m r r)
+ Data.Type.BitRecords.Builder.Holey: mapHoley :: (a -> b) -> Holey m r a -> Holey m r b
+ Data.Type.BitRecords.Builder.Holey: newtype Holey m r a
+ Data.Type.BitRecords.Builder.Holey: runHoley :: Holey m m a -> a
+ Data.Type.BitRecords.Builder.Holey: taggedHoley :: forall tag m r a x. Holey m r (a -> x) -> Holey m r (Tagged tag a -> x)
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: BitStringBuilder :: Dual (Endo BitStringBuilderState) -> BitStringBuilder
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: [$sel:unBitStringBuilder:BitStringBuilder] :: BitStringBuilder -> Dual (Endo BitStringBuilderState)
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: [BitStringBuilderState] :: !Builder -> !BitStringBuilderChunk -> !Word64 -> BitStringBuilderState
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: [MkBuilderBox] :: !Word64 -> !Builder -> BuilderBox
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: appBitStringBuilder :: BitStringBuilder -> BitStringBuilderState -> BitStringBuilderState
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: appendBitString :: BitString -> BitStringBuilder
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: appendStrictByteString :: ByteString -> BitStringBuilder
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: bitBuilderBox :: forall (record :: BitRecord). BitStringBuilderHoley (Proxy record) BuilderBox => Proxy record -> ToBitStringBuilder (Proxy record) BuilderBox
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: bitBuilderBoxHoley :: forall (record :: BitRecord) r. BitStringBuilderHoley (Proxy record) r => Proxy record -> Holey BuilderBox r (ToBitStringBuilder (Proxy record) r)
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: bitStringBuilder :: (BitStringBuilderState -> BitStringBuilderState) -> BitStringBuilder
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: bitStringBuilderHoley :: BitStringBuilderHoley a r => a -> Holey BitStringBuilder r (ToBitStringBuilder a r)
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: bitStringPrinter :: BitStringBuilderHoley a String => a -> ToBitStringBuilder a String
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: class BitStringBuilderHoley a r where type ToBitStringBuilder a r type ToBitStringBuilder a r = r where {
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: data BitStringBuilderState
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: data BuilderBox
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: flushBitStringBuilder :: BitStringBuilderState -> BitStringBuilderState
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: getBitStringBuilderStateBuilder :: BitStringBuilderState -> Builder
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: initialBitStringBuilderState :: BitStringBuilderState
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: instance (Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy Data.Type.BitRecords.Core.BitRecord l) (Data.Type.BitRecords.Builder.LazyByteStringBuilder.ToBitStringBuilder (Data.Proxy.Proxy Data.Type.BitRecords.Core.BitRecord r) a), Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy Data.Type.BitRecords.Core.BitRecord r) a) => Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy Data.Type.BitRecords.Core.BitRecord ('Data.Type.BitRecords.Core.BitRecordAppend l r)) a
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: instance Data.Type.BitRecords.Builder.BitBuffer.KnownChunkSize s => Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy (Data.Kind.Extra.A GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField (Data.Type.BitRecords.Core.B s) * GHC.Types.Nat s ('Data.Type.BitRecords.Core.MkFieldBits s)) -> GHC.Types.Type) (Data.Type.BitRecords.Core.MkField (Data.Type.BitRecords.Core.B s) * GHC.Types.Nat s ('Data.Type.BitRecords.Core.MkFieldBits s))) a
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: instance Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy (Data.Kind.Extra.A GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField GHC.Int.Int16 * Data.Type.BitRecords.Core.SignedNat 16 'Data.Type.BitRecords.Core.MkFieldI16) -> GHC.Types.Type) (Data.Type.BitRecords.Core.MkField GHC.Int.Int16 * Data.Type.BitRecords.Core.SignedNat 16 'Data.Type.BitRecords.Core.MkFieldI16)) a
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: instance Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy (Data.Kind.Extra.A GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField GHC.Int.Int32 * Data.Type.BitRecords.Core.SignedNat 32 'Data.Type.BitRecords.Core.MkFieldI32) -> GHC.Types.Type) (Data.Type.BitRecords.Core.MkField GHC.Int.Int32 * Data.Type.BitRecords.Core.SignedNat 32 'Data.Type.BitRecords.Core.MkFieldI32)) a
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: instance Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy (Data.Kind.Extra.A GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField GHC.Int.Int64 * Data.Type.BitRecords.Core.SignedNat 64 'Data.Type.BitRecords.Core.MkFieldI64) -> GHC.Types.Type) (Data.Type.BitRecords.Core.MkField GHC.Int.Int64 * Data.Type.BitRecords.Core.SignedNat 64 'Data.Type.BitRecords.Core.MkFieldI64)) a
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: instance Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy (Data.Kind.Extra.A GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField GHC.Int.Int8 * Data.Type.BitRecords.Core.SignedNat 8 'Data.Type.BitRecords.Core.MkFieldI8) -> GHC.Types.Type) (Data.Type.BitRecords.Core.MkField GHC.Int.Int8 * Data.Type.BitRecords.Core.SignedNat 8 'Data.Type.BitRecords.Core.MkFieldI8)) a
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: instance Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy (Data.Kind.Extra.A GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField GHC.Types.Bool * GHC.Types.Bool 1 'Data.Type.BitRecords.Core.MkFieldFlag) -> GHC.Types.Type) (Data.Type.BitRecords.Core.MkField GHC.Types.Bool * GHC.Types.Bool 1 'Data.Type.BitRecords.Core.MkFieldFlag)) a
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: instance Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy (Data.Kind.Extra.A GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField GHC.Word.Word16 * GHC.Types.Nat 16 'Data.Type.BitRecords.Core.MkFieldU16) -> GHC.Types.Type) (Data.Type.BitRecords.Core.MkField GHC.Word.Word16 * GHC.Types.Nat 16 'Data.Type.BitRecords.Core.MkFieldU16)) a
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: instance Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy (Data.Kind.Extra.A GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField GHC.Word.Word32 * GHC.Types.Nat 32 'Data.Type.BitRecords.Core.MkFieldU32) -> GHC.Types.Type) (Data.Type.BitRecords.Core.MkField GHC.Word.Word32 * GHC.Types.Nat 32 'Data.Type.BitRecords.Core.MkFieldU32)) a
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: instance Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy (Data.Kind.Extra.A GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField GHC.Word.Word64 * GHC.Types.Nat 64 'Data.Type.BitRecords.Core.MkFieldU64) -> GHC.Types.Type) (Data.Type.BitRecords.Core.MkField GHC.Word.Word64 * GHC.Types.Nat 64 'Data.Type.BitRecords.Core.MkFieldU64)) a
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: instance Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy (Data.Kind.Extra.A GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField GHC.Word.Word8 * GHC.Types.Nat 8 'Data.Type.BitRecords.Core.MkFieldU8) -> GHC.Types.Type) (Data.Type.BitRecords.Core.MkField GHC.Word.Word8 * GHC.Types.Nat 8 'Data.Type.BitRecords.Core.MkFieldU8)) a
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: instance Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy Data.Type.BitRecords.Core.BitRecord 'Data.Type.BitRecords.Core.EmptyBitRecord) a
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: instance Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy Data.Type.BitRecords.Core.BitRecord ('Data.Type.BitRecords.Core.BitRecordDoc d)) a
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: instance Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy Data.Type.BitRecords.Core.BitRecord (Data.Kind.Extra.Eval Data.Type.BitRecords.Core.BitRecord r)) a => Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy (Data.Kind.Extra.IsA * Data.Type.BitRecords.Core.BitRecord) r) a
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: instance Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy Data.Type.BitRecords.Core.BitRecord r) a => Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy Data.Type.BitRecords.Core.BitRecord ('Data.Type.BitRecords.Core.BitRecordDocNested d r)) a
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: instance Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley Data.Type.BitRecords.Builder.BitBuffer.BitString r
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: instance GHC.Base.Monoid Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilder
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: instance GHC.Base.Monoid Data.Type.BitRecords.Builder.LazyByteStringBuilder.BuilderBox
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: instance forall rt (len :: GHC.Types.Nat) (t :: Data.Type.BitRecords.Core.BitField * rt GHC.Types.Nat len) (f :: Data.Kind.Extra.IsA GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField rt * GHC.Types.Nat len t)) (v :: GHC.Types.Nat) a. (GHC.TypeLits.KnownNat v, Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy (Data.Kind.Extra.IsA GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField rt * GHC.Types.Nat len t)) f) a, Data.Type.BitRecords.Builder.LazyByteStringBuilder.ToBitStringBuilder (Data.Proxy.Proxy (Data.Kind.Extra.IsA GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField rt * GHC.Types.Nat len t)) f) a ~ (rt -> a), GHC.Num.Num rt) => Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy (Data.Kind.Extra.A GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField rt * GHC.Types.Nat len t) -> GHC.Types.Type) ((Data.Type.BitRecords.Core.:=) rt len GHC.Types.Nat t f v)) a
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: instance forall rt (size :: GHC.Types.Nat) (t :: Data.Type.BitRecords.Core.BitField * rt Data.Type.BitRecords.Core.SignedNat size) (v :: GHC.Types.Nat) (f :: Data.Kind.Extra.IsA GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField rt * Data.Type.BitRecords.Core.SignedNat size t)) a x. (GHC.TypeLits.KnownNat v, Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy (Data.Kind.Extra.IsA GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField rt * Data.Type.BitRecords.Core.SignedNat size t)) f) a, Data.Type.BitRecords.Builder.LazyByteStringBuilder.ToBitStringBuilder (Data.Proxy.Proxy (Data.Kind.Extra.IsA GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField rt * Data.Type.BitRecords.Core.SignedNat size t)) f) a ~ (x -> a), GHC.Num.Num x) => Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy (Data.Kind.Extra.A GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField rt * Data.Type.BitRecords.Core.SignedNat size t) -> GHC.Types.Type) ((Data.Type.BitRecords.Core.:=) rt size Data.Type.BitRecords.Core.SignedNat t f ('Data.Type.BitRecords.Core.NegativeNat v))) a
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: instance forall rt (size :: GHC.Types.Nat) (t :: Data.Type.BitRecords.Core.BitField * rt Data.Type.BitRecords.Core.SignedNat size) (v :: GHC.Types.Nat) (f :: Data.Kind.Extra.IsA GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField rt * Data.Type.BitRecords.Core.SignedNat size t)) a x. (GHC.TypeLits.KnownNat v, Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy (Data.Kind.Extra.IsA GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField rt * Data.Type.BitRecords.Core.SignedNat size t)) f) a, Data.Type.BitRecords.Builder.LazyByteStringBuilder.ToBitStringBuilder (Data.Proxy.Proxy (Data.Kind.Extra.IsA GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField rt * Data.Type.BitRecords.Core.SignedNat size t)) f) a ~ (x -> a), GHC.Num.Num x) => Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy (Data.Kind.Extra.A GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField rt * Data.Type.BitRecords.Core.SignedNat size t) -> GHC.Types.Type) ((Data.Type.BitRecords.Core.:=) rt size Data.Type.BitRecords.Core.SignedNat t f ('Data.Type.BitRecords.Core.PositiveNat v))) a
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: instance forall rt (size :: GHC.Types.Nat) (t :: Data.Type.BitRecords.Core.BitField * rt GHC.Types.Bool size) (f :: Data.Kind.Extra.IsA GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField rt * GHC.Types.Bool size t)) a. Data.Type.BitRecords.Core.BitRecordFieldSize rt * GHC.Types.Bool size t f ~ 1 => Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy (Data.Kind.Extra.A GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField rt * GHC.Types.Bool size t) -> GHC.Types.Type) ((Data.Type.BitRecords.Core.:=) rt size GHC.Types.Bool t f 'GHC.Types.False)) a
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: instance forall rt (size :: GHC.Types.Nat) (t :: Data.Type.BitRecords.Core.BitField * rt GHC.Types.Bool size) (f :: Data.Kind.Extra.IsA GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField rt * GHC.Types.Bool size t)) a. Data.Type.BitRecords.Core.BitRecordFieldSize rt * GHC.Types.Bool size t f ~ 1 => Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy (Data.Kind.Extra.A GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField rt * GHC.Types.Bool size t) -> GHC.Types.Type) ((Data.Type.BitRecords.Core.:=) rt size GHC.Types.Bool t f 'GHC.Types.True)) a
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: instance forall rt k (st :: k) (len :: GHC.Types.Nat) (t :: Data.Type.BitRecords.Core.BitField k rt st len) (f :: Data.Kind.Extra.IsA GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField rt k st len t)) a. Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy (Data.Kind.Extra.IsA GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField rt k st len t)) f) a => Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy Data.Type.BitRecords.Core.BitRecord ('Data.Type.BitRecords.Core.BitRecordMember rt k st len t f)) a
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: instance forall rt k (st :: k) (len :: GHC.Types.Nat) (t :: Data.Type.BitRecords.Core.BitField k rt st len) (nested :: Data.Kind.Extra.IsA GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField rt k st len t)) (l :: GHC.Types.Symbol) a. Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy (Data.Kind.Extra.IsA GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField rt k st len t)) nested) a => Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy (Data.Kind.Extra.A GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField rt k st len t) -> GHC.Types.Type) (Data.Type.BitRecords.Core.LabelF rt k st len t l nested)) a
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: newtype BitStringBuilder
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: printBuilder :: Builder -> String
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: runBitStringBuilder :: BitStringBuilder -> Builder
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: runBitStringBuilderHoley :: Holey BitStringBuilder Builder a -> a
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: type ToBitStringBuilder a r = r;
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: type family ToBitStringBuilder a r;
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: wrapBitBuilderBox :: forall (record :: BitRecord) wrapped. BitStringBuilderHoley (Proxy record) wrapped => (BuilderBox -> wrapped) -> Proxy record -> ToBitStringBuilder (Proxy record) wrapped
+ Data.Type.BitRecords.Builder.LazyByteStringBuilder: }
+ Data.Type.BitRecords.Core: B :: Word64 -> B
+ Data.Type.BitRecords.Core: [$sel:unB:B] :: B -> Word64
+ Data.Type.BitRecords.Core: [BitRecordAppend] :: BitRecord -> BitRecord -> BitRecord
+ Data.Type.BitRecords.Core: [BitRecordDocNested] :: PrettyType -> BitRecord -> BitRecord
+ Data.Type.BitRecords.Core: [BitRecordDoc] :: PrettyType -> BitRecord
+ Data.Type.BitRecords.Core: [BitRecordMember] :: IsA (BitRecordField t) -> BitRecord
+ Data.Type.BitRecords.Core: [EmptyBitRecord] :: BitRecord
+ Data.Type.BitRecords.Core: [MkFieldBitsXXL] :: forall (n :: Nat). BitField Integer Nat n
+ Data.Type.BitRecords.Core: [MkFieldBits] :: forall (n :: Nat). BitField (B n) Nat n
+ Data.Type.BitRecords.Core: [MkFieldCustom] :: BitField rt st n
+ Data.Type.BitRecords.Core: [MkFieldFlag] :: BitField Bool Bool 1
+ Data.Type.BitRecords.Core: [MkFieldI16] :: BitField Int16 SignedNat 16
+ Data.Type.BitRecords.Core: [MkFieldI32] :: BitField Int32 SignedNat 32
+ Data.Type.BitRecords.Core: [MkFieldI64] :: BitField Int64 SignedNat 64
+ Data.Type.BitRecords.Core: [MkFieldI8] :: BitField Int8 SignedNat 8
+ Data.Type.BitRecords.Core: [MkFieldU16] :: BitField Word16 Nat 16
+ Data.Type.BitRecords.Core: [MkFieldU32] :: BitField Word32 Nat 32
+ Data.Type.BitRecords.Core: [MkFieldU64] :: BitField Word64 Nat 64
+ Data.Type.BitRecords.Core: [MkFieldU8] :: BitField Word8 Nat 8
+ Data.Type.BitRecords.Core: [NegativeNat] :: Nat -> SignedNat
+ Data.Type.BitRecords.Core: [PositiveNat] :: Nat -> SignedNat
+ Data.Type.BitRecords.Core: data (:=) :: forall st (t :: BitField rt st size). IsA (BitRecordField t) -> st -> IsA (BitRecordField t)
+ Data.Type.BitRecords.Core: data BitField (runtimeRep :: Type) (staticRep :: k) (bitCount :: Nat)
+ Data.Type.BitRecords.Core: data BitRecord
+ Data.Type.BitRecords.Core: data BitRecordAppendFun_ :: BitRecord -> IsA (BitRecord :-> BitRecord)
+ Data.Type.BitRecords.Core: data BitRecordField :: BitField rt st len -> Type
+ Data.Type.BitRecords.Core: data BitRecordOfList (f :: IsA (foo :-> BitRecord)) (xs :: [foo]) :: IsA BitRecord
+ Data.Type.BitRecords.Core: data FieldValue :: Symbol -> staticRep -> Type
+ Data.Type.BitRecords.Core: data LabelF :: Symbol -> IsA (BitRecordField t) -> IsA (BitRecordField t)
+ Data.Type.BitRecords.Core: data MaybeField :: Maybe (IsA (BitRecordField t)) -> IsA BitRecord
+ Data.Type.BitRecords.Core: data MkField t :: IsA (BitRecordField t)
+ Data.Type.BitRecords.Core: data OptionalRecord :: Maybe BitRecord -> IsA BitRecord
+ Data.Type.BitRecords.Core: data RecArray :: BitRecord -> Nat -> IsA BitRecord
+ Data.Type.BitRecords.Core: data RecordField :: IsA (BitRecordField t) -> IsA BitRecord
+ Data.Type.BitRecords.Core: data RuntimeFieldValue (label :: Symbol) :: IsA (FieldValue label staticRep)
+ Data.Type.BitRecords.Core: data SignedNat
+ Data.Type.BitRecords.Core: data StaticFieldValue (label :: Symbol) :: staticRep -> IsA (FieldValue label staticRep)
+ Data.Type.BitRecords.Core: getRecordSizeFromProxy :: forall px (rec :: BitRecord). KnownNat (BitRecordSize rec) => px rec -> Integer
+ Data.Type.BitRecords.Core: instance (Text.Printf.PrintfArg GHC.Word.Word64, n GHC.TypeLits.<= 64) => Text.Printf.PrintfArg (Data.Type.BitRecords.Core.B n)
+ Data.Type.BitRecords.Core: instance Data.Bits.Bits (Data.Type.BitRecords.Core.B size)
+ Data.Type.BitRecords.Core: instance Data.Bits.FiniteBits (Data.Type.BitRecords.Core.B size)
+ Data.Type.BitRecords.Core: instance GHC.Classes.Eq (Data.Type.BitRecords.Core.B size)
+ Data.Type.BitRecords.Core: instance GHC.Classes.Ord (Data.Type.BitRecords.Core.B size)
+ Data.Type.BitRecords.Core: instance GHC.Enum.Bounded (Data.Type.BitRecords.Core.B size)
+ Data.Type.BitRecords.Core: instance GHC.Enum.Enum (Data.Type.BitRecords.Core.B size)
+ Data.Type.BitRecords.Core: instance GHC.Num.Num (Data.Type.BitRecords.Core.B size)
+ Data.Type.BitRecords.Core: instance GHC.Read.Read (Data.Type.BitRecords.Core.B size)
+ Data.Type.BitRecords.Core: instance GHC.Real.Integral (Data.Type.BitRecords.Core.B size)
+ Data.Type.BitRecords.Core: instance GHC.Real.Real (Data.Type.BitRecords.Core.B size)
+ Data.Type.BitRecords.Core: instance GHC.Show.Show (Data.Type.BitRecords.Core.B size)
+ Data.Type.BitRecords.Core: newtype B (size :: Nat)
+ Data.Type.BitRecords.Core: showARecord :: forall proxy (rec :: IsA BitRecord). PrettyTypeShow (PrettyRecord (Eval rec)) => proxy rec -> String
+ Data.Type.BitRecords.Core: showRecord :: forall proxy (rec :: BitRecord). PrettyTypeShow (PrettyRecord rec) => proxy rec -> String
+ Data.Type.BitRecords.Core: type (@:) (l :: Symbol) (f :: IsA (BitRecordField (t :: BitField rt (st :: stk) size))) = (LabelF l f :: IsA (BitRecordField t))
+ Data.Type.BitRecords.Core: type BitRecordAppendFun = Fun1 BitRecordAppendFun_
+ Data.Type.BitRecords.Core: type Field n = MkField (MkFieldBits :: BitField (B n) Nat n)
+ Data.Type.BitRecords.Core: type FieldI16 = MkField MkFieldI16
+ Data.Type.BitRecords.Core: type FieldI32 = MkField MkFieldI32
+ Data.Type.BitRecords.Core: type FieldI64 = MkField MkFieldI64
+ Data.Type.BitRecords.Core: type FieldI8 = MkField MkFieldI8
+ Data.Type.BitRecords.Core: type FieldU16 = MkField MkFieldU16
+ Data.Type.BitRecords.Core: type FieldU32 = MkField MkFieldU32
+ Data.Type.BitRecords.Core: type FieldU64 = MkField MkFieldU64
+ Data.Type.BitRecords.Core: type FieldU8 = MkField MkFieldU8
+ Data.Type.BitRecords.Core: type Flag = MkField MkFieldFlag
+ Data.Type.BitRecords.Core: type OptionalRecordOf (f :: IsA (s :-> IsA BitRecord)) (x :: Maybe s) = (Optional (Pure EmptyBitRecord) f $~ x :: IsA BitRecord)
+ Data.Type.BitRecords.Enum: [MkEnumOf] :: IsAn (EnumField enum size) -> IsA (FieldValue label enum) -> BitRecord -> EnumOf enum
+ Data.Type.BitRecords.Enum: [MkEnumValue] :: KnownNat (FromEnum e v) => Proxy (v :: e) -> EnumValue e
+ Data.Type.BitRecords.Enum: data EnumField (enum :: Type) (size :: Nat)
+ Data.Type.BitRecords.Enum: data EnumOf enum
+ Data.Type.BitRecords.Enum: data EnumParam (label :: Symbol) (ef :: IsAn (EnumField (enum :: Type) (size :: Nat))) :: IsAn (EnumOf enum)
+ Data.Type.BitRecords.Enum: data EnumParamAlt (label :: Symbol) (ef :: IsAn (EnumField (enum :: Type) (size :: Nat))) :: IsAn (EnumOf enum)
+ Data.Type.BitRecords.Enum: data EnumValue e
+ Data.Type.BitRecords.Enum: data ExtEnum (enum :: Type) (size :: Nat) (extInd :: enum) (extField :: IsA (BitRecordField (t :: BitField rt0 (st0 :: k0) len0))) :: IsAn (EnumField enum size)
+ Data.Type.BitRecords.Enum: data FixedEnum (enum :: Type) (size :: Nat) :: IsAn (EnumField enum size)
+ Data.Type.BitRecords.Enum: data SetEnum (l :: Symbol) (ef :: IsAn (EnumField enum size)) (v :: enum) :: IsAn (EnumOf enum)
+ Data.Type.BitRecords.Enum: data SetEnumAlt (l :: Symbol) (ef :: IsAn (EnumField (enum :: Type) (size :: Nat))) (v :: k) :: IsAn (EnumOf enum)
+ Data.Type.BitRecords.Enum: enumValueProxy :: KnownNat (FromEnum e v) => Proxy (v :: e) -> EnumValue e
+ Data.Type.BitRecords.Enum: fromEnumValue :: EnumValue e -> Word64
+ Data.Type.BitRecords.Enum: instance Data.Type.BitRecords.Builder.BitBuffer.KnownChunkSize size => Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy (Data.Kind.Extra.A GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField (Data.Type.BitRecords.Enum.EnumValue e) * e size ('Data.Type.BitRecords.Core.MkFieldCustom * (Data.Type.BitRecords.Enum.EnumValue e) e size)) -> GHC.Types.Type) (Data.Type.BitRecords.Core.MkField (Data.Type.BitRecords.Enum.EnumValue e) * e size ('Data.Type.BitRecords.Core.MkFieldCustom * (Data.Type.BitRecords.Enum.EnumValue e) e size))) r
+ Data.Type.BitRecords.Enum: instance forall (size :: GHC.Types.Nat) r e (v :: e) (f :: Data.Kind.Extra.IsA GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField (Data.Type.BitRecords.Enum.EnumValue e) * e size ('Data.Type.BitRecords.Core.MkFieldCustom * (Data.Type.BitRecords.Enum.EnumValue e) e size))). (GHC.TypeLits.KnownNat (Data.Type.BitRecords.Enum.FromEnum e v), Data.Type.BitRecords.Builder.BitBuffer.KnownChunkSize size) => Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy (Data.Kind.Extra.A GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField (Data.Type.BitRecords.Enum.EnumValue e) * e size ('Data.Type.BitRecords.Core.MkFieldCustom * (Data.Type.BitRecords.Enum.EnumValue e) e size)) -> GHC.Types.Type) ((Data.Type.BitRecords.Core.:=) (Data.Type.BitRecords.Enum.EnumValue e) size e ('Data.Type.BitRecords.Core.MkFieldCustom * (Data.Type.BitRecords.Enum.EnumValue e) e size) f v)) r
+ Data.Type.BitRecords.Enum: type BitRecordFieldOfEnumField (x :: IsA (EnumField e s)) = MkField (MkFieldCustom :: BitField (EnumValue e) e s)
+ Data.Type.BitRecords.Enum: type BitRecordOfEnum (e :: IsAn (EnumOf enum)) = (RenderEnumOf (Eval e) :: BitRecord)
+ Data.Type.BitRecords.Sized: data Sized (sf :: IsA (BitRecordField (t :: BitField (rt :: Type) Nat (size :: Nat)))) (r :: BitRecord) :: IsA BitRecord
+ Data.Type.BitRecords.Sized: data SizedField (sf :: IsA (BitRecordField (t :: BitField (rt :: Type) Nat (size :: Nat)))) (r :: IsA (BitRecordField (u :: BitField (rt' :: Type) (st' :: k0) (len0 :: Nat)))) :: IsA BitRecord
+ Data.Type.BitRecords.Sized: type Sized16 t = Sized FieldU16 t
+ Data.Type.BitRecords.Sized: type Sized32 t = Sized FieldU32 t
+ Data.Type.BitRecords.Sized: type Sized64 t = Sized FieldU64 t
+ Data.Type.BitRecords.Sized: type Sized8 t = Sized FieldU8 t
+ Data.Type.BitRecords.Sized: type SizedField16 t = SizedField FieldU16 t
+ Data.Type.BitRecords.Sized: type SizedField32 t = SizedField FieldU32 t
+ Data.Type.BitRecords.Sized: type SizedField64 t = SizedField FieldU64 t
+ Data.Type.BitRecords.Sized: type SizedField8 t = SizedField FieldU8 t
+ Data.Type.BitRecords.SizedString: data ASizedString
+ Data.Type.BitRecords.SizedString: instance forall (size :: GHC.Types.Nat) (str :: GHC.Types.Symbol) (bytes :: GHC.Types.Nat) r (f :: Data.Kind.Extra.IsA GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField Data.Type.BitRecords.SizedString.ASizedString * Data.Type.BitRecords.SizedString.ASizedString size ('Data.Type.BitRecords.Core.MkFieldCustom * Data.Type.BitRecords.SizedString.ASizedString Data.Type.BitRecords.SizedString.ASizedString size))). GHC.TypeLits.KnownSymbol str => Data.Type.BitRecords.Builder.LazyByteStringBuilder.BitStringBuilderHoley (Data.Proxy.Proxy (Data.Kind.Extra.A GHC.Types.Type (Data.Type.BitRecords.Core.BitRecordField Data.Type.BitRecords.SizedString.ASizedString * Data.Type.BitRecords.SizedString.ASizedString size ('Data.Type.BitRecords.Core.MkFieldCustom * Data.Type.BitRecords.SizedString.ASizedString Data.Type.BitRecords.SizedString.ASizedString size)) -> GHC.Types.Type) ((Data.Type.BitRecords.Core.:=) Data.Type.BitRecords.SizedString.ASizedString size Data.Type.BitRecords.SizedString.ASizedString ('Data.Type.BitRecords.Core.MkFieldCustom * Data.Type.BitRecords.SizedString.ASizedString Data.Type.BitRecords.SizedString.ASizedString size) f ('Data.Type.BitRecords.SizedString.MkASizedString str bytes))) r
+ Data.Type.BitRecords.SizedString: type SizedString str bytes = MkField (MkFieldCustom :: BitField ASizedString ASizedString (8 * bytes)) := MkASizedString str bytes
+ Data.Type.BitRecords.SizedString: utf8 :: QuasiQuoter
- Data.ByteString.IsoBaseFileFormat.Boxes.FileType: FileType :: FourCc -> Word32 -> [FourCc] -> FileType
+ Data.ByteString.IsoBaseFileFormat.Boxes.FileType: FileType :: !FourCc -> !Word32 -> ![FourCc] -> FileType
- Data.ByteString.IsoBaseFileFormat.Boxes.MediaHeader: [MediaHeader] :: KnownNat v => Timing v :+ (Language :+ Constant (I16 "pre_defined") 0) -> MediaHeader v
+ Data.ByteString.IsoBaseFileFormat.Boxes.MediaHeader: [MediaHeader] :: Timing v :+ (Language :+ Constant (I16 "pre_defined") 0) -> MediaHeader v
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader: [MovieHeader] :: KnownNat version => Timing version :+ (Template (I32 "rate") 65536 :+ (Template (I16 "volume") 256 :+ (Constant (I16 "reserved") 0 :+ (Constant (I32Arr "reserved" 2) '[0, 0] :+ (Template (I32Arr "matrix" 9) '[65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824] :+ (Template (U32Arr "pre_defined" 6) '[0, 0, 0, 0, 0, 0] :+ Template (U32 "next_track_ID") 4294967295)))))) -> MovieHeader version
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader: [MovieHeader] :: Timing version :+ (Template (I32 "rate") 65536 :+ (Template (I16 "volume") 256 :+ (Constant (I16 "reserved") 0 :+ (Constant (I32Arr "reserved" 2) '[0, 0] :+ (Template (I32Arr "matrix" 9) '[65536, 0, 0, 0, 65536, 0, 0, 0, 1073741824] :+ (Template (U32Arr "pre_defined" 6) '[0, 0, 0, 0, 0, 0] :+ Template (U32 "next_track_ID") 4294967295)))))) -> MovieHeader version
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader: type MovieHeaderTimes uint = uint "creation_time" :+ (uint "modification_time" :+ (TimeScale :+ uint "duration"))
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader: type MovieHeaderTimes uint dur = uint "creation_time" :+ (uint "modification_time" :+ (TimeScale :+ dur))
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader: type MovieHeaderTimesV0 = MovieHeaderTimes (Scalar Word32)
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader: type MovieHeaderTimesV0 = MovieHeaderTimes (Scalar Word32) (Template (U32 "duration") 4294967295)
- Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader: type MovieHeaderTimesV1 = MovieHeaderTimes (Scalar Word64)
+ Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader: type MovieHeaderTimesV1 = MovieHeaderTimes (Scalar Word64) (Template (U64 "duration") 18446744073709551615)
- Data.ByteString.IsoBaseFileFormat.Boxes.SampleDescription: SampleDescription :: (U32 "entry_count") -> SampleDescription handlerType
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleDescription: SampleDescription :: (U32 "entry_count") -> SampleDescription
- Data.ByteString.IsoBaseFileFormat.Boxes.SampleDescription: newtype SampleDescription handlerType
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleDescription: newtype SampleDescription
- Data.ByteString.IsoBaseFileFormat.Boxes.SampleDescription: sampleDescription :: (KnownNat (Length ts)) => Boxes ts -> Box (ContainerBox (FullBox (SampleDescription h) 0) ts)
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleDescription: sampleDescription :: (KnownNat (Length ts)) => Boxes ts -> Box (ContainerBox (FullBox SampleDescription 0) ts)
- Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry: data MatchSampleEntry (handlerType :: HandlerType)
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry: data MatchSampleEntry :: HandlerType -> Type
- Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry: sampleEntry :: forall (handlertype :: HandlerType) (format :: k). U16 "data_reference_index" -> SampleEntry handlertype format -> Box (SampleEntry handlertype format)
+ Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry: sampleEntry :: U16 "data_reference_index" -> handlerSpecific -> Box (SampleEntry handlerSpecific)
- Data.ByteString.IsoBaseFileFormat.Boxes.Skip: Skip :: Int -> Skip
+ Data.ByteString.IsoBaseFileFormat.Boxes.Skip: Skip :: ByteString -> Skip
- Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: trackHeader :: KnownNat version => TrackHeader version -> Box (FullBox (TrackHeader version) version)
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: trackHeader :: forall version. (KnownNat version) => TrackHeaderFlags -> TrackHeader version -> Box (FullBox (TrackHeader version) version)
- Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: type TrackHeaderTimes uint = uint "creation_time" :+ (uint "modification_time" :+ (U32 "track_ID" :+ (Constant (U32 "reserved") 0 :+ uint "duration")))
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: type TrackHeaderTimes uint dur = uint "creation_time" :+ (uint "modification_time" :+ (U32 "track_ID" :+ (Constant (U32 "reserved") 0 :+ dur)))
- Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: type TrackHeaderTimesV0 = TrackHeaderTimes (Scalar Word32)
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: type TrackHeaderTimesV0 = TrackHeaderTimes (Scalar Word32) (TS32 "duration")
- Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: type TrackHeaderTimesV1 = TrackHeaderTimes (Scalar Word64)
+ Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader: type TrackHeaderTimesV1 = TrackHeaderTimes (Scalar Word64) (TS64 "duration")
- Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: [SomeColourInformation] :: forall (profile :: ColourTypeProfile). IsBoxContent (ColourInformation profile) => ColourInformation profile -> SomeColourInformation
+ Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry: [SomeColourInformation] :: forall (profile :: ColourTypeProfile). IsBoxContent (ColourInformation profile) => !(ColourInformation profile) -> SomeColourInformation
Files
- .gitignore +3/−0
- .travis.yml +2/−2
- LICENSE +1/−1
- README.md +1/−1
- benchmarks/bit-records/Main.hs +193/−0
- doc/ES_Descriptor.markDown +36/−0
- doc/trun.markDown +43/−0
- examples/734397657.m4s binary
- examples/audio.mpd +0/−16
- examples/init.mp4 binary
- isobmff-builder.cabal +148/−26
- spec/BitRecordsSpec.hs +470/−0
- spec/BoxFieldsSpec.hs +3/−0
- spec/BoxSpec.hs +2/−1
- spec/BrandTypeSpec.hs +0/−70
- spec/DashSpec.hs +0/−105
- spec/DataReferenceSpec.hs +1/−0
- spec/ElementaryStreamDescriptorSpec.hs +40/−0
- spec/EnumSpec.hs +29/−0
- spec/ExpandableSpec.hs +68/−0
- spec/MediaFileSpec.hs +71/−0
- spec/Mp4AudioFileSpec.hs +195/−0
- spec/Mp4AudioSampleEntry.hs +27/−0
- spec/Mp4AudioSegmentSpec.hs +75/−0
- spec/TypeLayoutSpec.hs +9/−1
- src/Data/ByteString/IsoBaseFileFormat/Box.hs +379/−0
- src/Data/ByteString/IsoBaseFileFormat/Boxes.hs +13/−10
- src/Data/ByteString/IsoBaseFileFormat/Boxes/AudioSampleEntry.hs +16/−26
- src/Data/ByteString/IsoBaseFileFormat/Boxes/Box.hs +0/−360
- src/Data/ByteString/IsoBaseFileFormat/Boxes/BoxFields.hs +0/−298
- src/Data/ByteString/IsoBaseFileFormat/Boxes/ChunkOffset.hs +52/−0
- src/Data/ByteString/IsoBaseFileFormat/Boxes/DataEntryUrl.hs +3/−2
- src/Data/ByteString/IsoBaseFileFormat/Boxes/DataEntryUrn.hs +2/−2
- src/Data/ByteString/IsoBaseFileFormat/Boxes/DataInformation.hs +1/−1
- src/Data/ByteString/IsoBaseFileFormat/Boxes/DataReference.hs +4/−3
- src/Data/ByteString/IsoBaseFileFormat/Boxes/FileType.hs +5/−4
- src/Data/ByteString/IsoBaseFileFormat/Boxes/FullBox.hs +0/−92
- src/Data/ByteString/IsoBaseFileFormat/Boxes/Handler.hs +8/−3
- src/Data/ByteString/IsoBaseFileFormat/Boxes/HintMediaHeader.hs +4/−3
- src/Data/ByteString/IsoBaseFileFormat/Boxes/HintSampleEntry.hs +6/−8
- src/Data/ByteString/IsoBaseFileFormat/Boxes/Language.hs +6/−5
- src/Data/ByteString/IsoBaseFileFormat/Boxes/Media.hs +1/−1
- src/Data/ByteString/IsoBaseFileFormat/Boxes/MediaData.hs +1/−1
- src/Data/ByteString/IsoBaseFileFormat/Boxes/MediaHeader.hs +7/−7
- src/Data/ByteString/IsoBaseFileFormat/Boxes/MediaInformation.hs +1/−1
- src/Data/ByteString/IsoBaseFileFormat/Boxes/MetaDataSampleEntry.hs +5/−13
- src/Data/ByteString/IsoBaseFileFormat/Boxes/Movie.hs +1/−1
- src/Data/ByteString/IsoBaseFileFormat/Boxes/MovieExtends.hs +22/−0
- src/Data/ByteString/IsoBaseFileFormat/Boxes/MovieExtendsHeader.hs +27/−0
- src/Data/ByteString/IsoBaseFileFormat/Boxes/MovieFragment.hs +20/−0
- src/Data/ByteString/IsoBaseFileFormat/Boxes/MovieFragmentHeader.hs +28/−0
- src/Data/ByteString/IsoBaseFileFormat/Boxes/MovieHeader.hs +15/−15
- src/Data/ByteString/IsoBaseFileFormat/Boxes/NullMediaHeader.hs +3/−2
- src/Data/ByteString/IsoBaseFileFormat/Boxes/ProgressiveDownloadInformation.hs +5/−4
- src/Data/ByteString/IsoBaseFileFormat/Boxes/SampleDescription.hs +8/−7
- src/Data/ByteString/IsoBaseFileFormat/Boxes/SampleEntry.hs +28/−28
- src/Data/ByteString/IsoBaseFileFormat/Boxes/SampleSize.hs +42/−0
- src/Data/ByteString/IsoBaseFileFormat/Boxes/SampleTable.hs +1/−1
- src/Data/ByteString/IsoBaseFileFormat/Boxes/SampleToChunk.hs +32/−0
- src/Data/ByteString/IsoBaseFileFormat/Boxes/SegmentType.hs +25/−0
- src/Data/ByteString/IsoBaseFileFormat/Boxes/Skip.hs +6/−4
- src/Data/ByteString/IsoBaseFileFormat/Boxes/SoundMediaHeader.hs +4/−3
- src/Data/ByteString/IsoBaseFileFormat/Boxes/Time.hs +0/−72
- src/Data/ByteString/IsoBaseFileFormat/Boxes/TimeToSample.hs +4/−3
- src/Data/ByteString/IsoBaseFileFormat/Boxes/Track.hs +1/−1
- src/Data/ByteString/IsoBaseFileFormat/Boxes/TrackExtends.hs +62/−0
- src/Data/ByteString/IsoBaseFileFormat/Boxes/TrackFragBaseMediaDecodeTime.hs +32/−0
- src/Data/ByteString/IsoBaseFileFormat/Boxes/TrackFragment.hs +23/−0
- src/Data/ByteString/IsoBaseFileFormat/Boxes/TrackFragmentHeader.hs +33/−0
- src/Data/ByteString/IsoBaseFileFormat/Boxes/TrackHeader.hs +39/−19
- src/Data/ByteString/IsoBaseFileFormat/Boxes/TrackRun.hs +80/−0
- src/Data/ByteString/IsoBaseFileFormat/Boxes/Versioned.hs +0/−24
- src/Data/ByteString/IsoBaseFileFormat/Boxes/VideoMediaHeader.hs +4/−3
- src/Data/ByteString/IsoBaseFileFormat/Boxes/VisualSampleEntry.hs +10/−24
- src/Data/ByteString/IsoBaseFileFormat/Brands/Dash.hs +32/−54
- src/Data/ByteString/IsoBaseFileFormat/Brands/Types.hs +0/−17
- src/Data/ByteString/IsoBaseFileFormat/MediaFile.hs +18/−0
- src/Data/ByteString/IsoBaseFileFormat/ReExports.hs +41/−0
- src/Data/ByteString/IsoBaseFileFormat/Util/BitRecords.hs +0/−214
- src/Data/ByteString/IsoBaseFileFormat/Util/BoxFields.hs +304/−0
- src/Data/ByteString/IsoBaseFileFormat/Util/FullBox.hs +93/−0
- src/Data/ByteString/IsoBaseFileFormat/Util/Time.hs +140/−0
- src/Data/ByteString/IsoBaseFileFormat/Util/Versioned.hs +25/−0
- src/Data/ByteString/Mp4/AudioStreaming.hs +292/−0
- src/Data/ByteString/Mp4/Boxes/AudioSpecificConfig.hs +310/−0
- src/Data/ByteString/Mp4/Boxes/BaseDescriptor.hs +72/−0
- src/Data/ByteString/Mp4/Boxes/DecoderConfigDescriptor.hs +55/−0
- src/Data/ByteString/Mp4/Boxes/DecoderSpecificInfo.hs +112/−0
- src/Data/ByteString/Mp4/Boxes/ElementaryStreamDescriptor.hs +80/−0
- src/Data/ByteString/Mp4/Boxes/Expandable.hs +73/−0
- src/Data/ByteString/Mp4/Boxes/Mp4AudioSampleEntry.hs +90/−0
- src/Data/ByteString/Mp4/Boxes/SyncLayerConfigDescriptor.hs +18/−0
- src/Data/Kind/Extra.hs +156/−0
- src/Data/Type/BitRecords.hs +21/−0
- src/Data/Type/BitRecords/Arithmetic.hs +118/−0
- src/Data/Type/BitRecords/Assert.hs +91/−0
- src/Data/Type/BitRecords/Builder/BitBuffer.hs +163/−0
- src/Data/Type/BitRecords/Builder/Holey.hs +49/−0
- src/Data/Type/BitRecords/Builder/LazyByteStringBuilder.hs +322/−0
- src/Data/Type/BitRecords/Core.hs +379/−0
- src/Data/Type/BitRecords/Enum.hs +141/−0
- src/Data/Type/BitRecords/Sized.hs +73/−0
- src/Data/Type/BitRecords/SizedString.hs +74/−0
- stack.yaml +3/−61
.gitignore view
@@ -6,6 +6,9 @@ *_flymake.hs .hsenv .stack-work/+/*.html TAGS /.idea/ /.dir-locals.el+*.refactored.hs+/*.html
.travis.yml view
@@ -18,7 +18,7 @@ install: - stack -j 2 setup --no-terminal --resolver nightly- - stack -j 2 build --only-snapshot --no-terminal script:- - stack -j 2 test --no-terminal+ - stack test --flag isobmff-builder:-complextests --flag isobmff-builder:-fullbenchmarks --fast --no-terminal+ - stack bench --flag isobmff-builder:-complextests --flag isobmff-builder:-fullbenchmarks --fast --no-terminal
LICENSE view
@@ -1,4 +1,4 @@-Copyright Sven Heyll (c) 2016+Copyright Sven Heyll and Lindenbaum GmbH (c) 2016 All rights reserved.
README.md view
@@ -1,5 +1,5 @@ [](https://travis-ci.org/sheyll/isobmff-builder)-[](http://hackage.haskell.org/package/isobmff-builder)+[](http://hackage.haskell.org/package/isobmff-builder) # ISO-14496-12 Base Media File Format Builder
+ benchmarks/bit-records/Main.hs view
@@ -0,0 +1,193 @@+{-# OPTIONS_GHC -fno-warn-missing-signatures #-}+{-# LANGUAGE CPP #-}+module Main where++import Prelude hiding ( (.), id )+import Control.Category+import Criterion.Main+import qualified Data.ByteString.Builder as L+import qualified Data.ByteString.Lazy as L+import Data.Proxy+import Data.Type.BitRecords+import Data.Word+import Data.Tagged+import GHC.TypeLits ()+#ifdef FULLBENCHMARKS+import Data.Type.Equality+#endif+import Test.TypeSpecCrazy++#ifdef FULLBENCHMARKS++type Static64 =+ Field 3 := 2+ .+. Field 5 := 4+ .+. Field 9 := 333+ .+. Field 7 := 35+ .+. Field 30 := 458329+ .+. Field 2 := 1+ .+. Field 2 := 0+ .+. Field 2 := 1+ .+. Field 4 := 9+++type Static64WithParams =+ Field 3 := 0+ .+. Field 5 := 0+ .+. Field 9 := 0+ .+. "x" @: Field 7+ .+. Field 30 := 0+ .+. "y" @: Field 2+ .+. Field 2 := 0+ .+. Field 2 := 0+ .+. Field 4 := 0++type Static128 = Field 64 := 3735928559 .+. Field 64 := 3405688830++type Static256 = Static64 :+: Static128 :+: Static64++type Static517 = Static256 :+: Static256 :+. Field 5 := 0++#else++type Static64 = 'BitRecordMember (Field 64 := 0)+++type Static64WithParams =+ "x" @: Field 32+ .+. "y" @: Field 32++#endif++aboutStatic64 ::++ "Test Types Sizes"+ ########################++ It's "64 bit long: Static64" (ShouldBe 64 (BitRecordSize Static64))+ -* It's "64 bit long: Static64WithParams" (ShouldBe 64 (BitRecordSize Static64WithParams))+#ifdef FULLBENCHMARKS+ -* It's "128 bit long" (ShouldBeTrue ((BitRecordSize Static128) == 128))+ -* It's "256 bit long" (ShouldBeTrue ((BitRecordSize Static256) == 256))+ -* It's "517 bit long" (ShouldBeTrue ((BitRecordSize Static517) == 517))+#endif++aboutStatic64 =+ Valid++lumpUp :: Word64 -> L.Builder -> [Word8]+lumpUp m = L.unpack . L.toLazyByteString . mconcat . replicate (fromIntegral m)++static64 m = lumpUp m $+ runBitStringBuilderHoley $ bitStringBuilderHoley (Proxy :: Proxy Static64)++static64WithParam m = lumpUp m $+ runBitStringBuilderHoley (bitStringBuilderHoley (Proxy :: Proxy Static64WithParams))+ (B m)+ (B m)++#ifdef FULLBENCHMARKS++static128 m =+ lumpUp m $ runBitStringBuilderHoley $ bitStringBuilderHoley (Proxy :: Proxy Static128)++static256 m =+ lumpUp m $ runBitStringBuilderHoley $ bitStringBuilderHoley (Proxy :: Proxy Static256)++static517 m =+ lumpUp m $ runBitStringBuilderHoley $ bitStringBuilderHoley (Proxy :: Proxy Static517)++staticPlain512bitBaseline m =+ lumpUp m $ runBitStringBuilderHoley $ bitStringBuilderHoley+ (Proxy :: Proxy (+ Field 64 .+. Field 64 .+. Field 64 .+. Field 64 .+.+ Field 64 .+. Field 64 .+. Field 64 .+. Field 64+ ))+++#endif++main = do+ print aboutStatic64+ defaultMain [ bgroup "ByteStringBuilder"+ [ bgroup "64-bit"+ [ bench "1" $ nf static64 1+ , bench "100" $ nf static64 5+ , bench "1000" $ nf static64 1000+ ]+ , bgroup "64-bit parameterized"+ [ bench "1" $+ nf static64WithParam 1+ , bench "100" $+ nf static64WithParam 5+ , bench "1000" $+ nf static64WithParam 1000+ ]+#ifdef FULLBENCHMARKS+ , bgroup "128-bit"+ [ bench "1" $+ nf static128 1+ , bench "100" $+ nf static128 5+ , bench "1000" $+ nf static128 1000+ ]+ , bgroup "256-bit"+ [ bench "1" $+ nf static256 1+ , bench "100" $+ nf static256 5+ , bench "1000" $+ nf static256 1000+ ]+ , bgroup "517-bit"+ [ bench "1" $+ nf static517 1+ , bench "100" $+ nf static517 5+ , bench "1000" $+ nf static517 1000+ ]+ , bgroup "512-bit baseline"+ [ bench "1" $+ nf staticPlain512bitBaseline 1+ , bench "100" $+ nf staticPlain512bitBaseline 100+ , bench "1000" $+ nf staticPlain512bitBaseline 1000+ ]+#endif+ , bgroup "BitString Word64 direct"+ [ bench "1" $+ nf bitStringWord64Direct 1+ , bench "100" $+ nf bitStringWord64Direct 5+ , bench "1000" $+ nf bitStringWord64Direct 1000+ ]+ , bgroup "BitString Word64 holey"+ [ bench "1" $+ nf bitStringWord64Holey 1+ , bench "100" $+ nf bitStringWord64Holey 5+ , bench "1000" $+ nf bitStringWord64Holey 1000+ ]+ ]+ ]++bitStringWord64Direct m =+ lumpUp 1+ $ runBitStringBuilder+ $ mconcat+ $ replicate m+ $ appendBitString+ $ bitString 64 0x01020304050607++bitStringWord64Holey m =+ lumpUp 1+ $ runBitStringBuilderHoley+ $ mconcat+ $ replicate m+ $ bitStringBuilderHoley+ $ bitString 64 0x01020304050607
+ doc/ES_Descriptor.markDown view
@@ -0,0 +1,36 @@+# `esds` Box Contents++ 00000027 65736473 00000000++ ES_Descriptor+ | length+ x 03 | ES_ID+ x 19 |sdf+ x 0001|url+ b 0|ocr+ b 0| stream priority+ b 0 | DecoderConfigDescriptor+ b 00000 | length+ x 04 | objectype indication: Audio ISO/IEC 14496-3+ x 11 | stream-type: 0x5 AudioStream+ x 40 |Upstream+ b 000101|reserved+ b 0| BufferSize DB+ b 1 | maxBitrate+ x 000000 | avgBitrate+ x 00000000 | DecoderSpecificInfo+ x 00000000 | length+ x 05 |+ x 02+ x 1 1 9 0+ =b 00010 - audioObjectType: 2 AAC LC+ =b 0011 - (=3) samplingFrequencyIndex: 48k+ =b 0010 - channelConfiguration: channel pair+ =b 0 - frameLenflag \+ =b 0 - dependsOnCoreCoder | GASpecificconfig+ =b 0 - coreCoderDelay /+ SLConfigDescrTag+ | length: 1+ x 06 | Predefined according to iso 14496-14 section 3.1.2+ x 01 |+ x 02
+ doc/trun.markDown view
@@ -0,0 +1,43 @@++# Contents of a `trun` box+++ 0000 047c+ 00000060: 7472 756e 0000 0701 0000 005e 0000 04c8+ 00000070: 0000 0400 0000 0095 0200 0000 0000 0400+ 00000080: 0000 0076 0200 0000 0000 0400 0000 008c+ 00000090: 0200 0000 0000 0400 0000 008b 0200 0000+ 000000a0: 0000 0400 0000 0094 0200 0000 0000 0400+ 000000b0: 0000 007a 0200 0000 0000 0400 0000 0087+ 000000c0: 0200 0000 0000 0400 0000 0099 0200 0000+ 000000d0: 0000 0400 0000 0095 0200 0000 0000 0400++## Box header++ 0x0000047c size+ 0x7472 756e 'trun'+ 0x00 version+ 0x000701 flags+ 0x0000005e sample_count = 94+ 0x000004c8 data_offset++## A closer look at a single entry++ 0x00000400 sample duration+ 0x00000095 sample size+ 0x02000000 sample flags+++### Sample flags++ 0 2 0 0 0 0 0 0 (hex)+ 0000 0010 0000 0000 0000 0000 0000 0000 (binary)++ 0000 -> 4 bits reserved = 0+ 00 -> is_leading+ 10 -> sample_depends+ 00 -> sample_is_depended_on+ 00 -> sample has redundancy+ 000 -> padding+ 0 -> non sync+ 0000 0000 0000 0000 degradation priority
− examples/734397657.m4s
binary file changed (13293 → absent bytes)
− examples/audio.mpd
@@ -1,16 +0,0 @@-<?xml version="1.0" encoding="utf-8"?>-<MPD availabilityStartTime="1970-01-01T00:00:00Z" maxSegmentDuration="PT2S" minBufferTime="PT2S" minimumUpdatePeriod="P100Y" profiles="urn:mpeg:dash:profile:isoff-live:2011,http://dashif.org/guidelines/dash-if-simple" timeShiftBufferDepth="PT5M" type="dynamic" ns1:schemaLocation="urn:mpeg:dash:schema:mpd:2011 DASH-MPD.xsd" xmlns="urn:mpeg:dash:schema:mpd:2011" xmlns:ns1="http://www.w3.org/2001/XMLSchema-instance">- <ProgramInformation>- <Title>Media Presentation Description for audio only from DASH-IF live simulator</Title>- </ProgramInformation>- <BaseURL>http://vm2.dashif.org/livesim/testpic_2s/</BaseURL>-<Period id="p0" start="PT0S">- <AdaptationSet contentType="audio" lang="eng" mimeType="audio/mp4" segmentAlignment="true" startWithSAP="1">- <Role schemeIdUri="urn:mpeg:dash:role:2011" value="main" />- <SegmentTemplate duration="2" initialization="$RepresentationID$/init.mp4" media="$RepresentationID$/$Number$.m4s" startNumber="0" />- <Representation audioSamplingRate="48000" bandwidth="48000" codecs="mp4a.40.2" id="A48">- <AudioChannelConfiguration schemeIdUri="urn:mpeg:dash:23003:3:audio_channel_configuration:2011" value="2" />- </Representation>- </AdaptationSet>- </Period>-</MPD>
− examples/init.mp4
binary file changed (651 → absent bytes)
isobmff-builder.cabal view
@@ -1,13 +1,13 @@ name: isobmff-builder-version: 0.10.5.0+version: 0.11.2.0 synopsis: A (bytestring-) builder for the ISO-14496-12 base media file format description: Please see README.md homepage: https://github.com/sheyll/isobmff-builder#readme license: BSD3 license-file: LICENSE author: Sven Heyll-maintainer: sven.heyll@gmail.com-copyright: 2016 Sven Heyll+maintainer: sven.heyll@lindenbaum.eu+copyright: 2016 Sven Heyll, Lindenbaum GmbH category: Codec build-type: Simple extra-source-files: README.md@@ -15,24 +15,34 @@ , .travis.yml , doc/basic-structure.svg , doc/data_reference_box.svg- , examples/734397657.m4s- , examples/init.mp4- , examples/audio.mpd+ , doc/ES_Descriptor.markDown+ , doc/trun.markDown , .gitignore cabal-version: >=1.10 +flag tracing+ description: Build with trace output enabled+ default: True++flag fullbenchmarks+ description: Enable the compilation of all benchmarks, takes a long time to compile+ default: True++flag complextests+ description: Enable the compilation of all unit tests, even those, that take a long time to compile+ default: True+ library hs-source-dirs: src- exposed-modules: Data.ByteString.IsoBaseFileFormat.Boxes+ exposed-modules: Data.ByteString.IsoBaseFileFormat.Box+ , Data.ByteString.IsoBaseFileFormat.Boxes , Data.ByteString.IsoBaseFileFormat.Boxes.AudioSampleEntry- , Data.ByteString.IsoBaseFileFormat.Boxes.Box- , Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields+ , Data.ByteString.IsoBaseFileFormat.Boxes.ChunkOffset , Data.ByteString.IsoBaseFileFormat.Boxes.DataEntryUrl , Data.ByteString.IsoBaseFileFormat.Boxes.DataEntryUrn , Data.ByteString.IsoBaseFileFormat.Boxes.DataInformation , Data.ByteString.IsoBaseFileFormat.Boxes.DataReference , Data.ByteString.IsoBaseFileFormat.Boxes.FileType- , Data.ByteString.IsoBaseFileFormat.Boxes.FullBox , Data.ByteString.IsoBaseFileFormat.Boxes.Handler , Data.ByteString.IsoBaseFileFormat.Boxes.HintMediaHeader , Data.ByteString.IsoBaseFileFormat.Boxes.HintSampleEntry@@ -42,46 +52,90 @@ , Data.ByteString.IsoBaseFileFormat.Boxes.MediaInformation , Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry , Data.ByteString.IsoBaseFileFormat.Boxes.Movie+ , Data.ByteString.IsoBaseFileFormat.Boxes.MovieExtends+ , Data.ByteString.IsoBaseFileFormat.Boxes.MovieExtendsHeader+ , Data.ByteString.IsoBaseFileFormat.Boxes.MovieFragment+ , Data.ByteString.IsoBaseFileFormat.Boxes.MovieFragmentHeader , Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader , Data.ByteString.IsoBaseFileFormat.Boxes.NullMediaHeader , Data.ByteString.IsoBaseFileFormat.Boxes.ProgressiveDownloadInformation , Data.ByteString.IsoBaseFileFormat.Boxes.Language , Data.ByteString.IsoBaseFileFormat.Boxes.SampleDescription , Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry+ , Data.ByteString.IsoBaseFileFormat.Boxes.SampleSize , Data.ByteString.IsoBaseFileFormat.Boxes.SampleTable+ , Data.ByteString.IsoBaseFileFormat.Boxes.SampleToChunk+ , Data.ByteString.IsoBaseFileFormat.Boxes.SegmentType , Data.ByteString.IsoBaseFileFormat.Boxes.Skip , Data.ByteString.IsoBaseFileFormat.Boxes.SoundMediaHeader , Data.ByteString.IsoBaseFileFormat.Boxes.SpecificMediaHeader- , Data.ByteString.IsoBaseFileFormat.Boxes.Time , Data.ByteString.IsoBaseFileFormat.Boxes.TimeToSample , Data.ByteString.IsoBaseFileFormat.Boxes.Track+ , Data.ByteString.IsoBaseFileFormat.Boxes.TrackExtends+ , Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragBaseMediaDecodeTime+ , Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragment+ , Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragmentHeader , Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader- , Data.ByteString.IsoBaseFileFormat.Boxes.Versioned+ , Data.ByteString.IsoBaseFileFormat.Boxes.TrackRun , Data.ByteString.IsoBaseFileFormat.Boxes.VideoMediaHeader , Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry , Data.ByteString.IsoBaseFileFormat.Brands.Dash- , Data.ByteString.IsoBaseFileFormat.Brands.Types+ , Data.ByteString.IsoBaseFileFormat.MediaFile+ , Data.ByteString.IsoBaseFileFormat.ReExports+ , Data.ByteString.IsoBaseFileFormat.Util.BoxFields+ , Data.ByteString.IsoBaseFileFormat.Util.FullBox+ , Data.ByteString.IsoBaseFileFormat.Util.Time , Data.ByteString.IsoBaseFileFormat.Util.TypeLayout- , Data.ByteString.IsoBaseFileFormat.Util.BitRecords+ , Data.ByteString.IsoBaseFileFormat.Util.Versioned+ , Data.ByteString.Mp4.Boxes.AudioSpecificConfig+ , Data.ByteString.Mp4.Boxes.BaseDescriptor+ , Data.ByteString.Mp4.Boxes.DecoderConfigDescriptor+ , Data.ByteString.Mp4.Boxes.DecoderSpecificInfo+ , Data.ByteString.Mp4.Boxes.ElementaryStreamDescriptor+ , Data.ByteString.Mp4.Boxes.Expandable+ , Data.ByteString.Mp4.Boxes.Mp4AudioSampleEntry+ , Data.ByteString.Mp4.Boxes.SyncLayerConfigDescriptor+ , Data.ByteString.Mp4.AudioStreaming+ , Data.Kind.Extra+ , Data.Type.BitRecords+ , Data.Type.BitRecords.Arithmetic+ , Data.Type.BitRecords.Assert+ , Data.Type.BitRecords.Builder.BitBuffer+ , Data.Type.BitRecords.Builder.Holey+ , Data.Type.BitRecords.Builder.LazyByteStringBuilder+ , Data.Type.BitRecords.Core+ , Data.Type.BitRecords.Enum+ , Data.Type.BitRecords.SizedString+ , Data.Type.BitRecords.Sized build-depends: base >= 4.9 && < 5 , bytestring >= 0.10.8.1 && < 0.11 , type-list >= 0.5.0.0 && < 0.6 , data-default >= 0.7.1.1 && < 0.8- , vector-sized >= 0.3.2.0 && < 0.4+ , vector >= 0.11 && < 0.12 , singletons >= 2.2 && < 3 , tagged >= 0.8 && < 1 , time >= 1.6.0.1 && < 2 , text >= 1.2.2.1 && < 2- , type-spec >= 0.1+ , type-spec >= 0.3+ , mtl >= 2.2 && < 3+ , pretty-types >= 0.2.3 && < 0.3+ , template-haskell >= 2.11 && < 3 default-language: Haskell2010- ghc-options: -Wall -funbox-strict-fields -fno-warn-unused-do-bind- default-extensions: ConstraintKinds+ ghc-options: -O2 -Wall -funbox-strict-fields -fno-warn-unused-do-bind -fprint-explicit-kinds+ if flag(tracing)+ cpp-options: -DTRACING+ else+ cpp-options: -DNTRACING++ default-extensions: BangPatterns+ , ConstraintKinds , CPP , DataKinds , DefaultSignatures , DeriveDataTypeable , DeriveFunctor , DeriveGeneric+ , DuplicateRecordFields , FlexibleInstances , FlexibleContexts , FunctionalDependencies@@ -97,32 +151,44 @@ , StandaloneDeriving , TemplateHaskell , TupleSections+ , TypeApplications , TypeFamilies , TypeInType , TypeOperators , TypeSynonymInstances-+ , UnicodeSyntax test-suite spec type: exitcode-stdio-1.0 ghc-options: -Wall hs-source-dirs: spec default-language: Haskell2010 main-is: Spec.hs- other-modules: BoxFieldsSpec+ other-modules: BitRecordsSpec+ , BoxFieldsSpec , BoxSpec- , BrandTypeSpec , DataReferenceSpec- , DashSpec+ , ElementaryStreamDescriptorSpec+ , EnumSpec+ , ExpandableSpec+ , Mp4AudioSampleEntry+ , MediaFileSpec+ , Mp4AudioFileSpec+ , Mp4AudioSegmentSpec , TypeLayoutSpec build-depends: base >= 4.9 && < 5 , bytestring >= 0.10.8.1- , hspec+ , hspec >= 2.2 && < 3 , isobmff-builder , binary , text >= 1.2.2.1 && < 2- , type-spec >= 0.1+ , type-spec >= 0.3+ , mtl >= 2.2 && < 3+ , QuickCheck+ , tagged >= 0.8 && < 1+ , pretty-types >= 0.2.1 && < 0.3 default-language: Haskell2010- default-extensions: ConstraintKinds+ default-extensions: BangPatterns+ , ConstraintKinds , CPP , DataKinds , DefaultSignatures@@ -144,12 +210,68 @@ , StandaloneDeriving , TemplateHaskell , TupleSections+ , TypeApplications , TypeFamilies , TypeInType , TypeOperators , TypeSynonymInstances+ , UnicodeSyntax ghc-options: -Wall -O0 -j +RTS -A256m -n2m -RTS- -fwarn-unused-binds -fno-warn-unused-do-bind -fno-warn-missing-signatures+ -fwarn-unused-binds -fno-warn-unused-do-bind -fno-warn-missing-signatures -fprint-explicit-kinds+ if flag(complextests)+ cpp-options: -DCOMPLEXTESTS+ else+ cpp-options: -DNCOMPLEXTESTS++benchmark bit-records+ type: exitcode-stdio-1.0+ hs-source-dirs: benchmarks/bit-records+ main-is: Main.hs+ default-language: Haskell2010+ build-depends: base >= 4.9 && < 5+ , isobmff-builder+ , binary+ , bytestring >= 0.10.8.1 && < 0.11+ , criterion >= 1.1 && < 2+ , tagged >= 0.8 && < 1+ , type-spec >= 0.3+ default-language: Haskell2010+ default-extensions: BangPatterns+ , ConstraintKinds+ , CPP+ , DataKinds+ , DefaultSignatures+ , DeriveDataTypeable+ , DeriveFunctor+ , DeriveGeneric+ , FlexibleInstances+ , FlexibleContexts+ , FunctionalDependencies+ , GADTs+ , GeneralizedNewtypeDeriving+ , KindSignatures+ , MultiParamTypeClasses+ , OverloadedStrings+ , QuasiQuotes+ , RecordWildCards+ , RankNTypes+ , ScopedTypeVariables+ , StandaloneDeriving+ , TemplateHaskell+ , TupleSections+ , TypeApplications+ , TypeFamilies+ , TypeInType+ , TypeOperators+ , TypeSynonymInstances+ , UnicodeSyntax+ ghc-options: -O2 -j +RTS -A256m -n2m -RTS+ -Wall -fwarn-unused-binds+ -fno-warn-unused-do-bind -fprint-explicit-kinds+ if flag(fullbenchmarks)+ cpp-options: -DFULLBENCHMARKS+ else+ cpp-options: -DNFULLBENCHMARKS source-repository head type: git
+ spec/BitRecordsSpec.hs view
@@ -0,0 +1,470 @@+{-# LANGUAGE UndecidableInstances #-}+module BitRecordsSpec (spec) where++import Data.Bits+import Data.ByteString.Builder+import Data.Proxy+import Data.Type.BitRecords+import Data.Type.Equality ()+import Data.Kind.Extra+import GHC.TypeLits+import Prelude hiding ((.), id)+import Test.Hspec+import Test.QuickCheck (property, Arbitrary(..), choose)+import Test.TypeSpecCrazy+import Text.Printf++basicsSpec = do+ describe "Maybe, Lists, Either, Bool, 'True, 'False, FlagJust, FlagNothing" $ do+ let checkFlagJust ::+ "Type Level Bool, 'True, 'False, FlagJust, FlagNothing Accessors"+ ##################################################################++ "The record size works"+ ~~~~~~~~~~~~~~~~~~~~~~~~+ 1 `ShouldBe` BitRecordFieldSize (FlagJust 'Nothing)+ -* 1 `ShouldBe` BitRecordFieldSize (FlagJust ('Just "Blah"))+ -* 1 `ShouldBe` BitRecordFieldSize (FlagNothing ('Just "Blah"))+ -- TODO reenable tests+ -- -* 32 `ShouldBe` BitRecordSize (ToBitRecord ('Just FieldU32))+ -- -* 0 `ShouldBe` BitRecordSize (ToBitRecord '[])+ -- -* 10 `ShouldBe` BitRecordSize (ToBitRecord '[Field 10])+ -- -* 25 `ShouldBe` BitRecordSize (ToBitRecord '[Field 10, Field 15])+ -- -* 1 `ShouldBe` BitRecordSize (ToBitRecord Bool)+ -- -* 1 `ShouldBe` BitRecordSize (ToBitRecord 'True)+ -- -* 1 `ShouldBe` BitRecordSize (ToBitRecord 'False)+ checkFlagJust = Valid+ runIO $ print checkFlagJust+ describe "bitStringBuilder" $ do+ describe "Just x" $ it "writes x" $+ bitStringPrinter (Proxy :: Proxy (OptionalRecord ('Just ('BitRecordMember (Flag := 'True))))) `shouldBe` "<< 80 >>"+ describe "Nothing" $ it "writes nothing" $+ bitStringPrinter (Proxy :: Proxy (OptionalRecord ('Nothing))) `shouldBe` "<< >>"+ -- describe "'[]" $ it "writes nothing" $+ -- bitStringPrinter (Proxy :: Proxy (BitRecordOfList (Fun1 RecordField) ('[]))) `shouldBe` "<< >>"+ -- describe "'[x1, x2]" $ it "writes x1 then x2" $+ -- bitStringPrinter (Proxy :: Proxy (BitRecordOfList (Fun1 RecordField) ('[FieldU8 := 1, FieldU8 := 2]))) `shouldBe` "<< 01 02 >>"+ describe "'True" $ it "writes a single bit with a 1" $+ bitStringPrinter (Proxy :: Proxy (RecordField (Flag := 'True))) `shouldBe` "<< 80 >>"+ describe "'False" $ it "writes a single bit with a 0" $+ bitStringPrinter (Proxy :: Proxy (RecordField (Flag := 'False))) `shouldBe` "<< 00 >>"+ describe "@: labelled fields" $ do+ it "writes them ..." $+ let fld = Proxy @(Eval (RecordField ( "foo" @: FlagJust 'Nothing )))+ in bitStringPrinter fld `shouldBe` "<< 00 >>"+ describe "FlagJust" $ do+ it "writes a single bit '1' for a 'Just ...' parameter" $+ bitStringPrinter (Proxy :: Proxy (RecordField (FlagJust ('Just "test")))) `shouldBe` "<< 80 >>"+ it "writes a single bit '0' for a 'Nothing' parameter" $+ bitStringPrinter (Proxy :: Proxy (RecordField (FlagJust 'Nothing))) `shouldBe` "<< 00 >>"+ describe "FlagNothing" $ do+ it "writes a single bit '0' for a 'Just ...' parameter" $+ bitStringPrinter (Proxy :: Proxy (RecordField (FlagNothing ('Just "test")))) `shouldBe` "<< 00 >>"+ it "writes a single bit '1' for a 'Nothing' parameter" $+ bitStringPrinter (Proxy :: Proxy (RecordField (FlagNothing 'Nothing))) `shouldBe` "<< 80 >>"+ -- TODO reenable showRecord tests+ -- describe "showRecord" $ do+ -- describe "Maybe" $ do+ -- it "prints 'Just x'" $+ -- showRecord (Proxy :: Proxy (ToBitRecord ('Just 'True))) `shouldBe` "Field:\n Demote Rep: Bool\n Bits: 1\n Static Value: 'True"+ -- it "prints nothing for 'Nothing'" $+ -- showRecord (Proxy :: Proxy (ToBitRecord ('Nothing))) `shouldBe` ""+ -- describe "List" $ do+ -- it "prints '[x]'" $+ -- showRecord (Proxy :: Proxy (ToBitRecord ('[ 'True ]))) `shouldBe` "Field:\n Demote Rep: Bool\n Bits: 1\n Static Value: 'True"+ -- it "prints '[x1, x2, x3]'" $+ -- showRecord (Proxy :: Proxy (ToBitRecord ('[ Bool, Bool, Bool ]))) `shouldBe` "Field:\n Demote Rep: Bool\n Bits: 1\nField:\n Demote Rep: Bool\n Bits: 1\nField:\n Demote Rep: Bool\n Bits: 1"+ -- it "prints nothing for '[]'" $+ -- showRecord (Proxy :: Proxy (ToBitRecord ('[]))) `shouldBe` ""+ -- describe "Bool" $ do+ -- it "prints 'True" $+ -- showRecord (Proxy :: Proxy (ToBitRecord ('True))) `shouldBe` "Field:\n Demote Rep: Bool\n Bits: 1\n Static Value: 'True"+ -- it "prints 'False" $+ -- showRecord (Proxy :: Proxy (ToBitRecord ('False))) `shouldBe` "Field:\n Demote Rep: Bool\n Bits: 1\n Static Value: 'False"+ -- it "prints a Bool" $+ -- showRecord (Proxy :: Proxy (ToBitRecord Bool)) `shouldBe` "Field:\n Demote Rep: Bool\n Bits: 1"+ -- describe "FlagJust" $ do+ -- it "prints a 'FlagJust 'Just ..'" $+ -- showRecord (Proxy :: Proxy (ToBitRecord (FlagJust ('Just "123")))) `shouldBe` "Field:\n Demote Rep: Bool\n Bits: 1\n Static Value: 'True"+ -- it "prints a 'FlagJust 'Nothing'" $+ -- showRecord (Proxy :: Proxy (ToBitRecord (FlagJust 'Nothing))) `shouldBe` "Field:\n Demote Rep: Bool\n Bits: 1\n Static Value: 'False"+ -- describe "FlagNothing" $ do+ -- it "prints 'FlagNothing 'Just ..'" $+ -- showRecord (Proxy :: Proxy (ToBitRecord (FlagNothing ('Just "123")))) `shouldBe` "Field:\n Demote Rep: Bool\n Bits: 1\n Static Value: 'False"+ -- it "prints a 'FlagNothing 'Nothing'" $+ -- showRecord (Proxy :: Proxy (ToBitRecord (FlagNothing 'Nothing))) `shouldBe` "Field:\n Demote Rep: Bool\n Bits: 1\n Static Value: 'True"++#ifdef COMPLEXTESTS+arraySpec :: SpecWith ()+arraySpec =+ describe "RecArray" $ do+ describe "level record accessors" $ do+ let checkArrayRec ::+ "BitRecord accessors involving RecArray"+ #######################################++ "The record size works"+ ~~~~~~~~~~~~~~~~~~~~~~~~+ 1 `ShouldBe` BitRecordSize (Eval (RecArray ('BitRecordMember Flag) 1))+ -* 91 `ShouldBe` BitRecordSize (Eval (("foo" @: Flag .+. FieldU8) ^^ 10) :+. Flag)+ -* 91 `ShouldBe` BitRecordSize (Eval (RecArray ("foo" @: Flag .+. FieldU8) 10) :+. Flag)+ checkArrayRec = Valid+ runIO $ print checkArrayRec+ describe "showRecord" $+ it "appends its body n times" $+ let expected = "utf-8(40) := <<hello>> [5 Bytes]\nutf-8(40) := <<hello>> [5 Bytes]\nutf-8(40) := <<hello>> [5 Bytes]\nutf-8(40) := <<hello>> [5 Bytes]\nutf-8(40) := <<hello>> [5 Bytes]"+ actual = showARecord (Proxy @ (('BitRecordMember [utf8|hello|] ^^ 5)))+ in actual `shouldBe` expected+ describe "bitStringBuilder" $+ it "writes its contents n times to the builder" $+ let actual = bitStringPrinter (Proxy :: Proxy (('BitRecordMember (Field 24 := 0x010203) ^^ 4)))+ expected = "<< 01 02 03 01 02 03 01 02 03 01 02 03 >>"+ in actual `shouldBe` expected++sizedSpec =+ describe "Sized" $ do+ describe "TypeChecks" $+ let+ checkSized ::+ "Sized"+ #########++ "SizedString"+ ~~~~~~~~~~~~~~~+ 88 `ShouldBe` BitRecordFieldSize [utf8|Hello World|]+ -* 104 `ShouldBe` BitRecordSize (Eval (RecordField [utf8|Heλλo World|]))++ -/-++ "Sized BitRecord Members"+ ~~~~~~~~~~~~~~~~~~~~~~~~+ 8 `ShouldBe` BitRecordSize (Eval (Sized8 'EmptyBitRecord))+ -* 9 `ShouldBe` BitRecordSize (Eval (Sized8 ('BitRecordMember Flag)))+ -* 0 `ShouldBe` SizeFieldValue 'EmptyBitRecord+ -* 1 `ShouldBe` SizeFieldValue ('BitRecordMember Flag)++ -/-++ "SizedField"+ ~~~~~~~~~~~~+ 9 `ShouldBe` BitRecordSize (Eval (SizedField8 Flag))+ -* 1 `ShouldBe` SizeFieldValue Flag++ -- TODO add more Sized tests, especially for SizedField+ checkSized = Valid+ in runIO $ print checkSized+ describe "showRecord" $ do+ describe "SizedString" $+ it "renders a string containing wide utf-8 characters to a header containing the number of chars and the actual string" $+ showARecord (Proxy :: Proxy (RecordField [utf8|Heλλo World!|])) `shouldBe` "utf-8(112) := <<He\955\955o World!>> [14 Bytes]"+ describe "Sized SizeField16 SizedString" $+ it "renders the number bytes not chars as the size field value" $+ showARecord (Proxy :: Proxy (SizedField16 [utf8|Heλλo World!|])) `shouldBe` "sized-field\n size: U16 := hex: 000e (dec: 14)\n utf-8(112) := <<He\955\955o World!>> [14 Bytes]"+ describe "bitStringBuilder" $ do+ describe "no length prefix" $+ it "renders no size prefix and the string as UTF-8 bytes" $+ bitStringPrinter (Proxy :: Proxy (RecordField [utf8|ABC|]))+ `shouldBe`+ "<< 41 42 43 >>"+ describe "8-bit length prefix" $+ it "renders a single byte size prefix and the string as UTF-8 bytes" $+ bitStringPrinter (Proxy :: Proxy (SizedField8 [utf8|ABC|]))+ `shouldBe`+ "<< 03 41 42 43 >>"+ describe "16-bit length prefix" $+ it "renders a big endian 16 bit size prefix and the string as UTF-8 bytes" $+ bitStringPrinter (Proxy :: Proxy (SizedField16 [utf8|ABC|]))+ `shouldBe`+ "<< 00 03 41 42 43 >>"+ describe "32-bit length prefix" $+ it "renders a big endian 32 bit size prefix and the string as UTF-8 bytes" $+ bitStringPrinter (Proxy :: Proxy (SizedField32 [utf8|ABC|]))+ `shouldBe`+ "<< 00 00 00 03 41 42 43 >>"+ describe "64-bit length prefix" $+ it "renders a big endian 64 bit size prefix and the string as UTF-8 bytes" $+ bitStringPrinter (Proxy :: Proxy (SizedField64 [utf8|ABC|]))+ `shouldBe`+ "<< 00 00 00 00 00 00 00 03 41 42 43 >>"++type TestRecAligned =+ "bar" @: Field 8 .+:+ Field 8 := 0 .+:+ "baz" @: Field 8 .+:+ Field 32 := 0 .+:+ "foo" @: Field 8 .+:+ Field 8 := 0 .+:+ "oof" @: Field 8 .+:+ Field 8 := 0 .+.+ "rab" @: Field 8++checkTestRecAligned+ :: Expect '[ ShouldBe 96 (BitRecordSize TestRecAligned) ]+checkTestRecAligned = Valid++type TestRecUnAligned =+ "bar" @: Field 8 .+:+ Field 8 := 0 .+:+ "baz" @: Field 7 .+:+ Field 32 := 0 .+:+ "foo" @: Field 8 .+.+ Field 8 := 0xfe++checkTestRecUnAligned+ :: Expect '[ ShouldBe 71 (BitRecordSize TestRecUnAligned) ]+checkTestRecUnAligned = Valid++testTakeLastN ::+ "Taking the last n elements of a list" #######################################++ TakeLastN 0 '[1,2,3] `ShouldBe` ('[] :: [Nat])+ -* TakeLastN 1 '[1,2,3] `ShouldBe` '[3]+ -* TakeLastN 2 '[1,2,3] `ShouldBe` '[2,3]+ -* TakeLastN 5 '[1,2,3] `ShouldBe` '[1,2,3]++testTakeLastN = Valid++testRem+ :: Expect '[ Rem 0 3 `ShouldBe` 0+ , Rem 1 3 `ShouldBe` 1+ , Rem 2 3 `ShouldBe` 2+ , Rem 3 3 `ShouldBe` 0+ , Rem 4 3 `ShouldBe` 1+ , Rem 5 3 `ShouldBe` 2+ , Rem 6 3 `ShouldBe` 0+ ]+testRem = Valid++testRemPow2+ ::+ "RemPow2"+ #########++ "Remainder of '1'"+ ~~~~~~~~~~~~~~~~~~++ It "1 `RemPow2` 1 is 1" (Is 1 (RemPow2 1 1))+ -* It "1 `RemPow2` 8 is 1" (Is 1 (RemPow2 1 8))++ -/-++ "Remainder of '3916441'"+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~++ It " `RemPow2` 1 is 1" (Is 1 (RemPow2 3916441 1))+ -* It " `RemPow2` 4 is 9" (Is 9 (RemPow2 3916441 4))+ -* It " `RemPow2` 8 is 153" (Is 153 (RemPow2 3916441 8))++testRemPow2 = Valid++testDiv+ :: Expect '[ Div 0 3 `ShouldBe` 0+ , Div 1 3 `ShouldBe` 0+ , Div 2 3 `ShouldBe` 0+ , Div 3 3 `ShouldBe` 1+ , Div 4 3 `ShouldBe` 1+ , Div 5 3 `ShouldBe` 1+ , Div 6 3 `ShouldBe` 2+ , Div 144 13 `ShouldBe` 11+ -- , Div 512 128 `ShouldBe` 11+ ]+testDiv = Valid++testNatBits+ :: "Type Level bit operations"+ ###########################++ "TestHighBit"+ ~~~~~~~~~~~~++ ShouldBeFalse (TestHighBit 127 8)+ -* ShouldBeFalse (TestHighBit 127 7)+ -* ShouldBeTrue (TestHighBit 127 6)+ -* ShouldBeFalse (TestHighBit 32 6)+ -* ShouldBeTrue (TestHighBit 32 5)+ -* ShouldBeFalse (TestHighBit 16 5)+ -* ShouldBeTrue (TestHighBit 16 4)+ -* ShouldBeFalse (TestHighBit 8 4)+ -* ShouldBeTrue (TestHighBit 8 3)+ -* ShouldBeFalse (TestHighBit 4 3)+ -* ShouldBeTrue (TestHighBit 4 2)+ -* ShouldBeFalse (TestHighBit 2 2)+ -* ShouldBeTrue (TestHighBit 2 1)+ -* ShouldBeFalse (TestHighBit 0 1)+ -* ShouldBeTrue (TestHighBit 1 0)++ -/-++ "ToBits"+ ~~~~~~~~~++ It "returns the empty list for a zero bit length"+ (ToBits 1023 0 `ShouldBe` ('[] :: [Bool]) )++ -* It "returns [] for a single unset bit"+ (ShouldBe ('[] :: [Bool]) (ToBits 0 1))++ -* It "returns [True] for a single set bit"+ (ShouldBe '[ 'True] (ToBits 1 1))++ -* It "returns [True, False] when getting two bits from 0x2"+ (ShouldBe '[ 'True, 'False] (ToBits 0x2 2))++ -* It "returns the list of bits in correct order"+ (ShouldBe '[ 'True, 'True, 'True, 'True+ , 'False, 'False, 'False, 'False]+ (ToBits 0xf0 8))++ -* It "returns no leading 'False (i.e. it omits leading zero bits)"+ (ShouldBe '[ 'True, 'True, 'True, 'True]+ (ToBits 0x0000000f 32))+ -/-++ "FromBits"+ ~~~~~~~~~++ It "returns 0 for '[]"+ (ShouldBe 0 (FromBits ('[] :: [Bool])))++ -* It "returns 0 for [False]"+ (ShouldBe 0 (FromBits '[ 'False]))++ -* It "returns 1 for [True]"+ (ShouldBe 1 (FromBits '[ 'True]))++ -* It "returns 2 for [True, False]"+ (ShouldBe 2 (FromBits '[ 'True, 'False]))++ -* It "returns 4 for [True, False, False]"+ (ShouldBe 4 (FromBits '[ 'True, 'False, 'False]))++ -* It "returns 5 for [True, False, True]"+ (ShouldBe 5 (FromBits '[ 'True, 'False, 'True]))+ -/-++ "ShiftBitsR"+ ~~~~~~~~~~~~++ It "returns the input bits for n == 0"+ (ShouldBe '[ 'True, 'False] (ShiftBitsR ['True, 'False] 0))++ -* It "returns '[] when shifting [True] 1 bits"+ (ShouldBe ('[] :: [Bool]) (ShiftBitsR '[ 'True ] 1))++ -* It "returns '[True] when shifting [True, True] 1 bits"+ (ShouldBe '[ 'True] (ShiftBitsR '[ 'True, 'True ] 1))++ -* It "returns (ToBits 12 8) when shifting (ToBits 97 8) 3 bits to the right"+ (ShouldBe (ToBits 12 8) (ShiftBitsR (ToBits 97 8) 3))+ -/-++ "GetMostSignificantBitIndex"+ ~~~~~~~~~~~~~~~++ It "returns 1 for 0"+ (ShouldBe 1 (GetMostSignificantBitIndex 64 0))++ -* It "returns 1 for 1"+ (ShouldBe 1 (GetMostSignificantBitIndex 64 1))++ -* It "returns 1 for 2"+ (ShouldBe 1 (GetMostSignificantBitIndex 64 2))++ -* It "returns 1 for 3"+ (ShouldBe 1 (GetMostSignificantBitIndex 64 3))++ -* It "returns 2 for 4"+ (ShouldBe 2 (GetMostSignificantBitIndex 64 4))++ -* It "returns 2 for 5"+ (ShouldBe 2 (GetMostSignificantBitIndex 64 4))++ -* It "returns 8 for 511"+ (ShouldBe 8 (GetMostSignificantBitIndex 64 511))++ -* It "returns 63 for (2^64 - 1)"+ (ShouldBe 63 (GetMostSignificantBitIndex 64 (2^64 - 1)))++ -/-+++ "ShiftR"+ ~~~~~~~~~++ It "returns '0' when shifting '42' 6 bits to the right"+ (ShouldBe 0 (ShiftR 64 42 6))+ -* It "returns 2 when shifting 512 8 bits to the right"+ (ShouldBe 2 (ShiftR 64 512 8))++testNatBits = Valid+#endif+++spec :: Spec+spec = do+ basicsSpec+#ifdef COMPLEXTESTS+ sizedSpec+ arraySpec+ describe "The Set of Type Functions" $+ it "is sound" $ do+ print (Valid :: Expect (BitRecordSize (Flag .+. Field 7) `Is` 8))+ print testTakeLastN+ print testRem+ print testRemPow2+ print testDiv+ print testNatBits+ print checkTestRecAligned+ print checkTestRecUnAligned+ describe "showARecord" $ do+ it "prints (Field 4 .+. (Field 4 := 0x96)) to \"<..>0110\"" $+ let actual = showRecord (Proxy :: Proxy (Field 4 .+. Field 4 := 0x96))+ in actual `shouldBe` "bits(4)\nbits(4) := 10010110 (hex: 96 dec: 150)"+ describe "StaticLazybytestringbuilder" $ do+ it "writes (and flushes) bits" $+ let rec = Proxy+ rec :: Proxy TestRecUnAligned+ actualB :: Builder+ actualB =+ runBitStringBuilderHoley+ (bitStringBuilderHoley rec)+ 1+ 3+ 7+ actual = printBuilder actualB+ in actual `shouldBe`+ "<< 01 00 06 00 00 00 00 0f fc >>"+ describe "Formatting sub-byte fields" $ do+ it "only the addressed bits are copied to the output" $+ property $ \value ->+ let rec = Proxy+ rec :: Proxy (Field 4 := 0 .+. "here" @: Field 4)+ actualB :: Builder+ actualB = runBitStringBuilderHoley (bitStringBuilderHoley rec) value+ actual = printBuilder actualB+ expected = printf "<< %.2x >>" (value .&. 0xf)+ in actual `shouldBe` expected+ it "renders (Flag := 0 .+. Field 7 := 130) to << 02 >>" $+ let rec = Proxy+ rec :: Proxy (Flag := 'False .+. Field 7 := 130)+ actual = printBuilder b+ where b = runBitStringBuilderHoley (bitStringBuilderHoley rec)+ in actual `shouldBe` "<< 02 >>"+ describe "ByteStringBuilder" $+ describe "runBitStringBuilderHoley" $+ it "0x01020304050607 to << 00 01 02 03 04 05 06 07 >>" $+ let expected = "<< 00 01 02 03 04 05 06 07 >>"+ actual =+ printBuilder+ (runBitStringBuilderHoley+ (bitStringBuilderHoley+ (bitString 64 0x01020304050607)))+ in actual `shouldBe` expected+#endif++instance (KnownNat n, n <= 64) => Arbitrary (B n) where+ arbitrary = do+ let h = 2^(n'-1) - 1+ n' = fromIntegral (natVal (Proxy @n)) :: Int+ x <- choose (0, h + h + 1)+ return (B x)
spec/BoxFieldsSpec.hs view
@@ -2,6 +2,9 @@ import Test.Hspec import Data.ByteString.IsoBaseFileFormat.Boxes+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.ReExports+import Data.ByteString.IsoBaseFileFormat.Util.BoxFields import qualified Data.ByteString.Lazy as BL import Control.Exception (evaluate)
spec/BoxSpec.hs view
@@ -1,7 +1,8 @@ module BoxSpec (spec) where import Test.Hspec-import Data.ByteString.IsoBaseFileFormat.Boxes+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.ReExports import qualified Data.ByteString.Builder as B import qualified Data.ByteString.Lazy as BL import qualified Data.Binary.Get as Binary
− spec/BrandTypeSpec.hs
@@ -1,70 +0,0 @@-module BrandTypeSpec- (spec)- where--import Test.Hspec-import Data.ByteString.IsoBaseFileFormat.Boxes-import Data.ByteString.IsoBaseFileFormat.Brands.Types-import Data.ByteString.Lazy (unpack)--spec :: Spec-spec =- describe "mediaBuilder" $- do describe "Empty BoxLayout" $- it "accepts valid box content types" $- let test =- mediaBuilder (Proxy :: Proxy TestBrandEmpty)- NoBoxes- in printBuilder test- describe "Single Box BoxLayout" $- it "accepts valid box content types" $- let test =- mediaBuilder (Proxy :: Proxy TestBrandSingle)- (singletonBox testBox1)- in printBuilder test- describe "Multiple nested Boxes BoxLayout" $- it "accepts valid box content types" $- let test =- mediaBuilder (Proxy :: Proxy TestBrandNested)- (singletonBox (testParentBox1 $: testBox1))- in printBuilder test--printBuilder :: Builder -> IO ()-printBuilder b =- putStrLn $ unlines $ (" "++) <$> lines (show (unpack (toLazyByteString b)))--data TestBox1--instance IsBox TestBox1 where- type BoxContent TestBox1 = ()--type instance BoxTypeSymbol TestBox1 = "tst1"--testBox1 :: Box TestBox1-testBox1 = Box ()--data TestParentBox1--instance IsBox TestParentBox1 where- type BoxContent TestParentBox1 = ()--type instance BoxTypeSymbol TestParentBox1 = "par1"--testParentBox1- :: Boxes ts -> Box (ContainerBox TestParentBox1 ts)-testParentBox1 = containerBox ()--data TestBrandEmpty--instance IsMediaFileFormat TestBrandEmpty where- type BoxLayout TestBrandEmpty = Boxes '[]--data TestBrandSingle--instance IsMediaFileFormat TestBrandSingle where- type BoxLayout TestBrandSingle = Boxes '[OM_ TestBox1]--data TestBrandNested--instance IsMediaFileFormat TestBrandNested where- type BoxLayout TestBrandNested = Boxes '[OM TestParentBox1 '[OM_ TestBox1]]
− spec/DashSpec.hs
@@ -1,105 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}-module DashSpec (spec) where -- TODO rename to mp4 audio init spec--import Test.Hspec-import Data.ByteString.IsoBaseFileFormat.Brands.Dash-import qualified Data.ByteString.Lazy as BL-import Data.Text ()--spec :: Spec-spec =- do describe "SingleAudioTrackInit version 0" $- do it "renders some output at all" $- do createionTime <- mp4CurrentTime- let ct :: Word32- ct = fromScalar createionTime- ct3 = (ct `shiftR` 24) .&. 255- ct2 = (ct `shiftR` 16) .&. 255- ct1 = (ct `shiftR` 8) .&. 255- ct0 = (ct `shiftR` 0) .&. 255- cts :: [Word8]- cts = fromIntegral <$> [ct3,ct2,ct1,ct0]- let args = exampleSingleTrackInit createionTime- doc = mkSingleTrackInit args- rendered = BL.unpack $ toLazyByteString $ doc- expected =- [- -- ftyp box- 0,0,0,28,102,116,121,112,100,97,115,104,0,0,0,0- ,105,115,111,109,105,115,111,53,109,112,52,50- -- moov box- ,0,0,1,180,109 ,111 ,111 ,118- -- mvhd box- ,0 ,0 ,0 ,108 ,109 ,118 ,104 ,100 ,0 ,0 ,0 ,0]- ++ cts ++ [0 ,0 ,0 ,0 ,0- ,1 ,95 ,144 ,0 ,1 ,95 ,144 ,0 ,1 ,0 ,0 ,1 ,0 ,0 ,0- ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0- ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0- ,0 ,0 ,0 ,0 ,0 ,0 ,64 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0- ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0- ,255 ,255 ,255 ,255- -- trak box- ,0 ,0 ,1,64- ,116 ,114 ,97 ,107- -- tkhd box- ,0 ,0 ,0 ,92- ,116 ,107 ,104 ,100- ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0- ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,1 ,95 ,144 ,0 ,0- ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0- ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0- ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0- ,0 ,64 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0- -- mdia box- ,0,0,0,220- ,109,100,105,97- ,0,0,0,32,109,100,104,100,0,0,0,0- ,0,0,0,0,0,0,0,0,0,1,95,144,0,0,0,0,16,181,0,0- -- hdlr box- ,0,0,0,44- ,104,100,108,114- ,0,0,0,0,0,0,0,0,115,111,117,110,0,0,0,0,0,0,0,0,0,0,0,0- ,72,101,108,108,111,32,119,111,114,108,100,0- -- minf box- ,0,0,0,136- ,109,105,110,102- ,0,0,0,16- ,115,109,104,100,0,0,0,0,0,0,0,0- -- dinf box- ,0,0,0,36- ,100,105,110,102- -- dref box- ,0,0,0,28- ,100,114,101,102- ,0,0,0,0,0,0,0,1- -- url box- ,0,0,0,12- ,117,114,108,32- ,0,0,0,1- -- stbl- ,0,0,0,76,115,116,98,108- -- stsd- ,0,0,0,52,115,116,115,100- ,0,0,0,0,0,0,0,1- -- mp4a- ,0,0,0,36,109,112,52,97- ,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,2,0,16,0,0,0,0- ,187,128,0,0- -- stts- ,0,0,0,16,115,116,116,115,0,0,0,0,0,0,0,0]- BL.writeFile "/tmp/isobmff-test-case-dash-spec.mp4" (BL.pack rendered)- rendered `shouldBe`- expected--exampleSingleTrackInit :: U32 "creation_time" -> SingleAudioTrackInit-exampleSingleTrackInit creationTime =- SingleAudioTrackInit- (MovieHeader $- V0 (creationTime :+ 0 :+ Template :+ durationFromSeconds Template 1) :+- def)- (TrackHeader $- V0 (0 :+ 0 :+ 1 :+ Constant :+ durationFromSeconds Template 1) :+- def)- (MediaHeader def)- (namedAudioTrackHandler "Hello world")- (SoundMediaHeader def)
spec/DataReferenceSpec.hs view
@@ -1,5 +1,6 @@ module DataReferenceSpec (spec) where +import Data.ByteString.IsoBaseFileFormat.Box import Data.ByteString.IsoBaseFileFormat.Boxes import Test.Hspec
+ spec/ElementaryStreamDescriptorSpec.hs view
@@ -0,0 +1,40 @@+{-# LANGUAGE OverloadedStrings #-}+module ElementaryStreamDescriptorSpec (spec) where++import Test.Hspec+import Data.ByteString.Mp4.Boxes.ElementaryStreamDescriptor+import Data.ByteString.Mp4.Boxes.AudioSpecificConfig+import Data.ByteString.Mp4.Boxes.DecoderConfigDescriptor+import Data.ByteString.Mp4.Boxes.DecoderSpecificInfo+import Data.ByteString.IsoBaseFileFormat.ReExports+import Data.ByteString.IsoBaseFileFormat.Box++spec :: Spec+spec = do+#ifndef COMPLEXTESTS+ return ()+#else+ describe "EsdBox" $ do+ let eb = esdBox (Proxy @TestEsDescriptor) False 0 0 0+ it "has the correct size" $+ boxSize eb `shouldBe` 39+ it "generates the expected bits" $+ printBuilder (boxBuilder eb)+ `shouldBe` "<< 00 00 00 27 65 73 64 73 00 00 00 00 03 19 00 01 00 04 11 40 15 00 00 00 00 00 00 00 00 00 00 00 05 02 11 98 06 01 02 >>"++type TestEsDescriptor =+ ESDescriptorMp4File+ (StaticFieldValue "esId" 1)+ TestConfigDescriptor++type TestConfigDescriptor =+ DecoderConfigDescriptor+ 'AudioIso14496_3+ 'AudioStream+ '[AudioConfigAacMinimal+ 'AacLc+ DefaultGASpecificConfig+ (SetEnum "samplingFreq" SamplingFreq 'SF48000)+ (SetEnum "channelConfig" ChannelConfig 'SinglePair)]+ '[]+#endif
+ spec/EnumSpec.hs view
@@ -0,0 +1,29 @@+{-# LANGUAGE UndecidableInstances #-}+module EnumSpec (spec) where++import Data.Proxy+import Data.Type.BitRecords+import Data.Type.Equality ()+import Prelude hiding ((.), id)+import Test.Hspec++spec = do+ describe "ToPretty" $ do+ it "renders as a record using showRecord" $+ showRecord (Proxy @(BitRecordOfEnum (EnumParam "test" TestEnumExt)))+ `shouldBe` "test: <<enum>>(2)"+ describe "BitStringBuilder" $ do+ it "produces binary output" $+ bitStringPrinter (Proxy @(BitRecordOfEnum (EnumParam "test" TestEnumExt)))+ (MkEnumValue (Proxy @'A))+ `shouldBe` "<< 40 >>"++type TestEnumExt = ExtEnum TestEnum 2 'Be FieldU16+++data TestEnum =+ A | Be | C++type instance FromEnum TestEnum 'A = 1+type instance FromEnum TestEnum 'Be = 2+type instance FromEnum TestEnum 'C = 4
+ spec/ExpandableSpec.hs view
@@ -0,0 +1,68 @@+{-# LANGUAGE UndecidableInstances #-}+module ExpandableSpec (spec) where+++import Data.ByteString.Builder+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.ReExports+import qualified Data.ByteString.Lazy as B+import Data.ByteString.Mp4.Boxes.Expandable+import Test.Hspec+import Test.QuickCheck+++spec :: Spec+spec = do+ describe "StaticExpandable" $ do+ describe "ExpandableSizeLastChunk" $+ it "renders both 2 and 130 as 00000010 " $ do+ let actual130 = bitStringPrinter (Proxy :: Proxy ((ExpandableSizeLastChunk 130)))+ actual2 = bitStringPrinter (Proxy :: Proxy (ExpandableSizeLastChunk 2))+ actual130 `shouldBe` actual2+ actual2 `shouldBe` "<< 02 >>"+ describe "ExpandableSize" $+ it "creates a stdandard conform size representation for the size 130" $+ let actualStr = bitStringPrinter (Proxy :: Proxy (ExpandableSize 130))+ in actualStr `shouldBe` "<< 81 02 >>"++ -- TODO add new test+ -- it "has a boxSize of 3 when using a 16-bit body value" $+ -- boxSize (staticExpandable (Proxy :: Proxy (RecordField (Field 16 := 1234 )))) `shouldBe` BoxSize 3+ -- it "has a boxBuilder that writes the body in big endian byte order for a 32-bit body value" $+ -- B.unpack (toLazyByteString (boxBuilder (staticExpandable (Proxy :: Proxy (RecordField (Field 32 := 0x12345678 ))))))+ -- `shouldBe` [4, 0x12, 0x34, 0x56, 0x78]+ it "writes the size 128 as [ 0b10000001, 0b00000000 ] " $+ let actual = B.unpack $ toLazyByteString (boxBuilder (Expandable (ETC 128)))+ expected = [ 129, 0 ]+ in actual `shouldBe` expected+ it "writes the size (2 ^ 21) as [ 0b10000001, 0b10000000, 0b10000000, 0b00000000 ] " $+ let actual = B.unpack $ toLazyByteString (boxBuilder (Expandable (ETC (2^(21 :: Int)))))+ expected = [ 129, 128, 128, 0 ]+ in actual `shouldBe` expected+ it "writes the size (2 ^ 21 - 1) as [ 0b11111111, 0b11111111, 0b01111111 ] " $+ let actual = B.unpack $ toLazyByteString (boxBuilder (Expandable (ETC (2^(21 :: Int) - 1))))+ expected = [ 255, 255, 127 ]+ in actual `shouldBe` expected+ it "writes size according to the spec" $+ property $ \etc@(ETC s) ->+ let expectedBoxSize =+ BoxSize $+ s ++ if s < 2 ^ ( 7 :: Int) then 1+ else if s < 2 ^ (14 :: Int) then 2+ else if s < 2 ^ (21 :: Int) then 3 else 4+ actualBoxSize = boxSize (Expandable etc)+ in+ actualBoxSize `shouldBe` expectedBoxSize+++instance Arbitrary ExpandableTestContent where+ arbitrary = ETC <$> choose (0, 2^(28::Integer) - 1)++newtype ExpandableTestContent =+ ETC Word64+ deriving (Show, Eq)++instance IsBoxContent ExpandableTestContent where+ boxSize (ETC s) = BoxSize s+ boxBuilder _ = mempty
+ spec/MediaFileSpec.hs view
@@ -0,0 +1,71 @@+module MediaFileSpec+ (spec)+ where++import Test.Hspec+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.MediaFile+import Data.ByteString.IsoBaseFileFormat.ReExports+import Data.ByteString.Lazy (unpack)++spec :: Spec+spec =+ describe "mediaBuilder" $+ do describe "Empty BoxLayout" $+ it "accepts valid box content types" $+ let test =+ mediaBuilder (Proxy :: Proxy TestBrandEmpty)+ NoBoxes+ in printBuilderStdOut test+ describe "Single Box BoxLayout" $+ it "accepts valid box content types" $+ let test =+ mediaBuilder (Proxy :: Proxy TestBrandSingle)+ (singletonBox testBox1)+ in printBuilderStdOut test+ describe "Multiple nested Boxes BoxLayout" $+ it "accepts valid box content types" $+ let test =+ mediaBuilder (Proxy :: Proxy TestBrandNested)+ (singletonBox (testParentBox1 $: testBox1))+ in printBuilderStdOut test++printBuilderStdOut :: Builder -> IO ()+printBuilderStdOut b =+ putStrLn $ unlines $ (" "++) <$> lines (show (unpack (toLazyByteString b)))++data TestBox1++instance IsBox TestBox1 where+ type BoxContent TestBox1 = ()++type instance BoxTypeSymbol TestBox1 = "tst1"++testBox1 :: Box TestBox1+testBox1 = Box ()++data TestParentBox1++instance IsBox TestParentBox1 where+ type BoxContent TestParentBox1 = ()++type instance BoxTypeSymbol TestParentBox1 = "par1"++testParentBox1+ :: Boxes ts -> Box (ContainerBox TestParentBox1 ts)+testParentBox1 = containerBox ()++data TestBrandEmpty++instance IsMediaFileFormat TestBrandEmpty where+ type BoxLayout TestBrandEmpty = Boxes '[]++data TestBrandSingle++instance IsMediaFileFormat TestBrandSingle where+ type BoxLayout TestBrandSingle = Boxes '[OM_ TestBox1]++data TestBrandNested++instance IsMediaFileFormat TestBrandNested where+ type BoxLayout TestBrandNested = Boxes '[OM TestParentBox1 '[OM_ TestBox1]]
+ spec/Mp4AudioFileSpec.hs view
@@ -0,0 +1,195 @@+{-# LANGUAGE OverloadedStrings #-}+module Mp4AudioFileSpec (spec) where -- TODO rename to mp4 audio init spec++import Test.Hspec+import Data.ByteString.Mp4.Boxes.BaseDescriptor+import Data.ByteString.Mp4.Boxes.AudioSpecificConfig+import Data.ByteString.Mp4.Boxes.Mp4AudioSampleEntry+import Data.ByteString.Mp4.AudioStreaming+import qualified Data.ByteString.Lazy as BL+import Data.Text ()++spec :: Spec+spec =+ do+ describe "Mp4AacAudioDecoderConfigDescriptor" $ do+ it "can be pretty printed" $+ showRecord (Proxy @(BitRecordOfDescriptor+ $~ (Eval (Mp4AacAudioDecoderConfigDescriptor+ (AudioConfigAacLc+ (EnumParam "samplingFreq" SamplingFreq)+ (EnumParam "channelConfig" ChannelConfig))))))+ `shouldEndWith`+ "has-gas-extension: boolean := no"++#ifdef COMPLEXTESTS+ it "can be transformed to binary output" $+ let actual =+ bitStringPrinter+ (Proxy @(BitRecordOfDescriptor+ $~ Eval (Mp4AacAudioDecoderConfigDescriptor+ (AudioConfigAacLc+ (EnumParam "samplingFreq" SamplingFreq)+ (EnumParam "channelConfig" ChannelConfig)))))+ True+ 1+ 2+ 3+ (MkEnumValue (Proxy @'SF16000))+ (MkEnumValue (Proxy @'SingleChannel))+ expexted = "<< 04 11 40 17 00 00 01 00 00 00 02 00 00 00 03 05 02 14 08 >>"+ in actual `shouldBe` expexted+ describe "Mp4AacLcEsDescriptor" $+ do it "can be transformed to binary output" $+ bitStringPrinter (Proxy @(BitRecordOfDescriptor $~ Eval Mp4AacLcEsDescriptor))+ False 0 0 0+ (MkEnumValue (Proxy @'SF48000))+ (MkEnumValue (Proxy @'SingleChannel))+ `shouldBe`+ "<< 03 19 00 01 00 04 11 40 15 00 00 00 00 00 00 00 00 00 00 00 05 02 11 88 06 01 02 >>"+ it "can be pretty printed" $+ showRecord (Proxy @(BitRecordOfDescriptor $~ Eval Mp4AacLcEsDescriptor))+ `shouldStartWith` "base-descriptor: 03\n"+ describe "Mp4HeAacEsDescriptor" $+ do it "can be transformed to binary output" $+ bitStringPrinter (Proxy @(BitRecordOfDescriptor $~ Eval Mp4HeAacEsDescriptor))+ False 0 0 0+ (MkEnumValue (Proxy @'SF48000))+ (MkEnumValue (Proxy @'SingleChannel))+ (MkEnumValue (Proxy @'SF24000))+ `shouldBe`+ "<< 03 1a 00 01 00 04 12 40 15 00 00 00 00 00 00 00 00 00 00 00 05 03 29 8b 08 03 00 81 00 >>"+ it "can be pretty printed" $+ showRecord (Proxy @(BitRecordOfDescriptor $~ Eval Mp4HeAacEsDescriptor))+ `shouldStartWith` "base-descriptor: 03\n"+ describe "SingleAudioTrackInit version 0" $+ do it "renders some output at all" $+ do creationTime <- mp4CurrentTime+ let ct :: Word32+ ct = fromScalar creationTime+ ct3 = (ct `shiftR` 24) .&. 255+ ct2 = (ct `shiftR` 16) .&. 255+ ct1 = (ct `shiftR` 8) .&. 255+ ct0 = (ct `shiftR` 0) .&. 255+ cts :: [Word8]+ cts = fromIntegral <$> [ct3,ct2,ct1,ct0]+ let args = exampleSingleTrackInit creationTime+ doc = buildAacMp4StreamInit args+ rendered = BL.unpack $ toLazyByteString $ doc+ expected =+ [+ -- ftyp box+ 0,0,0,32+ ,102,116,121,112+ ,105,115,111,53,0,0,0,0+ ,105,115,111,109+ ,105,115,111,53+ ,100,97,115,104+ ,109,112,52,50+ -- skip box+ ,0,0,0,56+ ,115,107,105,112+ ,76,105,110,100,101,110,98,97,117,109,32,71,109,98,72,32,105+ ,115,111,98,109,102,102,45,98,117,105,108,100,101,114,44,32+ ,83,118,101,110,32,72,101,121,108,108,32,50,48,49,54+ -- moov box+ ,0,0,2,57,109 ,111 ,111 ,118+ -- mvhd box+ ,0 ,0 ,0 ,108 ,109 ,118 ,104 ,100 ,0 ,0 ,0 ,0]+ ++ cts ++ cts +++ [0 ,1 ,95 ,144+ ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,1 ,0 ,0 ,0+ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0+ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0+ ,0 ,0 ,0 ,0 ,0 ,0 ,64 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0+ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0+ ,0 ,0 ,0 ,2+ -- trak box+ ,0 ,0 ,1,157+ ,116 ,114 ,97 ,107+ -- tkhd box+ ,0 ,0 ,0 ,92+ ,116 ,107 ,104 ,100+ ,0 ,0 ,0 ,7]+ ++ cts ++ cts +++ [0 ,0 ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0+ ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,1 ,0 ,0 ,0+ ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0+ ,0 ,1 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0+ ,0 ,64 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0+ -- mdia box+ ,0,0,1,57+ ,109,100,105,97+ -- mdhd box+ ,0,0,0,32+ ,109,100,104,100+ ,0,0,0,0]+ ++ cts ++ cts +++ [0,0,187,128+ ,0,0,0,0+ ,85,196+ ,0,0+ -- hdlr box+ ,0,0,0,44+ ,104,100,108,114+ ,0,0,0,0,0,0,0,0,115,111,117,110,0,0,0,0,0,0,0,0,0,0,0,0+ ,72,101,108,108,111,32,119,111,114,108,100,0+ -- minf box+ ,0,0,0,229+ ,109,105,110,102+ -- smhd box+ ,0,0,0,16+ ,115,109,104,100,0,0,0,0,0,0,0,0+ -- dinf boimport Data.ByteString.IsoBaseFileFormat.Boxes+ ,0,0,0,36+ ,100,105,110,102+ -- dref box+ ,0,0,0,28+ ,100,114,101,102+ ,0,0,0,0,0,0,0,1+ -- url box+ ,0,0,0,12+ ,117,114,108,32+ ,0,0,0,1+ -- stbl box+ ,0,0,0,169+ ,115,116,98,108+ -- stsd box+ ,0,0,0,93+ ,115,116,115,100+ ,0,0,0,0,0,0,0,1+ -- mp4a box+ ,0,0,0,77+ ,109,112,52,97+ ,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,16,0,0,0,0,187,128,0,0+ -- esds box+ ,0,0,0,41+ ,101,115,100,115+ ,0,0,0,0,3,26,0,1,0,4,18,64,21+ ,0,0,0,0,0,0,0,0,0,0,0,5,3,41,137,136,3,0,129,0+ -- stts box+ ,0,0,0,16+ ,115,116,116,115,0,0,0,0,0,0,0,0+ -- stsc box+ ,0,0,0,16+ ,115,116,115,99,0,0,0,0,0,0,0,0+ -- stsz box+ ,0,0,0,20+ ,115,116,115,122,0,0,0,0,0,0,0,0,0,0,0,0+ -- stc0 box+ ,0,0,0,16+ ,115,116,99,111,0,0,0,0,0,0,0,0+ -- mvex box+ ,0,0,0,40+ ,109,118,101,120+ -- trex box+ ,0,0,0,32+ ,116,114,101,120,0,0,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0]+ BL.writeFile "/tmp/isobmff-test-case-dash-spec.mp4" (BL.pack rendered)+ rendered `shouldBe`+ expected++exampleSingleTrackInit :: U32 "creation_time" -> AacMp4StreamConfig+exampleSingleTrackInit creationTime =+ AacMp4StreamConfig creationTime "Hello world" True SF48000 SingleChannel+#endif
+ spec/Mp4AudioSampleEntry.hs view
@@ -0,0 +1,27 @@+module Mp4AudioSampleEntry ( spec ) where++import Data.ByteString.Builder+import Data.ByteString.IsoBaseFileFormat.ReExports+import qualified Data.ByteString.Lazy as B+import Data.ByteString.Mp4.Boxes.Mp4AudioSampleEntry+import Data.Type.BitRecords+import Test.Hspec++spec :: Spec+spec = describe "AudioObjectType" $+ it "type-checks" $ do+ print testAudioObjectType++testAudioObjectType = Valid+testAudioObjectType ::++ "Audio Object Types"+ #####################++ "Small Audio Object Types"+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~+ 5 `ShouldBe` BitRecordSize (ToBitRecord (AudioObjectType 30)) -/-++ "Big Audio Object Types"+ ~~~~~~~~~~~~~~~~~~~~~~~~+ 11 `ShouldBe` BitRecordSize (ToBitRecord (AudioObjectType 31))
+ spec/Mp4AudioSegmentSpec.hs view
@@ -0,0 +1,75 @@+{-# LANGUAGE OverloadedStrings #-}+module Mp4AudioSegmentSpec (spec) where++import qualified Data.ByteString as BS+import Data.ByteString.IsoBaseFileFormat.ReExports+import qualified Data.ByteString.Lazy as BL+import Data.ByteString.Mp4.AudioStreaming+import Data.Text ()+import Test.Hspec++spec :: Spec+spec =+ describe "AacMp4TrackFragment" $+ do let args = moof+ doc = buildAacMp4TrackFragment args+ rendered = BL.unpack $ toLazyByteString $ doc+ dataOffset = 120+ expected =+ [+ -- styp box+ 0,0,0,24+ ,115,116,121,112+ ,109,115,100,104,0,0,0,0+ ,109,115,100,104+ ,100,97,115,104+ -- moov box [offset here: 32]+ ,0,0,0,112+ ,109,111,111,102+ -- mfhd box+ ,0,0,0,16+ ,109,102,104,100+ ,0,0,0,0,0,0,0,13+ -- traf+ ,0,0,0,88+ ,116,114,97,102+ -- tfhd+ ,0,0,0,16+ ,116,102,104,100+ ,0,2,0,0,0,0,0,1+ -- tfdt+ ,0,0,0,20+ ,116,102,100,116+ ,1,0,0,0,0,0,0,0,0,0,0,37+ -- trun+ ,0,0,0,44+ ,116,114,117,110+ ,0,0,7,1+ ,0,0,0,2+ ,0,0,0,dataOffset+ -- sample 1+ ,0,0,0,23 -- duration+ ,0,0,0,192 -- length+ ,2,0,0,0 -- flags+ -- sample 2+ ,0,0,0,23+ ,0,0,0,192+ ,2,0,0,0+ -- mdat+ ,0,0,1,136+ ,109,100,97,116]+ -- sample 1+ ++ [0..191]+ -- sample 2+ ++ [0..191]+ it "renders the exact expectected output" $ do+#ifdef COMPLEXTESTS+ BL.writeFile "/tmp/isobmff-test-case-dash-spec.m4s" (BL.pack rendered)+#endif+ rendered `shouldBe` expected+ it "calculates the data-offset correctly" $+ drop ((fromIntegral dataOffset) + 12 * 2) rendered+ `shouldBe` ([0..191] ++ [0..191])++moof :: AacMp4TrackFragment+moof = AacMp4TrackFragment 13 37 (replicate 2 (23, BS.pack [0..191]))
spec/TypeLayoutSpec.hs view
@@ -5,7 +5,7 @@ import Test.Hspec import GHC.TypeLits () import Data.ByteString.IsoBaseFileFormat.Util.TypeLayout-import Data.ByteString.IsoBaseFileFormat.Boxes.Box+import Data.ByteString.IsoBaseFileFormat.Box spec :: Spec spec =@@ -25,6 +25,7 @@ describe "SomeMandatory" $ do it "validates a singleton container" $ test5a `shouldBe` () it "validates a multi-element container" $ test5b `shouldBe` ()+#ifdef COMPLEXTESTS it "validates a Mix of SomeMandatory, OnceOptional, SomeOptional" $ do test6a `shouldBe` () test6b `shouldBe` ()@@ -34,6 +35,7 @@ test7a `shouldBe` () test7b `shouldBe` () test7c `shouldBe` ()+#endif ---- data Foo@@ -84,7 +86,10 @@ type TestType5b = Box (ContainerBox Foo '[Bar, Bar]) test5b :: (IsRuleConform TestType5b TestRule5 ~ 'True) => () test5b = ()++ ----+#ifdef COMPLEXTESTS type TestRule6 = (ContainerBox Foo '[ OnceOptionalX (MatchSymbol "baz ")@@ -106,6 +111,8 @@ type TestType6d = Box (ContainerBox Foo '[Bar,Foo]) test6d :: (IsRuleConform TestType6d TestRule6 ~ 'True) => () test6d = ()++ ---- type TestRule7 = TopLevel (ContainerBox Foo@@ -142,3 +149,4 @@ ]) test7c :: (IsRuleConform TestType7c TestRule7 ~ 'True) => () test7c = ()+#endif
+ src/Data/ByteString/IsoBaseFileFormat/Box.hs view
@@ -0,0 +1,379 @@+{-# LANGUAGE UndecidableInstances #-}++-- | Definition of the most basic element in an ISOBMFF file: a /box/. See+-- Chapter 4 in the standard document. A box is a container with a type, a+-- size, some data and some nested boxes. The standard defines - among other+-- characteristics - available box types and their semantics, the fields they+-- contain and how they are nested into each other. This library tries to+-- capture some of these characteristics using modern Haskell type system+-- features, in order to provide compile time checks for (partial) standard+-- compliance.+module Data.ByteString.IsoBaseFileFormat.Box where++import Data.ByteString.IsoBaseFileFormat.ReExports+import Data.Singletons.Prelude.List ((:++),+ Length)+import qualified Data.Text as T+import qualified Data.Text.Encoding as T+import qualified Data.ByteString as B++-- * Box Type Classes+-- | Base class for all (abstract/phantom/normal-) types that represent boxes+class (KnownSymbol (BoxTypeSymbol t), IsBoxContent (BoxContent t))+ => IsBox (t :: Type) where+ type BoxContent t+ type BoxContent t = t+ toBoxType :: proxy t -> BoxType+ toBoxType _ = parseBoxType (Proxy :: Proxy (BoxTypeSymbol t))++-- | A type family used by the type-level consistency checks. It is required+-- that an instance of this type family exists for every 'IsBox' instance.+-- This family could not be associative since it is used by type families that+-- cannot have type class constraints.+type family BoxTypeSymbol (t :: k) :: Symbol++-- | Types that go into a box. A box content is a piece of data that can be+-- reused in different instances of 'IsBox'. It has no 'BoxType' and hence+-- defines no box.+class IsBoxContent a where+ boxSize :: a -> BoxSize+ boxBuilder :: a -> Builder++-- * Box Contents+-- TODO move all IsBoxContent stuff to BoxContent.hs++-- | A type that wraps the contents of a box and the box type.+data Box b where+ Box ::+ !(BoxContent b) -> Box b++instance IsBox b => IsBox (Box b) where+ type BoxContent (Box b) = BoxContent b+ toBoxType _ = toBoxType (Proxy :: Proxy b)++type instance BoxTypeSymbol (Box b) = BoxTypeSymbol b++instance IsBox cnt => IsBoxContent (Box cnt) where+ boxBuilder b@(Box cnt) = sB <> tB <> sExtB <> tExtB <> cntB+ where s = boxSize b+ t = toBoxType b+ sB = boxBuilder s+ sExtB = boxBuilder (BoxSizeExtension s)+ tB = boxBuilder t+ tExtB = boxBuilder (BoxTypeExtension t)+ cntB = boxBuilder cnt+ boxSize b@(Box cnt) = sPayload + boxSize (BoxSizeExtension sPayload)+ where sPayload =+ boxSize (BoxSize undefined) + boxSize t + boxSize cnt ++ boxSize (BoxTypeExtension t)+ t = toBoxType b++instance (Default (BoxContent b)) => Default (Box b) where+ def = Box def++-- | Compose 'BoxContent' and 'Boxes' under the Constraint that they are+-- composable.+data ContainerBox b (bs :: [Type]) where+ ContainerBox :: IsBox b => !(BoxContent b) -> !(Boxes bs) -> ContainerBox b bs++instance (IsBox b) => IsBox (ContainerBox b bs)++type instance BoxTypeSymbol (ContainerBox b bs) = BoxTypeSymbol b++instance IsBoxContent (ContainerBox b bs) where+ boxSize (ContainerBox c bs) = boxSize (c :+ bs)+ boxBuilder (ContainerBox c bs) = boxBuilder (c :+ bs)++-- | A heterogenous collection of boxes.+data Boxes (boxTypes :: [Type]) where+ NoBoxes :: Boxes '[]+ (:.) :: IsBox l => !(Box l) -> !(Boxes r) -> Boxes (Box l ': r)+ -- | Create a 'Boxes' collection from two 'Box'es+ (:<>) :: !(Boxes l) -> !(Boxes r) -> Boxes (l :++ r)+ (:|) :: (IsBox l, IsBox r) => !(Box l) -> !(Box r) -> Boxes '[Box l, Box r]++infixr 1 :<>+infixr 2 :.+infixr 2 :|+infixr 3 $:++-- | Apply a function to a 'Boxes' collection containing only a single 'Box'.+($:) :: IsBox l => (Boxes '[Box l] -> r) -> Box l -> r+($:) f = f . singletonBox++-- | Create a 'Boxes' collection with a single 'Box'.+singletonBox :: IsBox l => Box l -> Boxes '[Box l]+singletonBox b = b :. NoBoxes++-- | Get the elements in a type level array+typeListLength :: forall a proxy (ts :: [k]) . (KnownNat (Length ts), Num a)+ => proxy ts -> a+typeListLength _ = fromIntegral (natVal (Proxy :: Proxy (Length ts)))++instance IsBoxContent (Boxes bs) where+ boxSize NoBoxes = 0+ boxSize (l :. r) = boxSize l + boxSize r+ boxSize (l :| r) = boxSize l + boxSize r+ boxSize (l :<> r) = boxSize l + boxSize r+ boxBuilder NoBoxes = mempty+ boxBuilder (l :. r) = boxBuilder l <> boxBuilder r+ boxBuilder (l :| r) = boxBuilder l <> boxBuilder r+ boxBuilder (l :<> r) = boxBuilder l <> boxBuilder r++-- | A box that contains no fields, but nested boxes.+containerBox :: (IsBox t)+ => BoxContent t -> Boxes ts -> Box (ContainerBox t ts)+containerBox c bs = Box (ContainerBox c bs)++-- * Box Size and Type+-- | The size of the box. If the size is limited to a (fixed) value, it can be+-- provided as a 'Word64' which will be represented as either a 32bit compact+-- size or as 64 bit /largesize/. If 'UnlimitedSize' is used, the box extends to+-- the end of the file.+data BoxSize+ = UnlimitedSize+ | BoxSize !Word64+ deriving (Show,Eq)++fromBoxSize :: Num a => a -> BoxSize -> a+fromBoxSize !fallback UnlimitedSize = fallback+fromBoxSize _fallback (BoxSize !s) = fromIntegral s++instance IsBoxContent BoxSize where+ boxSize _ = BoxSize 4+ boxBuilder UnlimitedSize = word32BE 0+ boxBuilder (BoxSize n) =+ word32BE $+ if n < (4294967296 :: Word64)+ then fromIntegral n+ else 1++instance Num BoxSize where+ (+) UnlimitedSize _ = UnlimitedSize+ (+) _ UnlimitedSize = UnlimitedSize+ (+) (BoxSize l) (BoxSize r) = BoxSize (l + r)+ (-) UnlimitedSize _ = UnlimitedSize+ (-) _ UnlimitedSize = UnlimitedSize+ (-) (BoxSize l) (BoxSize r) = BoxSize (l - r)+ (*) UnlimitedSize _ = UnlimitedSize+ (*) _ UnlimitedSize = UnlimitedSize+ (*) (BoxSize l) (BoxSize r) = BoxSize (l * r)+ abs UnlimitedSize = UnlimitedSize+ abs (BoxSize n) = BoxSize (abs n)+ signum UnlimitedSize = UnlimitedSize+ signum (BoxSize n) = BoxSize (signum n)+ fromInteger n = BoxSize $ fromInteger n++-- | The 'BoxSize' can be > 2^32 in which case an 'BoxSizeExtension' must be+-- added after the type field.+newtype BoxSizeExtension =+ BoxSizeExtension BoxSize++instance IsBoxContent BoxSizeExtension where+ boxBuilder (BoxSizeExtension UnlimitedSize) = mempty+ boxBuilder (BoxSizeExtension (BoxSize n)) =+ if n < 4294967296+ then mempty+ else word64BE n+ boxSize (BoxSizeExtension UnlimitedSize) = 0+ boxSize (BoxSizeExtension (BoxSize n)) =+ BoxSize $+ if n < 4294967296+ then 0+ else 8++-- | A box has a /type/, this is the value level representation for the box type.+data BoxType+ =+ -- | `FourCc` can be used as @boxType@ in `Box`, standard four letter character+ -- code, e.g. @ftyp@+ StdType !FourCc+ |+ -- | CustomBoxType defines custom @boxType@s in `Box`es.+ CustomBoxType !String+ deriving (Show,Eq)++-- | Create a box type from a 'Symbol'. Parse the symbol value, if it's a four+-- charachter code, then return that as 'StdType' otherwise parse a UUID (TODO)+-- and return a 'CustomBoxType'.+parseBoxType :: KnownSymbol t => proxy t -> BoxType+parseBoxType px = StdType (fromString (symbolVal px))++-- | A type containin a printable four letter character code. TODO replace impl with U32Text+newtype FourCc =+ FourCc (Char,Char,Char,Char)+ deriving (Show,Eq)++instance IsString FourCc where+ fromString !str+ | length str == 4 =+ let [!a,!b,!c,!d] = str+ in FourCc (a,b,c,d)+ | otherwise =+ error ("cannot make a 'FourCc' of a String which isn't exactly 4 bytes long: " +++ show str ++ " has a length of " ++ show (length str))++instance IsBoxContent FourCc where+ boxSize _ = 4+ boxBuilder (FourCc (!a,!b,!c,!d)) = putW a <> putW b <> putW c <> putW d+ where putW = word8 . fromIntegral . fromEnum++instance IsBoxContent BoxType where+ boxSize _ = boxSize (FourCc undefined)+ boxBuilder t =+ case t of+ StdType x -> boxBuilder x+ CustomBoxType _ -> boxBuilder (FourCc ('u','u','i','d'))++-- | When using custom types extra data must be written after the extra size+-- information. Since the box type and the optional custom box type are not+-- guaranteed to be consequtive, this type handles the /second/ part seperately.+newtype BoxTypeExtension =+ BoxTypeExtension BoxType++instance IsBoxContent BoxTypeExtension where+ boxSize (BoxTypeExtension !(StdType _)) = 0+ boxSize (BoxTypeExtension !(CustomBoxType _)) = 16 * 4+ boxBuilder (BoxTypeExtension !(StdType _)) = mempty+ boxBuilder (BoxTypeExtension !(CustomBoxType str)) =+ mconcat (map (word8 . fromIntegral . fromEnum)+ (take (16 * 4) str) +++ repeat (word8 0))++-- * 'IsBoxContent' instances+-- | An empty box content can by represented by @()@ (i.e. /unit/).+instance IsBoxContent () where+ boxSize _ = 0+ boxBuilder _ = mempty++-- | Trivial instance for 'ByteString'+instance IsBoxContent B.ByteString where+ boxSize = fromIntegral . B.length+ boxBuilder = byteString-- -- | A list, a maybe, and every other 'Foldable' of contents is a content.+ -- instance (Foldable f, IsBoxContent t) => IsBoxContent (f t) where+ -- boxSize = foldr' (\e acc -> acc + boxSize e) 0+ -- boxBuilder = foldMap boxBuilder++-- | This 'Text' instance writes a null terminated UTF-8 string.+instance IsBoxContent T.Text where+ boxSize = (1+) . fromIntegral . T.length+ boxBuilder txt = boxBuilder (T.encodeUtf8 txtNoNulls) <> word8 0+ where txtNoNulls = T.map (\c -> if c == '\0' then ' ' else c) txt++-- | This instance writes zero bytes for 'Nothing' and delegates on 'Just'.+instance IsBoxContent a => IsBoxContent (Maybe a) where+ boxSize = maybe 0 boxSize+ boxBuilder = maybe mempty boxBuilder++-- * Box concatenation++-- | Box content composition+data a :+ b = !a :+ !b++infixr 3 :+++instance (IsBoxContent p,IsBoxContent c) => IsBoxContent (p :+ c) where+ boxSize (p :+ c) = boxSize p + boxSize c+ boxBuilder (p :+ c) = boxBuilder p <> boxBuilder c++instance (Default a, Default b) => Default (a :+ b) where+ def = def :+ def++-- * Tagged boxes++instance IsBoxContent c => IsBoxContent (Tagged s c) where+ boxSize = boxSize . untag+ boxBuilder = boxBuilder . untag++-- * List Box Content++-- | A list of things that renders to a size field with the number of elements+-- and the sequence of elements. This type is index with the size field type.+newtype ListContent sizeType contentType =+ ListContent [contentType]++instance (Num sizeType, IsBoxContent sizeType, IsBoxContent contentType)+ => IsBoxContent (ListContent sizeType contentType) where+ boxSize (ListContent es) =+ boxSize (fromIntegral (length es) :: sizeType) + sum (boxSize <$> es)+ boxBuilder (ListContent es) =+ boxBuilder (fromIntegral (length es) :: sizeType)+ <> fold (boxBuilder <$> es)++instance Default (ListContent sizeTupe contentType) where+ def = ListContent []++-- * Words and Integer++instance IsBoxContent Word8 where+ boxSize _ = 1+ boxBuilder = word8++instance IsBoxContent Word16 where+ boxSize _ = 2+ boxBuilder = word16BE++instance IsBoxContent Word32 where+ boxSize _ = 4+ boxBuilder = word32BE++instance IsBoxContent Word64 where+ boxSize _ = 8+ boxBuilder = word64BE++instance IsBoxContent Int8 where+ boxSize _ = 1+ boxBuilder = int8++instance IsBoxContent Int16 where+ boxSize _ = 2+ boxBuilder = int16BE++instance IsBoxContent Int32 where+ boxSize _ = 4+ boxBuilder = int32BE++instance IsBoxContent Int64 where+ boxSize _ = 8+ boxBuilder = int64BE++-- * Boxes of Bits++instance IsBoxContent BuilderBox where+ boxSize (MkBuilderBox !s _) = fromIntegral s+ boxBuilder (MkBuilderBox _ !b) = b++-- * Type Layout Rule Matchers++-- | Mandatory, container box, exactly one+type OM b bs = ContainerBox b bs+-- | Optional, container box, zero or one+type OO b bs = OnceOptionalX (ContainerBox b bs)+-- | Mandatory, container box, one or more+type SM b bs = SomeMandatoryX (ContainerBox b bs)+-- | Optional, container box, zero or more+type SO b bs = SomeOptionalX (ContainerBox b bs)++-- | Mandatory, exactly one, no children+type OM_ b = Box b+-- | Optional, zero or one, no children+type OO_ b = OnceOptionalX (Box b)+-- | Mandatory, one or more, no children+type SM_ b = SomeMandatoryX (Box b)+-- | Optional, zero or more, no children+type SO_ b = SomeOptionalX (Box b)++----+type instance IsRuleConform (Box b) (Box r) = BoxTypeSymbol b == BoxTypeSymbol r+----+type instance IsRuleConform (Boxes bs) (Boxes rs) = IsRuleConform bs rs -- TODO+----+type instance IsRuleConform (Box b) (ContainerBox b' rules)+ = IsContainerBox b+ && IsRuleConform (Box b) (Box b')+ && IsRuleConform (ChildBoxes b) (Boxes rules)+type family IsContainerBox t :: Bool where+ IsContainerBox (ContainerBox a as) = 'True+ IsContainerBox b = 'False+type family ChildBoxes c where+ ChildBoxes (ContainerBox a as) = Boxes as
src/Data/ByteString/IsoBaseFileFormat/Boxes.hs view
@@ -4,14 +4,12 @@ where import Data.ByteString.IsoBaseFileFormat.Boxes.AudioSampleEntry as X-import Data.ByteString.IsoBaseFileFormat.Boxes.Box as X-import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields as X+import Data.ByteString.IsoBaseFileFormat.Boxes.ChunkOffset as X import Data.ByteString.IsoBaseFileFormat.Boxes.DataEntryUrl as X import Data.ByteString.IsoBaseFileFormat.Boxes.DataEntryUrn as X import Data.ByteString.IsoBaseFileFormat.Boxes.DataInformation as X import Data.ByteString.IsoBaseFileFormat.Boxes.DataReference as X import Data.ByteString.IsoBaseFileFormat.Boxes.FileType as X-import Data.ByteString.IsoBaseFileFormat.Boxes.FullBox as X import Data.ByteString.IsoBaseFileFormat.Boxes.Handler as X import Data.ByteString.IsoBaseFileFormat.Boxes.HintMediaHeader as X import Data.ByteString.IsoBaseFileFormat.Boxes.HintSampleEntry as X@@ -22,24 +20,29 @@ import Data.ByteString.IsoBaseFileFormat.Boxes.MediaInformation as X import Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry as X import Data.ByteString.IsoBaseFileFormat.Boxes.Movie as X+import Data.ByteString.IsoBaseFileFormat.Boxes.MovieExtends as X+import Data.ByteString.IsoBaseFileFormat.Boxes.MovieExtendsHeader as X+import Data.ByteString.IsoBaseFileFormat.Boxes.MovieFragment as X+import Data.ByteString.IsoBaseFileFormat.Boxes.MovieFragmentHeader as X import Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader as X import Data.ByteString.IsoBaseFileFormat.Boxes.NullMediaHeader as X import Data.ByteString.IsoBaseFileFormat.Boxes.ProgressiveDownloadInformation as X import Data.ByteString.IsoBaseFileFormat.Boxes.SampleDescription as X import Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry as X+import Data.ByteString.IsoBaseFileFormat.Boxes.SampleSize as X import Data.ByteString.IsoBaseFileFormat.Boxes.SampleTable as X+import Data.ByteString.IsoBaseFileFormat.Boxes.SampleToChunk as X+import Data.ByteString.IsoBaseFileFormat.Boxes.SegmentType as X import Data.ByteString.IsoBaseFileFormat.Boxes.Skip as X import Data.ByteString.IsoBaseFileFormat.Boxes.SoundMediaHeader as X import Data.ByteString.IsoBaseFileFormat.Boxes.SpecificMediaHeader as X-import Data.ByteString.IsoBaseFileFormat.Boxes.Time as X import Data.ByteString.IsoBaseFileFormat.Boxes.TimeToSample as X import Data.ByteString.IsoBaseFileFormat.Boxes.Track as X+import Data.ByteString.IsoBaseFileFormat.Boxes.TrackExtends as X+import Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragBaseMediaDecodeTime as X+import Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragment as X+import Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragmentHeader as X import Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader as X-import Data.ByteString.IsoBaseFileFormat.Boxes.Versioned as X+import Data.ByteString.IsoBaseFileFormat.Boxes.TrackRun as X import Data.ByteString.IsoBaseFileFormat.Boxes.VideoMediaHeader as X import Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry as X--import Data.Kind as X- (Constraint,- Type)-import Text.Printf as X
src/Data/ByteString/IsoBaseFileFormat/Boxes/AudioSampleEntry.hs view
@@ -1,40 +1,30 @@ -- | Detailed audio sample description. module Data.ByteString.IsoBaseFileFormat.Boxes.AudioSampleEntry where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box-import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.BoxFields import Data.ByteString.IsoBaseFileFormat.Boxes.Handler-import Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry---- | Construct an audio sample entry box.-audioSampleEntry ::- (KnownSymbol- (BoxTypeSymbol (SampleEntry 'AudioTrack (AudioCoding c))))- => AudioCoding c- -> U16 "data_reference_index"- -> SampleEntry 'AudioTrack (AudioCoding c)- -> Box (SampleEntry 'AudioTrack (AudioCoding c))-audioSampleEntry _ = sampleEntry+import Data.ByteString.IsoBaseFileFormat.ReExports --- | Fields if audio sample entries-newtype instance SampleEntry 'AudioTrack (AudioCoding c) where+-- | Fields of audio sample entries+newtype AudioSampleEntry b where AudioSampleEntry :: Constant (U32Arr "reserved" 2) '[0,0] :+ Template (U16 "channelcount") 2 :+ Template (U16 "samplesize") 16 :+ U16 "pre_defined" :+ Constant (U16 "reserved") 0- :+ Template (U32 "samplerate") (DefaultSoundSamplerate * 65536)- -- TODO implement fix point integer- -> SampleEntry 'AudioTrack (AudioCoding c)- deriving (IsBoxContent, Default)--type DefaultSoundSamplerate = 48000+ :+ Template (U32 "samplerate")+ (DefaultSoundSamplerate * 65536) -- TODO implement fix point integer+ :+ b+ -> AudioSampleEntry b+ deriving (Default, IsBoxContent) --- | A coproduct of audio codec types-data family AudioCoding (c :: Symbol)+instance Functor AudioSampleEntry where+ fmap fun (AudioSampleEntry (a :+ b :+ c :+ d :+ e :+ f :+ x)) =+ AudioSampleEntry (a :+ b :+ c :+ d :+ e :+ f :+ fun x) --- | The MPEG-4 AAC Audio codec-data instance AudioCoding "mp4a" = Mpeg4Aac+type DefaultSoundSamplerate = 48000 -type instance BoxTypeSymbol (AudioCoding c) = c+type instance GetHandlerType (AudioSampleEntry b) = 'AudioTrack+type instance BoxTypeSymbol (AudioSampleEntry b) = BoxTypeSymbol b
− src/Data/ByteString/IsoBaseFileFormat/Boxes/Box.hs
@@ -1,360 +0,0 @@-{-# LANGUAGE UndecidableInstances #-}---- | Definition of the most basic element in an ISOBMFF file: a /box/. See--- Chapter 4 in the standard document. A box is a container with a type, a--- size, some data and some nested boxes. The standard defines - among other--- characteristics - available box types and their semantics, the fields they--- contain and how they are nested into each other. This library tries to--- capture some of these characteristics using modern Haskell type system--- features, in order to provide compile time checks for (partial) standard--- compliance.-module Data.ByteString.IsoBaseFileFormat.Boxes.Box- (module Data.ByteString.IsoBaseFileFormat.Boxes.Box, module X)- where--import Data.ByteString.IsoBaseFileFormat.Util.TypeLayout as X-import Data.Default as X-import Data.Foldable as X (fold)-import Data.Int as X-import Data.Maybe as X-import Data.Tagged as X-import Data.Proxy as X-import Data.Word as X-import Data.Bits as X-import Data.ByteString.Builder as X-import Data.Monoid as X-import Data.Kind-import GHC.TypeLits as X-import Data.String as X-import Data.Singletons.Prelude.List (Length, (:++))-import Data.Type.Equality as X-import Data.Type.Bool as X-import qualified Data.Text as T-import qualified Data.Text.Encoding as T-import qualified Data.ByteString as B---- * Box Type Classes--- | Base class for all (abstract/phantom/normal-) types that represent boxes-class (KnownSymbol (BoxTypeSymbol t), IsBoxContent (BoxContent t)) => IsBox (t :: Type) where- type BoxContent t- type BoxContent t = t- toBoxType :: proxy t -> BoxType- toBoxType _ = parseBoxType (Proxy :: Proxy (BoxTypeSymbol t))---- | A type family used by the type-level consistency checks. It is required--- that an instance of this type family exists for every 'IsBox' instance.--- This family could not be associative since it is used by type families that--- cannot have type class constraints.-type family BoxTypeSymbol (t :: k) :: Symbol---- | Types that go into a box. A box content is a piece of data that can be--- reused in different instances of 'IsBox'. It has no 'BoxType' and hence--- defines no box.-class IsBoxContent a where- boxSize :: a -> BoxSize- boxBuilder :: a -> Builder---- * Box Contents--- TODO move all IsBoxContent stuff to BoxContent.hs---- | A type that wraps the contents of a box and the box type.-data Box b where- Box ::- !(BoxContent b) -> Box b--instance IsBox b => IsBox (Box b) where- type BoxContent (Box b) = BoxContent b- toBoxType _ = toBoxType (Proxy :: Proxy b)--type instance BoxTypeSymbol (Box b) = BoxTypeSymbol b--instance IsBox cnt => IsBoxContent (Box cnt) where- boxBuilder b@(Box cnt) = sB <> tB <> sExtB <> tExtB <> cntB- where s = boxSize b- t = toBoxType b- sB = boxBuilder s- sExtB = boxBuilder (BoxSizeExtension s)- tB = boxBuilder t- tExtB = boxBuilder (BoxTypeExtension t)- cntB = boxBuilder cnt- boxSize b@(Box cnt) = sPayload + boxSize (BoxSizeExtension sPayload)- where sPayload =- boxSize (BoxSize undefined) + boxSize t + boxSize cnt +- boxSize (BoxTypeExtension t)- t = toBoxType b--instance (Default (BoxContent b)) => Default (Box b) where- def = Box def---- | Compose 'BoxContent' and 'Boxes' under the Constraint that they are--- composable.-data ContainerBox b (bs :: [Type]) where- ContainerBox :: IsBox b => !(BoxContent b) -> !(Boxes bs) -> ContainerBox b bs--instance (IsBox b) => IsBox (ContainerBox b bs)--type instance BoxTypeSymbol (ContainerBox b bs) = BoxTypeSymbol b--instance IsBoxContent (ContainerBox b bs) where- boxSize (ContainerBox c bs) = boxSize (c :+ bs)- boxBuilder (ContainerBox c bs) = boxBuilder (c :+ bs)---- | A heterogenous collection of boxes.-data Boxes (boxTypes :: [Type]) where- NoBoxes :: Boxes '[]- (:.) :: IsBox l => !(Box l) -> !(Boxes r) -> Boxes (Box l ': r)- -- | Create a 'Boxes' collection from two 'Box'es- (:<>) :: !(Boxes l) -> !(Boxes r) -> Boxes (l :++ r)- (:|) :: (IsBox l, IsBox r) => !(Box l) -> !(Box r) -> Boxes '[Box l, Box r]--infixr 1 :<>-infixr 2 :.-infixr 2 :|-infixr 3 $:---- | Apply a function to a 'Boxes' collection containing only a single 'Box'.-($:) :: IsBox l => (Boxes '[Box l] -> r) -> Box l -> r-($:) f = f . singletonBox---- | Create a 'Boxes' collection with a single 'Box'.-singletonBox :: IsBox l => Box l -> Boxes '[Box l]-singletonBox b = b :. NoBoxes---- | Get the elements in a type level array-typeListLength :: forall a proxy (ts :: [k]) . (KnownNat (Length ts), Num a)- => proxy ts -> a-typeListLength _ = fromIntegral (natVal (Proxy :: Proxy (Length ts)))--instance IsBoxContent (Boxes bs) where- boxSize NoBoxes = 0- boxSize (l :. r) = boxSize l + boxSize r- boxSize (l :| r) = boxSize l + boxSize r- boxSize (l :<> r) = boxSize l + boxSize r- boxBuilder NoBoxes = mempty- boxBuilder (l :. r) = boxBuilder l <> boxBuilder r- boxBuilder (l :| r) = boxBuilder l <> boxBuilder r- boxBuilder (l :<> r) = boxBuilder l <> boxBuilder r---- | A box that contains no fields, but nested boxes.-containerBox :: (IsBox t)- => BoxContent t -> Boxes ts -> Box (ContainerBox t ts)-containerBox c bs = Box (ContainerBox c bs)---- * Box Size and Type--- | The size of the box. If the size is limited to a (fixed) value, it can be--- provided as a 'Word64' which will be represented as either a 32bit compact--- size or as 64 bit /largesize/. If 'UnlimitedSize' is used, the box extends to--- the end of the file.-data BoxSize- = UnlimitedSize- | BoxSize !Word64- deriving (Show,Eq)--instance IsBoxContent BoxSize where- boxSize _ = BoxSize 4- boxBuilder UnlimitedSize = word32BE 0- boxBuilder (BoxSize n) =- word32BE $- if n < (4294967296 :: Word64)- then fromIntegral n- else 1--instance Num BoxSize where- (+) UnlimitedSize _ = UnlimitedSize- (+) _ UnlimitedSize = UnlimitedSize- (+) (BoxSize l) (BoxSize r) = BoxSize (l + r)- (-) UnlimitedSize _ = UnlimitedSize- (-) _ UnlimitedSize = UnlimitedSize- (-) (BoxSize l) (BoxSize r) = BoxSize (l - r)- (*) UnlimitedSize _ = UnlimitedSize- (*) _ UnlimitedSize = UnlimitedSize- (*) (BoxSize l) (BoxSize r) = BoxSize (l * r)- abs UnlimitedSize = UnlimitedSize- abs (BoxSize n) = BoxSize (abs n)- signum UnlimitedSize = UnlimitedSize- signum (BoxSize n) = BoxSize (signum n)- fromInteger n = BoxSize $ fromInteger n---- | The 'BoxSize' can be > 2^32 in which case an 'BoxSizeExtension' must be--- added after the type field.-newtype BoxSizeExtension =- BoxSizeExtension BoxSize--instance IsBoxContent BoxSizeExtension where- boxBuilder (BoxSizeExtension UnlimitedSize) = mempty- boxBuilder (BoxSizeExtension (BoxSize n)) =- if n < 4294967296- then mempty- else word64BE n- boxSize (BoxSizeExtension UnlimitedSize) = 0- boxSize (BoxSizeExtension (BoxSize n)) =- BoxSize $- if n < 4294967296- then 0- else 8---- | A box has a /type/, this is the value level representation for the box type.-data BoxType- =- -- | `FourCc` can be used as @boxType@ in `Box`, standard four letter character- -- code, e.g. @ftyp@- StdType !FourCc- |- -- | CustomBoxType defines custom @boxType@s in `Box`es.- CustomBoxType !String- deriving (Show,Eq)---- | Create a box type from a 'Symbol'. Parse the symbol value, if it's a four--- charachter code, then return that as 'StdType' otherwise parse a UUID (TODO)--- and return a 'CustomBoxType'.-parseBoxType :: KnownSymbol t => proxy t -> BoxType-parseBoxType px = StdType (fromString (symbolVal px))---- | A type containin a printable four letter character code. TODO replace impl with U32Text-newtype FourCc =- FourCc (Char,Char,Char,Char)- deriving (Show,Eq)--instance IsString FourCc where- fromString str- | length str == 4 =- let [a,b,c,d] = str- in FourCc (a,b,c,d)- | otherwise =- error ("cannot make a 'FourCc' of a String which isn't exactly 4 bytes long: " ++- show str ++ " has a length of " ++ show (length str))--instance IsBoxContent FourCc where- boxSize _ = 4- boxBuilder (FourCc (a,b,c,d)) = putW a <> putW b <> putW c <> putW d- where putW = word8 . fromIntegral . fromEnum--instance IsBoxContent BoxType where- boxSize _ = boxSize (FourCc undefined)- boxBuilder t =- case t of- StdType x -> boxBuilder x- CustomBoxType _ -> boxBuilder (FourCc ('u','u','i','d'))---- | When using custom types extra data must be written after the extra size--- information. Since the box type and the optional custom box type are not--- guaranteed to be consequtive, this type handles the /second/ part seperately.-newtype BoxTypeExtension =- BoxTypeExtension BoxType--instance IsBoxContent BoxTypeExtension where- boxSize (BoxTypeExtension (StdType _)) = 0- boxSize (BoxTypeExtension (CustomBoxType _)) = 16 * 4- boxBuilder (BoxTypeExtension (StdType _)) = mempty- boxBuilder (BoxTypeExtension (CustomBoxType str)) =- mconcat (map (word8 . fromIntegral . fromEnum)- (take (16 * 4) str) ++- repeat (word8 0))---- * 'IsBoxContent' instances--- | An empty box content can by represented by @()@ (i.e. /unit/).-instance IsBoxContent () where- boxSize _ = 0- boxBuilder _ = mempty---- | Trivial instance for 'ByteString'-instance IsBoxContent B.ByteString where- boxSize = fromIntegral . B.length- boxBuilder = byteString-- -- | A list, a maybe, and every other 'Foldable' of contents is a content.- -- instance (Foldable f, IsBoxContent t) => IsBoxContent (f t) where- -- boxSize = foldr' (\e acc -> acc + boxSize e) 0- -- boxBuilder = foldMap boxBuilder--instance Default B.ByteString where- def = mempty---- | This 'Text' instance writes a null terminated UTF-8 string.-instance IsBoxContent T.Text where- boxSize = (1+) . fromIntegral . T.length- boxBuilder txt = boxBuilder (T.encodeUtf8 txtNoNulls) <> word8 0- where txtNoNulls = T.map (\c -> if c == '\0' then ' ' else c) txt--instance Default T.Text where- def = ""----- | This instance writes zero bytes for 'Nothing' and delegates on 'Just'.-instance IsBoxContent a => IsBoxContent (Maybe a) where- boxSize = maybe 0 boxSize- boxBuilder = maybe mempty boxBuilder---- * Box concatenation---- | Box content composition-data a :+ b = !a :+ !b--infixr 3 :+--instance (IsBoxContent p,IsBoxContent c) => IsBoxContent (p :+ c) where- boxSize (p :+ c) = boxSize p + boxSize c- boxBuilder (p :+ c) = boxBuilder p <> boxBuilder c--instance (Default a, Default b) => Default (a :+ b) where- def = def :+ def---- * Tagged boxes--instance IsBoxContent c => IsBoxContent (Tagged s c) where- boxSize = boxSize . untag- boxBuilder = boxBuilder . untag--instance Default c => Default (Tagged s c) where- def = Tagged def---- * List Box Content---- | A list of things that renders to a size field with the number of elements--- and the sequence of elements. This type is index with the size field type.-newtype ListContent sizeType contentType =- ListContent [contentType]--instance (Num sizeType, IsBoxContent sizeType, IsBoxContent contentType)- => IsBoxContent (ListContent sizeType contentType) where- boxSize (ListContent es) =- boxSize (fromIntegral (length es) :: sizeType) + sum (boxSize <$> es)- boxBuilder (ListContent es) =- boxBuilder (fromIntegral (length es) :: sizeType)- <> fold (boxBuilder <$> es)--instance Default (ListContent sizeTupe contentType) where- def = ListContent []---- * Type Layout Rule Matchers---- | Mandatory, container box, exactly one-type OM b bs = ContainerBox b bs--- | Optional, container box, zero or one-type OO b bs = OnceOptionalX (ContainerBox b bs)--- | Mandatory, container box, one or more-type SM b bs = SomeMandatoryX (ContainerBox b bs)--- | Optional, container box, zero or more-type SO b bs = SomeOptionalX (ContainerBox b bs)---- | Mandatory, exactly one, no children-type OM_ b = Box b--- | Optional, zero or one, no children-type OO_ b = OnceOptionalX (Box b)--- | Mandatory, one or more, no children-type SM_ b = SomeMandatoryX (Box b)--- | Optional, zero or more, no children-type SO_ b = SomeOptionalX (Box b)-------type instance IsRuleConform (Box b) (Box r) = BoxTypeSymbol b == BoxTypeSymbol r------type instance IsRuleConform (Boxes bs) (Boxes rs) = IsRuleConform bs rs -- TODO------type instance IsRuleConform (Box b) (ContainerBox b' rules)- = IsContainerBox b- && IsRuleConform (Box b) (Box b')- && IsRuleConform (ChildBoxes b) (Boxes rules)-type family IsContainerBox t :: Bool where- IsContainerBox (ContainerBox a as) = 'True- IsContainerBox b = 'False-type family ChildBoxes c where- ChildBoxes (ContainerBox a as) = Boxes as
− src/Data/ByteString/IsoBaseFileFormat/Boxes/BoxFields.hs
@@ -1,298 +0,0 @@--- | Mini EDSL for labelled box fields. The boxfields can be 'Scalar' or--- 'ScalarArray's.-module Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields- where--import Data.ByteString.IsoBaseFileFormat.Boxes.Box-import Text.Printf-import Data.Singletons-import Data.Singletons.Prelude.List-import qualified Data.Vector.Sized as Vec-import qualified Data.Text as T-import qualified Data.Text.Encoding as T-import qualified Data.ByteString as B----- * Scalar box fields--type U64 label = Scalar Word64 label--type I64 label = Scalar Int64 label--u64 :: Word64 -> U64 label-u64 = Scalar--i64 :: Int64 -> I64 label-i64 = Scalar--type U32 label = Scalar Word32 label-type I32 label = Scalar Int32 label--u32 :: Word32 -> U32 label-u32 = Scalar--i32 :: Int32 -> I32 label-i32 = Scalar--type U16 label = Scalar Word16 label--type I16 label = Scalar Int16 label--u16 :: Word16 -> U16 label-u16 = Scalar--i16 :: Int16 -> I16 label-i16 = Scalar--type U8 label = Scalar Word8 label--type I8 label = Scalar Int8 label--u8 :: Word8 -> U8 label-u8 = Scalar--i8 :: Int8 -> I8 label-i8 = Scalar---- | A numeric box field with a type level label. Note that it has a 'Num'--- instance. Use the type aliases above, e.g.--- 'U8','I8','U16','I16','U32','I32','U64','I64' from above. Use either the--- smart constructors, e.g. 'u8','i8','u16','i16','u32','i32','u64','i64' or the--- 'Num' instance, whereas the constructors might give a bit more safety.-newtype Scalar scalartype (label :: k) =- Scalar {fromScalar :: scalartype}- deriving (Show, Read, Ord, Eq, Num, Default)---- | Relabel a scalar value, e.g. convert a @Scalar U32 "foo"@ to a @Scalar U32--- "bar"@.-relabelScalar :: Scalar t l -> Scalar t l'-relabelScalar (Scalar x) = (Scalar x)--instance IsBoxContent (Scalar Word8 label) where- boxSize _ = 1- boxBuilder (Scalar v) = word8 v--instance IsBoxContent (Scalar Word16 label) where- boxSize _ = 2- boxBuilder (Scalar v) = word16BE v--instance IsBoxContent (Scalar Word32 label) where- boxSize _ = 4- boxBuilder (Scalar v) = word32BE v--instance IsBoxContent (Scalar Word64 label) where- boxSize _ = 8- boxBuilder (Scalar v) = word64BE v--instance IsBoxContent (Scalar Int8 label) where- boxSize _ = 1- boxBuilder (Scalar v) = int8 v--instance IsBoxContent (Scalar Int16 label) where- boxSize _ = 2- boxBuilder (Scalar v) = int16BE v--instance IsBoxContent (Scalar Int32 label) where- boxSize _ = 4- boxBuilder (Scalar v) = int32BE v--instance IsBoxContent (Scalar Int64 label) where- boxSize _ = 8- boxBuilder (Scalar v) = int64BE v--instance (KnownNat scalar,Num o) => FromTypeLit (Scalar o label) scalar where- fromTypeLit _ = Scalar $ fromIntegral $ natVal (Proxy :: Proxy scalar)---- * Array fields--type U64Arr label size = ScalarArray label size Word64--u64Arr :: (KnownNat size,KnownSymbol label)- => [Word64] -> U64Arr label size-u64Arr = fromList--type I64Arr label size = ScalarArray label size Int64--i64Arr :: (KnownNat size,KnownSymbol label)- => [Int64] -> I64Arr label size-i64Arr = fromList--type U32Arr label size = ScalarArray label size Word32--u32Arr :: (KnownNat size,KnownSymbol label)- => [Word32] -> U32Arr label size-u32Arr = fromList--type I32Arr label size = ScalarArray label size Int32--i32Arr :: (KnownNat size,KnownSymbol label)- => [Int32] -> I32Arr label size-i32Arr = fromList--type U16Arr label size = ScalarArray label size Word16--u16Arr :: (KnownNat size,KnownSymbol label)- => [Word16] -> U16Arr label size-u16Arr = fromList--type I16Arr label size = ScalarArray label size Int16--i16Arr :: (KnownNat size,KnownSymbol label)- => [Int16] -> I16Arr label size-i16Arr = fromList--type U8Arr label size = ScalarArray label size Word8--u8Arr :: (KnownNat size,KnownSymbol label)- => [Word8] -> U8Arr label size-u8Arr = fromList--type I8Arr label size = ScalarArray label size Int8--i8Arr :: (KnownNat size,KnownSymbol label)- => [Int8] -> I8Arr label size-i8Arr = fromList---- | A box field that is an array of 'Scalar's with a type level label. Use the--- type aliases, e.g.--- 'U8Arr','I8Arr','U16Arr','I16Arr','U32Arr','I32Arr','U64Arr','I64Arr' from--- above. Use the smart constructors, e.g.--- 'u8Arr','i8Arr','u16Arr','i16Arr','u32Arr','i32Arr','u64Arr','i64Arr' .-newtype ScalarArray (label :: k) (len :: Nat) o where- ScalarArray :: Vec.Vector n o -> ScalarArray label n o- deriving (Show,Eq)--instance (Default o,KnownNat (len :: Nat)) => Default (ScalarArray label len o) where- def = ScalarArray $ Vec.replicate def--instance (Num o,IsBoxContent (Scalar o label),KnownNat (len :: Nat)) => IsBoxContent (ScalarArray label len o) where- boxSize (ScalarArray vec) =- fromIntegral (Vec.length vec) * boxSize (Scalar 0 :: Scalar o label)- boxBuilder (ScalarArray vec) =- Vec.foldl' mappend- mempty- (Vec.map (boxBuilder . mkScalar) vec)- where mkScalar :: o -> Scalar o label- mkScalar = Scalar---- | Internal function-fromList :: forall label n o.- (KnownSymbol label,KnownNat n)- => [o] -> ScalarArray label n o-fromList l =- ScalarArray $- case Vec.fromList l of- Nothing ->- error $- printf "Invalid number of array elements for array %s. Got length: %d elments, expected %d."- (show (symbolVal (Proxy :: Proxy label)))- (length l)- (natVal (Proxy :: Proxy n))- Just v -> v---- * Constant fields---- | Wrapper around a field, e.g. a 'Scalar' or 'ScalarArray', with a type level--- value. The wrapped content must implement 'FromTypeLit'. To get the value of--- a 'Constant' use 'fromTypeLit'.-data Constant o v where- Constant :: Constant o v--instance (IsBoxContent o,FromTypeLit o v) => IsBoxContent (Constant o v) where- boxSize = boxSize . fromTypeLit- boxBuilder = boxBuilder . fromTypeLit--instance Default (Constant o v) where- def = Constant---- * Template Fields---- | Fields with default values that can be overriden with custom value. Like--- 'Constant' this is a wrapper around a field, e.g. a 'Scalar' or--- 'ScalarArray', with a type level default value. The wrapped content must--- implement 'FromTypeLit'.-data Template o v where- Template :: Template o v- Custom :: o -> Template o v--instance Default (Template o v) where- def = Template---- | Get a value from a 'Template'.-templateValue :: FromTypeLit o v => Template o v -> o-templateValue d@Template = fromTypeLit d-templateValue (Custom v) = v--instance (IsBoxContent o,FromTypeLit o v) => IsBoxContent (Template o v) where- boxSize = boxSize . templateValue- boxBuilder = boxBuilder . templateValue---- * Conversion from type-level numbers and lists to values---- | Types that can be constructed from type level value representations.-class FromTypeLit o v where- fromTypeLit :: proxy o v -> o--instance (SingI arr,Num o,SingKind [Nat],KnownNat len,len ~ Length arr) => FromTypeLit (ScalarArray label len o) (arr :: [Nat]) where- fromTypeLit _ =- let s = sing :: Sing arr- vs :: [Integer]- vs = fromSing s- vs' :: [o]- vs' = fromIntegral <$> vs- in ScalarArray (fromJust (Vec.fromList vs'))--instance KnownSymbol str => FromTypeLit T.Text (str :: Symbol) where- fromTypeLit = T.pack . symbolVal---- * String/Text field types---- | A fixed size string, the first byte is the string length, after the String,--- the field is padded with @0@ bytes. The string must be in UTF8 format.-newtype FixSizeText (len :: Nat) (label :: Symbol) where- FixSizeText :: T.Text -> FixSizeText len label---- | A constraint that matches type level numbers that are valid text sizes for--- 'FixSizeText's.-type IsTextSize len = (KnownNat len, 1 <= len, len <= 255)--instance IsTextSize len => IsBoxContent (FixSizeText len label) where- boxSize _ = fromIntegral (natVal (Proxy :: Proxy len))- boxBuilder (FixSizeText t) =- let- -- leave room for the size byte- maxSize = fromIntegral (natVal (Proxy :: Proxy len) - 1)- displayableText = B.take maxSize (T.encodeUtf8 t)- displayableTextSize = B.length displayableText- paddingSize = max 0 (maxSize - displayableTextSize)- in- word8 (fromIntegral displayableTextSize)- <> byteString displayableText- <> fold (replicate paddingSize (word8 0))--instance IsTextSize len => Default (FixSizeText len label) where- def = FixSizeText ""---- | Four character strings embedded in a uint32.-newtype U32Text (label :: Symbol) where- U32Text :: Word32 -> U32Text label--instance IsString (U32Text label) where- fromString str = U32Text $- let cw s c = (0xFF .&. (fromIntegral (fromEnum c))) `shiftL` s- in case str of- [] -> 0x20202020- [a] -> (cw 24 a .|. 0x00202020)- [a,b] -> (cw 24 a .|. cw 16 b .|. 0x00002020)- [a,b,c] -> (cw 24 a .|. cw 16 b .|. cw 8 c .|. 0x20)- (a:b:c:d:_) -> (cw 24 a .|. cw 16 b .|. cw 8 c .|. cw 0 d)--instance IsBoxContent (U32Text label) where- boxSize _ = 4- boxBuilder (U32Text t) = word32BE t--instance KnownSymbol str => FromTypeLit (U32Text label) (str :: Symbol) where- fromTypeLit = fromString . symbolVal--instance Default (U32Text label) where- def = U32Text 0x20202020
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/ChunkOffset.hs view
@@ -0,0 +1,52 @@+-- | A table mapping chunks to *absolute* file offsets.+-- Two variants exist: 32 or 64 bits.++module Data.ByteString.IsoBaseFileFormat.Boxes.ChunkOffset where++import Data.ByteString.IsoBaseFileFormat.ReExports+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.BoxFields+import Data.ByteString.IsoBaseFileFormat.Util.FullBox++-- | Create a hunk offset box for 32 bit entries (@stco@). If possible use+-- this over 'ChunkOffset64'+chunkOffset32 :: [StcoEntry32] -> Box ChunkOffset32+chunkOffset32 = fullBox 0 . ChunkOffsetTable . ListContent++-- | Create a hunk offset box for 64 bit entries (@stco@). If possible use+-- 'ChunkOffset32'+chunkOffset64 :: [StcoEntry64] -> Box ChunkOffset64+chunkOffset64 = fullBox 0 . ChunkOffsetTable . ListContent++-- | Chunk offset box for 32 bit entries (@stco@). If possible use+-- this over 'ChunkOffset64'+type ChunkOffset32 = FullBox ChunkOffsetTable32 0++-- | Chunk offset box for 64 bit entries (@stco@). If possible use+-- 'ChunkOffset32'+type ChunkOffset64 = FullBox ChunkOffsetTable64 0++-- | Alias for 'ChunkOffsetTable' for 32 bit entries (@stco@)+type ChunkOffsetTable32 = ChunkOffsetTable StcoEntry32++-- | Alias for 'ChunkOffsetTable' for 64 bit entries (@co64@)+type ChunkOffsetTable64 = ChunkOffsetTable StcoEntry64++-- | A list of 'StcoEntry32' or 'StcoEntry64' entries.+newtype ChunkOffsetTable stcoEntry =+ ChunkOffsetTable (ListContent (U32 "entry_count") stcoEntry)+ deriving (Default, IsBoxContent)++-- | An entry of the 'ChunkOffsetTable' contains just the absolute file offset+-- to the chunk.+type StcoEntry32 = U32 "chunk_offset"++-- | An entry of the 'ChunkOffsetTable' contains just the absolute file offset+-- to the chunk.+type StcoEntry64 = U64 "chunk_offset"++type instance BoxTypeSymbol ChunkOffsetTable32 = "stco"+type instance BoxTypeSymbol ChunkOffsetTable64 = "co64"++instance IsBox ChunkOffsetTable32+instance IsBox ChunkOffsetTable64
src/Data/ByteString/IsoBaseFileFormat/Boxes/DataEntryUrl.hs view
@@ -6,9 +6,10 @@ ) where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box-import Data.ByteString.IsoBaseFileFormat.Boxes.FullBox+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.FullBox import qualified Data.Text as T+import Data.ByteString.IsoBaseFileFormat.ReExports -- | A container for a URL or an indicator for local only media newtype DataEntryUrl =
src/Data/ByteString/IsoBaseFileFormat/Boxes/DataEntryUrn.hs view
@@ -5,8 +5,8 @@ ) where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box-import Data.ByteString.IsoBaseFileFormat.Boxes.FullBox+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.FullBox import qualified Data.Text as T -- | A container for a URN and optionally a URL
src/Data/ByteString/IsoBaseFileFormat/Boxes/DataInformation.hs view
@@ -2,7 +2,7 @@ -- 'Track' the actual location are stored in 'DataReference's. module Data.ByteString.IsoBaseFileFormat.Boxes.DataInformation where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box+import Data.ByteString.IsoBaseFileFormat.Box -- | Data information box phantom type. data DataInformation
src/Data/ByteString/IsoBaseFileFormat/Boxes/DataReference.hs view
@@ -9,11 +9,12 @@ ) where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box-import Data.ByteString.IsoBaseFileFormat.Boxes.FullBox+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.FullBox import Data.ByteString.IsoBaseFileFormat.Boxes.DataEntryUrl-import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields+import Data.ByteString.IsoBaseFileFormat.Util.BoxFields import Data.Singletons.Prelude.List (Length)+import Data.ByteString.IsoBaseFileFormat.ReExports -- | A container for 'DataEntryUrl's and 'DataEntryUrn's newtype DataReference =
src/Data/ByteString/IsoBaseFileFormat/Boxes/FileType.hs view
@@ -1,6 +1,7 @@ module Data.ByteString.IsoBaseFileFormat.Boxes.FileType where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.ReExports -- | File Type Box instance IsBox FileType where@@ -14,9 +15,9 @@ -- | Contents of a 'ftyp' box are some 'FourCc' /brands/ and a version. data FileType =- FileType {majorBrand :: FourCc- ,minorVersion :: Word32- ,compatibleBrands :: [FourCc]}+ FileType {majorBrand :: !FourCc -- TODO use U32String+ ,minorVersion :: !Word32 -- TODO use U32String+ ,compatibleBrands :: ![FourCc]} -- TODO use U32String instance IsBoxContent FileType where boxSize (FileType maj _ver comps) = boxSize maj + 4 + sum (boxSize <$> comps)
− src/Data/ByteString/IsoBaseFileFormat/Boxes/FullBox.hs
@@ -1,92 +0,0 @@--- | Full Boxes-module Data.ByteString.IsoBaseFileFormat.Boxes.FullBox- (FullBox(..), fullBox, BoxFlags(..))- where--import Data.ByteString.IsoBaseFileFormat.Boxes.Box---- | A 'FullBox' contains an extra version and a flags field. In this--- implementation it is wrapped around the rest of the box content. This--- enforces that the 'FullBox' header fields are always at the beginning - at--- least as long as this module hides the 'FullBox' constructor ;)-data FullBox t (version :: Nat) where- FullBox :: (KnownNat version, IsBox t)- => BoxFlags 24- -> BoxContent t- -> FullBox t version--instance (KnownNat version, IsBox t, Default (BoxContent t))- => Default (FullBox t version) where- def = FullBox 0 def--instance (KnownNat v, IsBox t) => IsBox (FullBox t v) where- type BoxContent (FullBox t v) = FullBox t v--type instance BoxTypeSymbol (FullBox t v) = BoxTypeSymbol t--instance (IsBox t, KnownNat v) => IsBoxContent (FullBox t v) where- boxSize (FullBox f c) = 1 + boxSize f + boxSize c- boxBuilder (FullBox f c) =- word8 (fromIntegral (natVal (Proxy :: Proxy v)))- <> boxBuilder f- <> boxBuilder c---- | Create a 'FullBox' from a 'BoxVersion' and 'BoxFlags'-fullBox- :: (KnownNat v, IsBox t)- => BoxFlags 24 -> BoxContent t -> Box (FullBox t v)-fullBox f c = Box (FullBox f c)---- | In addition to a version there can be 24 bits for custom flags etc in--- a 'FullBox'.-newtype BoxFlags bits =- BoxFlags Integer- deriving (Eq,Show,Num)---- | Internal function that creates a bit mask with all bits in a 'BoxFlags' set--- to 1.-boxFlagBitMask :: KnownNat bits- => BoxFlags bits -> Integer-boxFlagBitMask px = 2 ^ natVal px - 1---- | Internal function that masks-out all bits higher than 'bits'.-cropBits :: KnownNat bits- => BoxFlags bits -> BoxFlags bits-cropBits f@(BoxFlags b) = BoxFlags (b .&. boxFlagBitMask f)---- | Get the number of bytes required to store a number of bits.-instance KnownNat bits => IsBoxContent (BoxFlags bits) where- boxSize f =- let minBytes = fromInteger $ natVal f `div` 8- modBytes = fromInteger $ natVal f `mod` 8- in BoxSize $ minBytes + signum modBytes- boxBuilder f@(BoxFlags b) =- let bytes =- let (BoxSize bytes') = boxSize f- in fromIntegral bytes'- wordSeq n- | n <= bytes =- word8 (fromIntegral (shiftR b ((bytes - n) * 8) .&. 255)) <>- wordSeq (n + 1)- | otherwise = mempty- in wordSeq 1--instance KnownNat bits => Bits (BoxFlags bits) where- (.&.) (BoxFlags l) (BoxFlags r) = cropBits $ BoxFlags $ l .&. r- (.|.) (BoxFlags l) (BoxFlags r) = cropBits $ BoxFlags $ l .&. r- xor (BoxFlags l) (BoxFlags r) = cropBits $ BoxFlags $ xor l r- complement (BoxFlags x) = cropBits $ BoxFlags $ complement x- shift (BoxFlags x) = cropBits . BoxFlags . shift x- rotateL = error "TODO rotateL"- rotateR = error "TODO rotateR"- bitSize = fromInteger . natVal- bitSizeMaybe = Just . fromInteger . natVal- isSigned _ = False- testBit f n =- let (BoxFlags b) = cropBits f- in testBit b n- bit = cropBits . BoxFlags . bit- popCount f =- let (BoxFlags b) = cropBits f- in popCount b- zeroBits = BoxFlags 0
src/Data/ByteString/IsoBaseFileFormat/Boxes/Handler.hs view
@@ -15,13 +15,15 @@ ,auxilliaryVideoTrackHandler ,namedAuxilliaryVideoTrackHandler ,HandlerType(..)+ ,GetHandlerType ,HandlerTypeCode) where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box-import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields-import Data.ByteString.IsoBaseFileFormat.Boxes.FullBox+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.BoxFields+import Data.ByteString.IsoBaseFileFormat.Util.FullBox import qualified Data.Text as T+import Data.ByteString.IsoBaseFileFormat.ReExports -- | Handler box fields. A handler box may also contain a null terminated -- description text in UTF-8. The 'T.Text' parameter is a human readable name of@@ -43,6 +45,9 @@ | HintTrack | TimedMetaDataTrack | AuxilliaryVideoTrack++-- | Return 'HandlerType' for 'BoxLayout' checking.+type family GetHandlerType t :: HandlerType type family HandlerTypeCode (handlertype :: HandlerType) :: Symbol where HandlerTypeCode 'VideoTrack = "vide"
src/Data/ByteString/IsoBaseFileFormat/Boxes/HintMediaHeader.hs view
@@ -1,11 +1,12 @@ -- | Media-independent properties of a hint tracks media content. module Data.ByteString.IsoBaseFileFormat.Boxes.HintMediaHeader where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box-import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields-import Data.ByteString.IsoBaseFileFormat.Boxes.FullBox+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.BoxFields+import Data.ByteString.IsoBaseFileFormat.Util.FullBox import Data.ByteString.IsoBaseFileFormat.Boxes.Handler import Data.ByteString.IsoBaseFileFormat.Boxes.SpecificMediaHeader+import Data.ByteString.IsoBaseFileFormat.ReExports type instance MediaHeaderFor 'HintTrack = HintMediaHeader
src/Data/ByteString/IsoBaseFileFormat/Boxes/HintSampleEntry.hs view
@@ -2,16 +2,14 @@ -- | Format of the hint track as well as streaming protocol settings. module Data.ByteString.IsoBaseFileFormat.Boxes.HintSampleEntry where -import Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry+import Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry () import Data.ByteString.IsoBaseFileFormat.Boxes.Handler-import Data.ByteString.IsoBaseFileFormat.Boxes.Box+import Data.ByteString.IsoBaseFileFormat.Box -- | Protocol specific data. To create 'HintSampleEntry's a protocol specific -- 'HintFields' instance must be provided-data instance SampleEntry 'HintTrack protocol where- HintSampleEntry- :: (IsBoxContent (HintFields protocol), Default (HintFields protocol))- => HintFields protocol -> SampleEntry 'HintTrack protocol+newtype HintSampleEntry protocol where+ HintSampleEntry :: protocol -> HintSampleEntry protocol --- | Family of protocol specific contents for 'HintTrack's.-type family HintFields (protocol :: Symbol)+type instance GetHandlerType (HintSampleEntry protocol) = 'HintTrack+type instance BoxTypeSymbol (HintSampleEntry protocol) = BoxTypeSymbol protocol
src/Data/ByteString/IsoBaseFileFormat/Boxes/Language.hs view
@@ -1,22 +1,23 @@ -- | Boxfield indicating an ISO 639-2 alpha-3 language code. module Data.ByteString.IsoBaseFileFormat.Boxes.Language (Language, mkLanguage) where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.ReExports -- | A Boxfield contains an ISO 639-2-T alpha-3 language code, which is encoded -- as a single bit followed by three 5 bit words, each representing the -- lower-case character from the language code subtracted by 0x60. -- If available, the code for /terminoligy/ purposes should be used (T-code).-data Language = Language Word16+newtype Language = Language Word16 -- TODO use bitrecords -- | Create a 'Language', throw a runtime error when bad characters were given. -- The characters must be in @a - z@ (lower-case!), there must be exactly three -- characters. mkLanguage :: String -> Language mkLanguage [c0,c1,c2] |- (c0 > toEnum 0x60 && c0 < toEnum 0x7b &&+ c0 > toEnum 0x60 && c0 < toEnum 0x7b && c1 > toEnum 0x60 && c1 < toEnum 0x7b &&- c2 > toEnum 0x60 && c2 < toEnum 0x7b) =+ c2 > toEnum 0x60 && c2 < toEnum 0x7b = let s :: Char -> Word16 s c = fromIntegral (fromEnum c) - 0x60@@ -31,7 +32,7 @@ fromString = mkLanguage instance Default Language where- def = mkLanguage "deu"+ def = mkLanguage "und" instance IsBoxContent Language where boxSize _ = 2
src/Data/ByteString/IsoBaseFileFormat/Boxes/Media.hs view
@@ -1,7 +1,7 @@ -- | Track specific media information container box. module Data.ByteString.IsoBaseFileFormat.Boxes.Media where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box+import Data.ByteString.IsoBaseFileFormat.Box -- | Media data box data Media
src/Data/ByteString/IsoBaseFileFormat/Boxes/MediaData.hs view
@@ -1,7 +1,7 @@ -- | Media data box module Data.ByteString.IsoBaseFileFormat.Boxes.MediaData where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box+import Data.ByteString.IsoBaseFileFormat.Box import qualified Data.ByteString as B -- | Media data box phantom type
src/Data/ByteString/IsoBaseFileFormat/Boxes/MediaHeader.hs view
@@ -1,17 +1,17 @@ -- | Media-independent properties of a tracks media content. module Data.ByteString.IsoBaseFileFormat.Boxes.MediaHeader where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box-import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields-import Data.ByteString.IsoBaseFileFormat.Boxes.FullBox+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.BoxFields+import Data.ByteString.IsoBaseFileFormat.Util.FullBox import Data.ByteString.IsoBaseFileFormat.Boxes.Language-import Data.ByteString.IsoBaseFileFormat.Boxes.Time+import Data.ByteString.IsoBaseFileFormat.Util.Time+import Data.ByteString.IsoBaseFileFormat.ReExports -- | Media header data box.-data MediaHeader (v :: Nat) where+newtype MediaHeader (v :: Nat) where MediaHeader- :: KnownNat v- => Timing v :+ Language :+ Constant (I16 "pre_defined") 0+ :: Timing v :+ Language :+ Constant (I16 "pre_defined") 0 -> MediaHeader v -- | Create a 'MediaHeader' box.
src/Data/ByteString/IsoBaseFileFormat/Boxes/MediaInformation.hs view
@@ -2,7 +2,7 @@ -- technicalities of the media data associated with a 'Track'. module Data.ByteString.IsoBaseFileFormat.Boxes.MediaInformation where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box+import Data.ByteString.IsoBaseFileFormat.Box -- | Media information box type. data MediaInformation
src/Data/ByteString/IsoBaseFileFormat/Boxes/MetaDataSampleEntry.hs view
@@ -1,26 +1,18 @@ module Data.ByteString.IsoBaseFileFormat.Boxes.MetaDataSampleEntry where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box-import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields-import Data.ByteString.IsoBaseFileFormat.Boxes.FullBox+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.BoxFields+import Data.ByteString.IsoBaseFileFormat.Util.FullBox import Data.ByteString.IsoBaseFileFormat.Boxes.Handler-import Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry import qualified Data.Text as T import qualified Data.ByteString as B import Data.Tagged () import Data.Default ()+import Data.ByteString.IsoBaseFileFormat.ReExports -- * Generat meta data sample entry --- | Construct a meta data sample entry box. For every 'MetaDataCoding'--- a 'SampleEntry' instances must be provided.-metaDataSampleEntry ::- MetaDataCoding c- -> U16 "data_reference_index"- -> SampleEntry 'TimedMetaDataTrack (MetaDataCoding c)- -> Box (SampleEntry 'TimedMetaDataTrack (MetaDataCoding c))-metaDataSampleEntry _ = sampleEntry-+type instance GetHandlerType (MetaDataCoding c) = 'TimedMetaDataTrack type instance BoxTypeSymbol (MetaDataCoding c) = c -- | A coproduct of meta data codings (XML, Text, ...)
src/Data/ByteString/IsoBaseFileFormat/Boxes/Movie.hs view
@@ -1,7 +1,7 @@ -- | Meta data for a presentation of a /movie/. module Data.ByteString.IsoBaseFileFormat.Boxes.Movie where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box+import Data.ByteString.IsoBaseFileFormat.Box -- | Compose a set of boxes into a 'Movie' movie :: Boxes ts -> Box (ContainerBox Movie ts)
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/MovieExtends.hs view
@@ -0,0 +1,22 @@+-- | Indicate the possibility of 'MovieFragment' boxes in the current file; the+-- total samples are comprised of those fragments, so they must be parsed by the+-- player.+module Data.ByteString.IsoBaseFileFormat.Boxes.MovieExtends where++import Data.ByteString.IsoBaseFileFormat.Box++-- * @mvex@ Box++-- | Indicate that the media fragmented; more detailed info is obtained by the+-- extra boxes contained in this box, e.g. the 'MovieExtendsHeader' or the+-- 'TrackExtends' boxes.+movieExtends :: Boxes ts -> Box (ContainerBox MovieExtends ts)+movieExtends = containerBox ()++-- | Phantom type to indicate @mvex@ boxes, see ISO-14496-12 8.8.1+data MovieExtends++instance IsBox MovieExtends where+ type BoxContent MovieExtends = ()++type instance BoxTypeSymbol MovieExtends = "mvex"
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/MovieExtendsHeader.hs view
@@ -0,0 +1,27 @@+-- | Overall duration of fragmented media.+module Data.ByteString.IsoBaseFileFormat.Boxes.MovieExtendsHeader where++import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.BoxFields+import Data.ByteString.IsoBaseFileFormat.Util.FullBox+import Data.ByteString.IsoBaseFileFormat.Util.Versioned+import Data.ByteString.IsoBaseFileFormat.ReExports++-- * @mehd@ Box++-- | Construct a 'MovieHeader' box.+movieExtendsHeader+ :: (KnownNat version)+ => MovieExtendsHeader version -> Box (FullBox (MovieExtendsHeader version) version)+movieExtendsHeader = fullBox 0++-- | Movie length incorporating all fragments.+newtype MovieExtendsHeader (version :: Nat) where+ MovieExtendsHeader ::+ Versioned (U32 "fragment_duration") (U64 "fragment_duration") version+ -> MovieExtendsHeader version+ deriving (IsBoxContent)++instance IsBox (MovieExtendsHeader version)++type instance BoxTypeSymbol (MovieExtendsHeader v) = "mehd"
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/MovieFragment.hs view
@@ -0,0 +1,20 @@+-- | TODO: this box is a bit of a hack due to the deadline pressure...+module Data.ByteString.IsoBaseFileFormat.Boxes.MovieFragment where++import Data.ByteString.IsoBaseFileFormat.Box++-- | Compose a set of boxes into a 'MovieFragment'+movieFragment :: Boxes ts -> Box (ContainerBox MovieFragment ts)+movieFragment = containerBox ()++-- | Movie Fragments+data MovieFragment++instance IsBox MovieFragment where+ type BoxContent MovieFragment = ()++type instance BoxTypeSymbol MovieFragment = "moof"++-- | Return the static size of the empty box+movieFragmentStaticSize :: Num a => a+movieFragmentStaticSize = fromBoxSize 0 (boxSize (movieFragment NoBoxes))
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/MovieFragmentHeader.hs view
@@ -0,0 +1,28 @@+-- | Meta data for a presentation of a /movie fragment/.+module Data.ByteString.IsoBaseFileFormat.Boxes.MovieFragmentHeader where++import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.BoxFields+import Data.ByteString.IsoBaseFileFormat.Util.FullBox+import Data.Default++-- * @mvhd@ Box++-- | Construct a 'MovieFragmentHeader' box.+movieFragmentHeader+ :: MovieFragmentHeader-> Box (FullBox MovieFragmentHeader 0)+movieFragmentHeader = fullBox 0++-- | Movie fragment meta data+-- The sequence number, just an increasing number, of this fragment+newtype MovieFragmentHeader where+ MovieFragmentHeader :: U32 "sequence_number" -> MovieFragmentHeader+ deriving (IsBoxContent, Default)++instance IsBox MovieFragmentHeader++type instance BoxTypeSymbol MovieFragmentHeader = "mfhd"++-- | Return the static size of the empty box+movieFragmentHeaderStaticSize :: Num a => a+movieFragmentHeaderStaticSize = fromBoxSize 0 (boxSize (movieFragmentHeader def))
src/Data/ByteString/IsoBaseFileFormat/Boxes/MovieHeader.hs view
@@ -1,10 +1,11 @@ -- | Meta data for a presentation of a /movie/. module Data.ByteString.IsoBaseFileFormat.Boxes.MovieHeader where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box-import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields-import Data.ByteString.IsoBaseFileFormat.Boxes.FullBox-import Data.ByteString.IsoBaseFileFormat.Boxes.Time+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.BoxFields+import Data.ByteString.IsoBaseFileFormat.Util.FullBox+import Data.ByteString.IsoBaseFileFormat.Util.Time+import Data.ByteString.IsoBaseFileFormat.ReExports -- * @mvhd@ Box @@ -23,9 +24,8 @@ -- available track id, if the track ID is (0xFFFFFFFF) then the system must -- search through all tracks associated with this presentation and figure it -- out, 0 is not allowed.-data MovieHeader (version :: Nat) where+newtype MovieHeader (version :: Nat) where MovieHeader ::- KnownNat version => Timing version :+ Template (I32 "rate") 0x00010000 :+ Template (I16 "volume") 0x0100@@ -36,12 +36,17 @@ :+ Template (U32Arr "pre_defined" 6) '[0,0,0,0,0,0] :+ Template (U32 "next_track_ID") 0xFFFFFFFF -> MovieHeader version+ deriving (IsBoxContent) -- | Time and timing information about a movie (32bit version).-type MovieHeaderTimesV0 = MovieHeaderTimes (Scalar Word32)+type MovieHeaderTimesV0 = MovieHeaderTimes+ (Scalar Word32)+ (Template (U32 "duration") 0xffffffff) -- | Time and timing information about a movie (64bit version).-type MovieHeaderTimesV1 = MovieHeaderTimes (Scalar Word64)+type MovieHeaderTimesV1 = MovieHeaderTimes+ (Scalar Word64)+ (Template (U64 "duration") 0xffffffffffffffff) -- | Time and timing information about a movie. --@@ -50,16 +55,11 @@ -- number of time units that pass one second. The time coordinate system is used -- by e.g. the duration field, which by the way contains the duration of the -- longest track, if known, or simply the equivalent of 1s.-type MovieHeaderTimes uint =+type MovieHeaderTimes uint dur = uint "creation_time" :+ uint "modification_time" :+ TimeScale- :+ uint "duration"---instance IsBoxContent (MovieHeader version) where- boxSize (MovieHeader c) = boxSize c- boxBuilder (MovieHeader c) = boxBuilder c+ :+ dur instance IsBox (MovieHeader version)
src/Data/ByteString/IsoBaseFileFormat/Boxes/NullMediaHeader.hs view
@@ -1,8 +1,9 @@ -- | Indicate that a tracks media content is /null/ or /dummy/ media. module Data.ByteString.IsoBaseFileFormat.Boxes.NullMediaHeader where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box-import Data.ByteString.IsoBaseFileFormat.Boxes.FullBox+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.FullBox+import Data.ByteString.IsoBaseFileFormat.ReExports -- | Null header data box. data NullMediaHeader = NullMediaHeader
src/Data/ByteString/IsoBaseFileFormat/Boxes/ProgressiveDownloadInformation.hs view
@@ -1,9 +1,9 @@ module Data.ByteString.IsoBaseFileFormat.Boxes.ProgressiveDownloadInformation where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box-import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields-import Data.ByteString.IsoBaseFileFormat.Boxes.FullBox+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.BoxFields+import Data.ByteString.IsoBaseFileFormat.Util.FullBox -- | A Box with progressive download information data ProgressiveDownload@@ -19,5 +19,6 @@ -- | Construct a @pdin@ box. pdinBox- :: ProgressiveDownloadContent -> Box (FullBox ProgressiveDownload 0)+ :: ProgressiveDownloadContent+ -> Box (FullBox ProgressiveDownload 0) pdinBox = fullBox 0
src/Data/ByteString/IsoBaseFileFormat/Boxes/SampleDescription.hs view
@@ -3,13 +3,14 @@ -- entry boxes are entailed. module Data.ByteString.IsoBaseFileFormat.Boxes.SampleDescription where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box-import Data.ByteString.IsoBaseFileFormat.Boxes.FullBox-import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.FullBox+import Data.ByteString.IsoBaseFileFormat.Util.BoxFields import Data.Singletons.Prelude.List (Length)+import Data.ByteString.IsoBaseFileFormat.ReExports -- | A sample table contains no fieds.-newtype SampleDescription handlerType =+newtype SampleDescription = SampleDescription (U32 "entry_count") deriving (Default,IsBoxContent) @@ -17,11 +18,11 @@ sampleDescription :: (KnownNat (Length ts)) => Boxes ts- -> Box (ContainerBox (FullBox (SampleDescription h) 0) ts)+ -> Box (ContainerBox (FullBox SampleDescription 0) ts) sampleDescription bs = containerBox (FullBox 0 $ SampleDescription (typeListLength bs)) bs -instance IsBox (SampleDescription h)+instance IsBox SampleDescription -type instance BoxTypeSymbol (SampleDescription h) = "stsd"+type instance BoxTypeSymbol SampleDescription = "stsd"
src/Data/ByteString/IsoBaseFileFormat/Boxes/SampleEntry.hs view
@@ -3,50 +3,50 @@ -- reference entry table. module Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box+import Data.ByteString.IsoBaseFileFormat.Box import Data.ByteString.IsoBaseFileFormat.Boxes.Handler-import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields---- | Specific sample entries must provide an instance for this data family.--- The @format@ parameter will be used as 'BoxTypeSymbol'.-data family SampleEntry (handlertype :: HandlerType) (format :: k)+import Data.ByteString.IsoBaseFileFormat.Util.BoxFields+import Data.ByteString.IsoBaseFileFormat.ReExports -- | Create a 'SampleEntry' 'Box' from the data reference index and the -- 'HandlerType' specific 'SampleEntry' instance. sampleEntry- :: forall (handlertype :: HandlerType) (format :: k)- . U16 "data_reference_index"- -> SampleEntry handlertype format- -> Box (SampleEntry handlertype format)-sampleEntry i c = Box (SampleEntryFields (Constant :+ i :+ c))+ :: U16 "data_reference_index"+ -> handlerSpecific+ -> Box (SampleEntry handlerSpecific)+sampleEntry i se = Box (SampleEntry (Constant :+ i :+ se)) -- | A common header for all specific sample entries, the 'BoxContent' of the--- abstract 'SampleEntry' is @SampleEntryFields (SampleEntry h f)@.-newtype SampleEntryFields a where- SampleEntryFields+-- abstract 'SampleEntry' is @SampleEntry (SampleEntry h f)@.+newtype SampleEntry handlerSpecific where+ SampleEntry :: Constant (U8Arr "reserved" 6) '[0,0,0,0,0,0] :+ U16 "data_reference_index"- :+ a- -> SampleEntryFields a-deriving instance IsBoxContent a => IsBoxContent (SampleEntryFields a)-deriving instance Default a => Default (SampleEntryFields a)+ :+ handlerSpecific+ -> SampleEntry handlerSpecific +deriving instance IsBoxContent handlerSpecific =>+ IsBoxContent (SampleEntry handlerSpecific)++deriving instance Default handlerSpecific =>+ Default (SampleEntry handlerSpecific)+ -- | Use this in 'IsMediaFileFormat's 'BoxLayout' to range over any specific -- 'SampleEntry', disregarding the second parameter (that indicates low-level--- format, protocol or codec characteristics).-data MatchSampleEntry (handlerType :: HandlerType)+-- format, protocol or codec characteristics). Add a 'GetHandlerType' instance for+-- 'MatchSampleEntry' to match a sample type specific entry.+data MatchSampleEntry :: HandlerType -> Type type instance- IsRuleConform (Box (SampleEntry g' f)) (MatchSampleEntry g) =- HandlerTypeCode g' == HandlerTypeCode g+ IsRuleConform (Box (SampleEntry handlerSpecificEntry))+ (MatchSampleEntry handlerType) =+ HandlerTypeCode (GetHandlerType handlerSpecificEntry) == HandlerTypeCode handlerType -- | The 'BoxTypeSymbol' of sample entry is exactly the @format@ type index of -- the 'SampleEntry' family. type instance- BoxTypeSymbol (SampleEntry handlertype format) = BoxTypeSymbol format+ BoxTypeSymbol (SampleEntry handlerSpecific) = BoxTypeSymbol handlerSpecific -instance (IsBoxContent (SampleEntry handlertype format)- ,KnownSymbol (BoxTypeSymbol (SampleEntry handlertype format)))- => IsBox (SampleEntry handlertype format) where- type BoxContent (SampleEntry handlertype format) =- SampleEntryFields (SampleEntry handlertype format)+instance (IsBoxContent handlertype+ ,KnownSymbol (BoxTypeSymbol handlertype))+ => IsBox (SampleEntry handlertype)
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/SampleSize.hs view
@@ -0,0 +1,42 @@+-- | A box containing the sample count and sample size table.+module Data.ByteString.IsoBaseFileFormat.Boxes.SampleSize where++import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.FullBox+import Data.ByteString.IsoBaseFileFormat.ReExports++-- | Content type of the 'FullBox' containing the 'SampleSize'.+type SampleSize = FullBox SampleSizeTable 0++-- | Create a 'SampleSize' box for the case where all sample sizes are equal, no+-- table with the size of each sample is required.+fixedSampleSize :: Word32 -> Word32 -> Box SampleSize+fixedSampleSize sampleSize sampleCount =+ fullBox 0 $ FixedSampleSize sampleSize sampleCount++-- | Create a 'SampleSize' box for the case where samples have different sizes.+-- The list MUST contain an entry for **every sample** in the media file.+individualSampleSizes :: [Word32] -> Box SampleSize+individualSampleSizes sampleSizes =+ fullBox 0 $+ SampleSizeTable (ListContent sampleSizes)++-- | The 'SampleSize' box content. If @sampleSize == 0@ then each sample has its+-- own size and the @table@ field contains an entry for **every** sample, the+-- number of entries is stored in @sampleCount@. Otherwise the samples are+-- assumed to all have the same size: @sampleSize@.+data SampleSizeTable =+ FixedSampleSize { sampleSize :: !Word32, sampleCount :: !Word32 }+ | SampleSizeTable !(ListContent Word32 Word32)++instance IsBox SampleSizeTable++type instance BoxTypeSymbol SampleSizeTable = "stsz"++instance IsBoxContent SampleSizeTable where+ boxSize (FixedSampleSize _ _) = 8+ boxSize (SampleSizeTable entries) = 4 + boxSize entries+ boxBuilder (FixedSampleSize size count) = word32BE size <> word32BE count+ boxBuilder (SampleSizeTable entries) = word32BE 0 <> boxBuilder entries++-- TODO implement compact sample size box (stz2)
src/Data/ByteString/IsoBaseFileFormat/Boxes/SampleTable.hs view
@@ -5,7 +5,7 @@ -- block of audio samples. module Data.ByteString.IsoBaseFileFormat.Boxes.SampleTable where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box+import Data.ByteString.IsoBaseFileFormat.Box -- | A sample table contains no fieds. data SampleTable = SampleTable
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/SampleToChunk.hs view
@@ -0,0 +1,32 @@+-- | The chunks into which samples are grouped, can vary in size, as can the+-- samples within a chunk. This compact table contains the info to find the+-- chunk and offset within of a sample.+module Data.ByteString.IsoBaseFileFormat.Boxes.SampleToChunk where++import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.FullBox+import Data.ByteString.IsoBaseFileFormat.Util.BoxFields+import Data.ByteString.IsoBaseFileFormat.ReExports++-- | An alias for the box content type.+type SampleToChunk = FullBox SampleToChunkTable 0++-- | Define an entry of the compact table. An entry represents a group of chunks+-- of the same size and the same 'SampleDescription'. The @first_chunk@ is an+-- index of the first chunk in a sequence of chunks correspondiing to an entry.+-- The very first entry has an index of 1.+type StscEntry =+ U32 "first_chunk" :+ U32 "samples_per_chunk" :+ U32 "sample_description_index"++-- | A compact table to map decoding time to sample number.+newtype SampleToChunkTable =+ SampleToChunkTable (ListContent (U32 "entry_count") StscEntry)+ deriving (Default, IsBoxContent)++-- | Create a hint media header data box.+sampleToChunk :: [StscEntry] -> Box SampleToChunk+sampleToChunk = fullBox 0 . SampleToChunkTable . ListContent++instance IsBox SampleToChunkTable++type instance BoxTypeSymbol SampleToChunkTable = "stsc"
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/SegmentType.hs view
@@ -0,0 +1,25 @@+module Data.ByteString.IsoBaseFileFormat.Boxes.SegmentType where++import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.ReExports++-- | Segment Type Box+instance IsBox SegmentType where+ type BoxContent SegmentType = SegmentType+type instance BoxTypeSymbol SegmentType = "styp"++-- | Create a 'SegmentTypeBox' from a major brand, a minor version and a list of+-- compatible brands+segmentTypeBox :: SegmentType -> Box SegmentType+segmentTypeBox = Box++-- | Contents of a 'styp' box are some 'FourCc' /brands/ and a version.+data SegmentType =+ SegmentType {majorBrand :: !FourCc -- TODO use U32String+ ,minorVersion :: !Word32 -- TODO use U32String+ ,compatibleBrands :: ![FourCc]} -- TODO use U32String++instance IsBoxContent SegmentType where+ boxSize (SegmentType maj _ver comps) = boxSize maj + 4 + sum (boxSize <$> comps)+ boxBuilder (SegmentType maj ver comps) =+ boxBuilder maj <> word32BE ver <> mconcat (boxBuilder <$> comps)
src/Data/ByteString/IsoBaseFileFormat/Boxes/Skip.hs view
@@ -1,10 +1,12 @@ -- | A filler box with a specific size. module Data.ByteString.IsoBaseFileFormat.Boxes.Skip where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box+import qualified Data.ByteString as B+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.ReExports -- | Contents of a 'skip' box are just any number of filler bytes.-newtype Skip = Skip Int+newtype Skip = Skip B.ByteString instance IsBox Skip where type BoxContent Skip = Skip@@ -16,5 +18,5 @@ skipBox = Box instance IsBoxContent Skip where- boxSize (Skip bs) = fromIntegral bs- boxBuilder (Skip bs) = mconcat (replicate bs (word8 0))+ boxSize (Skip bs) = fromIntegral $ B.length bs+ boxBuilder (Skip bs) = byteString bs
src/Data/ByteString/IsoBaseFileFormat/Boxes/SoundMediaHeader.hs view
@@ -1,11 +1,12 @@ -- | Media-independent properties of a tracks sound content. module Data.ByteString.IsoBaseFileFormat.Boxes.SoundMediaHeader where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box-import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields-import Data.ByteString.IsoBaseFileFormat.Boxes.FullBox+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.BoxFields+import Data.ByteString.IsoBaseFileFormat.Util.FullBox import Data.ByteString.IsoBaseFileFormat.Boxes.Handler import Data.ByteString.IsoBaseFileFormat.Boxes.SpecificMediaHeader+import Data.ByteString.IsoBaseFileFormat.ReExports type instance MediaHeaderFor 'AudioTrack = SoundMediaHeader
− src/Data/ByteString/IsoBaseFileFormat/Boxes/Time.hs
@@ -1,72 +0,0 @@--- | Time and timing utilities.-module Data.ByteString.IsoBaseFileFormat.Boxes.Time- (referenceTime, utcToMp4, mp4CurrentTime, durationFromSeconds,- TimeScale, Timing)- where--import Data.Time.Clock-import Data.Time.Calendar-import Data.Ratio-import Data.ByteString.IsoBaseFileFormat.Boxes.Box-import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields-import Data.ByteString.IsoBaseFileFormat.Boxes.Versioned---- * Absolute Dates--- | According to the standard, fields with absolute dates and times are in--- seconds since 1904/01/01 at midnight (UTC). This is this reference time.-referenceTime :: UTCTime-referenceTime =- let startDay = fromGregorian 1904 1 1- startTime = 0- in UTCTime startDay startTime---- | Convert a 'UTCTime' to a number of seconds since 'referenceTime'.-utcToMp4 :: Num t- => UTCTime -> t-utcToMp4 u =- let picoSecondsDiff = toRational $ diffUTCTime u referenceTime- picoSecondsDiffNumerator = numerator picoSecondsDiff- picoSecondsDiffDenominator = denominator picoSecondsDiff- secondsSinceReferenceTime =- div picoSecondsDiffNumerator picoSecondsDiffDenominator- in fromIntegral secondsSinceReferenceTime---- | Get the current time as number of seconds since 'referenceTime'-mp4CurrentTime :: Num t- => IO t-mp4CurrentTime = utcToMp4 <$> getCurrentTime---- * Time-Scale and Durations--- | Default time-scale value--- Based on history and tradition this value is @90000@.--- MPEG-2 TS defines a single clock for each program, running at 27MHz. The--- timescale of MPEG-2 TS Hint Tracks should be divisable by 90000.-type TimeScale = Template (U32 "timescale") 90000---- | Utility function to convert seconds (Integers) to any 'Num' using a--- 'TimeScale', Since 'Scalar' has a 'Num' instance this can be used to generate--- @duration@ fields.-durationFromSeconds :: Num t- => TimeScale -> Integer -> t-durationFromSeconds timeScale seconds =- let timeScaleI = fromIntegral $ fromScalar $ templateValue timeScale- in timeScaleI * fromInteger seconds---- | Time and timing information about a movie.------ The creation/modification times are in seconds since midnight, Jan. 1, 1904,--- in UTC time. Time scale declares the time coordinate system, it specifies the--- number of time units that pass one second. The time coordinate system is used--- by e.g. the duration field, which by the way contains the duration of the--- longest track, if known, or simply the equivalent of 1s.-type Timing (version :: Nat) = Versioned TimingV0 TimingV1 version--type TimingV0 = TimingImpl (Scalar Word32)--type TimingV1 = TimingImpl (Scalar Word64)--type TimingImpl uint =- uint "creation_time"- :+ uint "modification_time"- :+ TimeScale- :+ uint "duration"
src/Data/ByteString/IsoBaseFileFormat/Boxes/TimeToSample.hs view
@@ -2,9 +2,10 @@ -- seeking in complex media files. module Data.ByteString.IsoBaseFileFormat.Boxes.TimeToSample where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box-import Data.ByteString.IsoBaseFileFormat.Boxes.FullBox-import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.FullBox+import Data.ByteString.IsoBaseFileFormat.Util.BoxFields+import Data.ByteString.IsoBaseFileFormat.ReExports -- | An alias for the box content type. type TimeToSample = FullBox TimeToSampleTable 0
src/Data/ByteString/IsoBaseFileFormat/Boxes/Track.hs view
@@ -1,7 +1,7 @@ -- | Meta data for a presentation of a /movie/. module Data.ByteString.IsoBaseFileFormat.Boxes.Track where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box+import Data.ByteString.IsoBaseFileFormat.Box -- * @trak@ Box -- | Compose a 'Track' box from the given boxes.
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/TrackExtends.hs view
@@ -0,0 +1,62 @@+-- | Default values for duration, size and other metadata of track fragments.+-- This might allow a more efficient transfer and decoding of media.+module Data.ByteString.IsoBaseFileFormat.Boxes.TrackExtends where++import Data.ByteString.IsoBaseFileFormat.Box++import Data.ByteString.IsoBaseFileFormat.Util.FullBox+import Data.ByteString.IsoBaseFileFormat.ReExports++-- * @trex@ Box++-- | Construct a 'TrackExtends' box, with all durations and sizes set to @0@.+-- Only the track index and the index into the sample description table is+-- passed set.+trackExtendsUnknownDuration :: Word32 -> Word32 -> Box (FullBox TrackExtends 0)+trackExtendsUnknownDuration trackId descrIndex = trackExtends trackId descrIndex+ 0 0 0 0 0 0 0 False 0++-- | Construct a 'TrackExtends' box from all its parameters+trackExtends+ :: Word32 -- ^ Track ID+ -> Word32 -- ^ Sample Description Index+ -> Word32 -- ^ Sample Duration+ -> Word32 -- ^ Sample Size+ -> B 2 -- ^ is leading+ -> B 2 -- ^ sample depends on+ -> B 2 -- ^ sample is depended on+ -> B 2 -- ^ sample has redundancy+ -> B 3 -- ^ padding value+ -> Bool -- ^ is non sync sample+ -> Word16 -- ^ sample degradation priority+ -> Box (FullBox TrackExtends 0)+trackExtends =+ wrapBitBuilderBox (fullBox 0 . MkTrackExtends) (Proxy @TrackExtendsBody)++-- | Defaults for movie fragments - the type alias+newtype TrackExtends where+ MkTrackExtends :: BuilderBox -> TrackExtends+ deriving (IsBoxContent)++instance IsBox TrackExtends++type instance BoxTypeSymbol TrackExtends = "trex"++-- | Defaults for movie fragment - the content+type TrackExtendsBody =+ "track_ID" @: FieldU32+ .+: "default_sample_description_index" @: FieldU32+ .+: "default_sample_duration" @: FieldU32+ .+: "default_sample_size" @: FieldU32+ .+: TrackExtendsDefaultSampleFlags++type TrackExtendsDefaultSampleFlags =+ "reserved" @: Field 4 := 0+ .+: "is_leading" @: Field 2+ .+: "sample_depends_on" @: Field 2+ .+: "sample_is_depended_on" @: Field 2+ .+: "sample_has_redundancy" @: Field 2+ .+: "sample_padding_value" @: Field 3+ .+: "sample_is_non_sync_sample" @: Flag+ .+: "sample_degradation_priority" @: FieldU16+ .+: 'EmptyBitRecord
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/TrackFragBaseMediaDecodeTime.hs view
@@ -0,0 +1,32 @@+-- | Sum of the total base media time in the timescale from the movie header box.+module Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragBaseMediaDecodeTime where++import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.FullBox+import Data.ByteString.IsoBaseFileFormat.Util.Time+import GHC.TypeLits++-- * @tfdt@ Box++-- | Construct a 'TrackFragBaseMediaDecodeTime box.+trackFragBaseMediaDecodeTime -- TODO allow 64 bit variant+ :: KnownNat version+ => TS version "track-fragment-base-media-decode-time"+ -> Box (FullBox (TrackFragBaseMediaDecodeTime version) version)+trackFragBaseMediaDecodeTime = fullBox 0 . TrackFragBaseMediaDecodeTime++-- | Track fragment media base decode time+newtype TrackFragBaseMediaDecodeTime (version :: Nat) where+ TrackFragBaseMediaDecodeTime+ :: TS version "track-fragment-base-media-decode-time"+ -> TrackFragBaseMediaDecodeTime version+ deriving (IsBoxContent)++instance IsBox (TrackFragBaseMediaDecodeTime v)++type instance BoxTypeSymbol (TrackFragBaseMediaDecodeTime v) = "tfdt"++-- | Return the static size of the empty box+trackFragBaseMediaDecodeTimeStaticSize64 :: Num a => a+trackFragBaseMediaDecodeTimeStaticSize64 =+ fromBoxSize 0 (boxSize (trackFragBaseMediaDecodeTime (TSv1 0)))
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/TrackFragment.hs view
@@ -0,0 +1,23 @@+-- | Meta data for fragments of a track inside a movie fragment.+module Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragment where++import Data.ByteString.IsoBaseFileFormat.Box++-- * @traf@ Box++-- | Compose a 'TrackFragment' box from the given boxes.+trackFragment+ :: Boxes ts -> Box (ContainerBox TrackFragment ts)+trackFragment = containerBox ()++-- | Container box for tracks.+data TrackFragment++instance IsBox TrackFragment where+ type BoxContent TrackFragment = ()++type instance BoxTypeSymbol TrackFragment = "traf"++-- | Return the static size of the empty box+trackFragmentStaticSize :: Num a => a+trackFragmentStaticSize = fromBoxSize 0 (boxSize (trackFragment NoBoxes))
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/TrackFragmentHeader.hs view
@@ -0,0 +1,33 @@+-- | Meta data for a presentation of a /movie fragment/.+module Data.ByteString.IsoBaseFileFormat.Boxes.TrackFragmentHeader where++import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.BoxFields+import Data.ByteString.IsoBaseFileFormat.Util.FullBox+import Data.Default++-- * @tfhd@ Box++-- | Construct a 'TrackFragmentHeader' box.++trackFragmentHeader -- TODO allow 64 bit variant+ :: TrackFragmentHeader -> Box (FullBox TrackFragmentHeader 0)+trackFragmentHeader =+ fullBox 0x020000 -- TODO box is hard coded for file offset calculations in the 'trun' box++-- | Track fragment meta data+-- TODO box is hard coded for file offset calculations in the 'trun' box+newtype TrackFragmentHeader where+ TrackFragmentHeader ::+ Template (U32 "track_ID") 0x001+ -> TrackFragmentHeader+ -- TODO all optional fields currently omitted for offset calculations in the 'trun' box+ deriving (IsBoxContent, Default)++instance IsBox TrackFragmentHeader++type instance BoxTypeSymbol TrackFragmentHeader = "tfhd"++-- | Return the static size of the empty box+trackFragmentHeaderStaticSize :: Num a => a+trackFragmentHeaderStaticSize = fromBoxSize 0 (boxSize (trackFragmentHeader def))
src/Data/ByteString/IsoBaseFileFormat/Boxes/TrackHeader.hs view
@@ -1,20 +1,39 @@ -- | Track header box-module Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader where+module Data.ByteString.IsoBaseFileFormat.Boxes.TrackHeader+ (trackHeader, TrackHeader(..), TrackHeaderFlags(..)+ , type TrackHeaderTimes , type TrackHeaderTimesV0 , type TrackHeaderTimesV1 ) where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box-import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields-import Data.ByteString.IsoBaseFileFormat.Boxes.FullBox-import Data.ByteString.IsoBaseFileFormat.Boxes.Versioned+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.BoxFields+import Data.ByteString.IsoBaseFileFormat.Util.FullBox+import Data.ByteString.IsoBaseFileFormat.Util.Versioned+import Data.ByteString.IsoBaseFileFormat.Util.Time+import Data.ByteString.IsoBaseFileFormat.ReExports -- * @tkhd@ Box -- | Create a 'TrackHeader' box. trackHeader- :: KnownNat version- => TrackHeader version -> Box (FullBox (TrackHeader version) version)-trackHeader = fullBox 0+ :: forall version . ( KnownNat version )+ => TrackHeaderFlags+ -> TrackHeader version+ -> Box (FullBox (TrackHeader version) version)+trackHeader flags = fullBox flags'+ where+ flags' = case flags of+ TrackDisabled -> 0+ TrackEnabled -> 1+ TrackInMovie -> 3+ TrackInMovieAndPreview -> 7 +data TrackHeaderFlags =+ TrackDisabled+ | TrackEnabled+ | TrackInMovie+ | TrackInMovieAndPreview++ -- | Track meta data, indexed by a version.-data TrackHeader (version :: Nat) where+newtype TrackHeader (version :: Nat) where TrackHeader :: Versioned TrackHeaderTimesV0 TrackHeaderTimesV1 version :+ Constant (I32Arr "reserved" 2) '[0, 0]@@ -27,25 +46,26 @@ :+ I32 "width" :+ I32 "height" -> TrackHeader version+ deriving (IsBoxContent) -- | Time and timing information about a track (32bit version).-type TrackHeaderTimesV0 = TrackHeaderTimes (Scalar Word32)+type TrackHeaderTimesV0 = TrackHeaderTimes+ (Scalar Word32)+ (TS32 "duration") -- | Time and timing information about a track (64bit version).-type TrackHeaderTimesV1 = TrackHeaderTimes (Scalar Word64)+type TrackHeaderTimesV1 = TrackHeaderTimes+ (Scalar Word64)+ (TS64 "duration") -- | Time and timing information about a track.-type TrackHeaderTimes uint =+type TrackHeaderTimes uint dur = uint "creation_time" :+ uint "modification_time" :+ U32 "track_ID" :+ Constant (U32 "reserved") 0- :+ uint "duration"--instance IsBoxContent (TrackHeader version) where- boxSize (TrackHeader c) = boxSize c- boxBuilder (TrackHeader c) = boxBuilder c+ :+ dur -instance IsBox (TrackHeader version)+instance IsBox (TrackHeader v) -type instance BoxTypeSymbol (TrackHeader version) = "tkhd"+type instance BoxTypeSymbol (TrackHeader v) = "tkhd"
+ src/Data/ByteString/IsoBaseFileFormat/Boxes/TrackRun.hs view
@@ -0,0 +1,80 @@+-- | A list of sample offsets and sizes of a track. This tells the decoder where+-- stuff inside an 'mdat' box is, and also where the 'mdat' box /starts/, which+-- is the reason why currently there are several TODOs concercning the offset+-- calculation.+module Data.ByteString.IsoBaseFileFormat.Boxes.TrackRun (trackRunIso5, TrackRun) where++import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.ReExports+import qualified Data.ByteString as BS++-- | Create a track run box. First parameter is the accumulated offset to the+-- /moof/ box. This is needed for data offset calculation. Then follows a list+-- of __sample-duration__ and __sample-sizes__. All samples are flagged+-- /independent/.+trackRunIso5 :: Int32 -> [(Word32, BS.ByteString)] -> Box TrackRun+trackRunIso5 !mdatOffset !samples = Box c+ where+ !c = TrackRun (header <> body)+ where+ !header = h (fromIntegral sampleCount) dataOffset+ where+ !dataOffset = 8 -- box size field + fourcc code of this very box+ + mdatOffset + 8 -- +8 because we want to skip the box header od the mdat box+ + fromIntegral+ ((headerStaticSize `div` 8)+ + sampleCount * (sampleStaticSize `div` 8))+ !h = bitBuilderBox (Proxy @(Header TrackRunFlagsIso5))+ !headerStaticSize = (natVal (Proxy @(BitRecordSize (Header TrackRunFlagsIso5))))+ !sampleStaticSize = (natVal (Proxy @(BitRecordSize (Sample TrackRunFlagsIso5))))+ !sampleCount = fromIntegral (length samples)++ !body = mconcat $ s <$> samples+ where+ s (!duration, !bs) = bitBuilderBox (Proxy @(Sample TrackRunFlagsIso5)) duration size+ where+ !size = fromIntegral (BS.length bs)++newtype TrackRun where+ TrackRun :: BuilderBox -> TrackRun+ deriving (IsBoxContent)++instance IsBox TrackRun+type instance BoxTypeSymbol TrackRun = "trun"++-- class MkTrackRunArgs (t :: IsA (TrackRunFlags sop fsp sdp ssp sfp sop)) where+-- data TrRunArgs (t :: IsA (TrackRunFlags sop fsp sdp ssp sfp sop))++data TrackRunFlags+ (dataOffsetPresent :: Bool)+ (firstSampleFlagsPresent :: Bool)+ (sampleDurationPresent :: Bool)+ (sampleSizePresent :: Bool)+ (sampleFlagsPresent :: Bool)+ (sampleCompositionTimeOffsetPresent :: Bool)++data TrackRunFlagsIso5+ :: IsA (TrackRunFlags 'True 'False 'True 'True 'True 'False)++type Header (t :: IsA (TrackRunFlags dop fsp sdp ssp sfp sctop)) =+ "version" @: FieldU8 := 0 -- TODO allow version 1+ .+: Field 12 := 0+ .+: "sample-scto-present" @: Flag := sctop+ .+: "sample-flags-present" @: Flag := sfp+ .+: "sample-size-present" @: Flag := ssp+ .+: "sample-duration-present" @: Flag := sdp+ .+: Field 5 := 0+ .+: "first-sample-flag-present" @: Flag := fsp+ .+: Flag := 'False+ .+: "data-offset-preset" @: Flag := dop+ .+: "sample-count" @: FieldU32+ .+: WhenR dop+ ('BitRecordMember ("data-offset" @: FieldI32))+ :+: WhenR fsp+ ('BitRecordMember ("first-sample-flags" @: FieldU32))+++type Sample (t :: IsA (TrackRunFlags dop fsp sdp ssp sfp sctop)) =+ WhenR sdp ('BitRecordMember ("sample-duration" @: FieldU32))+ :+: WhenR ssp ('BitRecordMember ("sample-size" @: FieldU32))+ :+: WhenR sfp ('BitRecordMember ("sample-flags" @: FieldU32 := 0x02000000)) -- TODO allow flags as in TrackExtends
− src/Data/ByteString/IsoBaseFileFormat/Boxes/Versioned.hs
@@ -1,24 +0,0 @@-{-# LANGUAGE UndecidableInstances #-}--- | A binary version 0/1 field with seperate content for each version.-module Data.ByteString.IsoBaseFileFormat.Boxes.Versioned- (Versioned(..))- where--import Data.ByteString.IsoBaseFileFormat.Boxes.Box---- TODO rewrite/cleanup the versioned mess---- | Two alternative representations based on a /version/ index.--- Use this for box content that can be either 32 or 64 bit.-data Versioned v0 v1 (version :: Nat) where- V0 :: IsBoxContent v0 => v0 -> Versioned v0 v1 0- V1 :: IsBoxContent v1 => v1 -> Versioned v0 v1 1--instance (version ~ 0,IsBoxContent v0,Default v0) => Default (Versioned v0 v1 (version :: Nat)) where- def = V0 def--instance IsBoxContent (Versioned v0 v1 version) where- boxSize (V0 c) = boxSize c- boxSize (V1 c) = boxSize c- boxBuilder (V0 c) = boxBuilder c- boxBuilder (V1 c) = boxBuilder c
src/Data/ByteString/IsoBaseFileFormat/Boxes/VideoMediaHeader.hs view
@@ -1,11 +1,12 @@ -- | Media-independent properties of a tracks video content. module Data.ByteString.IsoBaseFileFormat.Boxes.VideoMediaHeader where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box-import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields-import Data.ByteString.IsoBaseFileFormat.Boxes.FullBox+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.BoxFields+import Data.ByteString.IsoBaseFileFormat.Util.FullBox import Data.ByteString.IsoBaseFileFormat.Boxes.Handler import Data.ByteString.IsoBaseFileFormat.Boxes.SpecificMediaHeader+import Data.ByteString.IsoBaseFileFormat.ReExports type instance MediaHeaderFor 'VideoTrack = VideoMediaHeader
src/Data/ByteString/IsoBaseFileFormat/Boxes/VisualSampleEntry.hs view
@@ -2,27 +2,17 @@ -- | Detailed visual sample description. module Data.ByteString.IsoBaseFileFormat.Boxes.VisualSampleEntry where -import Data.ByteString.IsoBaseFileFormat.Boxes.Box-import Data.ByteString.IsoBaseFileFormat.Boxes.BoxFields+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.BoxFields import Data.ByteString.IsoBaseFileFormat.Boxes.Handler-import Data.ByteString.IsoBaseFileFormat.Boxes.SampleEntry+import Data.ByteString.IsoBaseFileFormat.ReExports import qualified Data.Text as T --- | Construct a visual sample entry box-visualSampleEntry ::- (KnownSymbol- (BoxTypeSymbol (SampleEntry 'VideoTrack (VideoCoding codec))))- => VideoCoding codec- -> U16 "data_reference_index"- -> SampleEntry 'VideoTrack (VideoCoding codec)- -> Box (SampleEntry 'VideoTrack (VideoCoding codec))-visualSampleEntry _ = sampleEntry- -- | Fields if visual sample entries. -- A @depth@ of 0x0018 means colour image with no alpha. -- The @horizresolution@ and @vertresolution@ of 0x00480000 means 72 dpi. -- The @frame_count@ indicates the number of video frames per sample.-newtype instance SampleEntry 'VideoTrack (VideoCoding c) where+newtype VideoSampleEntry c where VideoSampleEntry :: U16 "pre_defined" :+ Constant (U16 "reserved") 0@@ -38,21 +28,17 @@ :+ Maybe (Box CleanAperture) :+ Maybe (Box PixelAspectRatio) :+ [Box SomeColourInformation]- -> SampleEntry 'VideoTrack (VideoCoding c)+ :+ c+ -> VideoSampleEntry c deriving (IsBoxContent, Default) +type instance GetHandlerType (VideoSampleEntry c) = 'VideoTrack+type instance BoxTypeSymbol (VideoSampleEntry c) = BoxTypeSymbol c+ instance IsBoxContent [Box SomeColourInformation] where boxSize = sum . fmap boxSize boxBuilder = fold . fmap boxBuilder --- | A coproduct of video codec types-data family VideoCoding (c :: Symbol)---- | Simple default MPEG-4 video-data instance VideoCoding "mp4v" = Mpeg4Avc--type instance BoxTypeSymbol (VideoCoding c) = c- -- * Clean Aperture sub box -- | Construct a 'CleanAperture' (sub-) 'Box'@@ -124,7 +110,7 @@ SomeColourInformation :: forall (profile :: ColourTypeProfile) . IsBoxContent (ColourInformation profile)- => ColourInformation profile+ => !(ColourInformation profile) -> SomeColourInformation instance IsBoxContent SomeColourInformation where boxSize (SomeColourInformation c) = boxSize c
src/Data/ByteString/IsoBaseFileFormat/Brands/Dash.hs view
@@ -4,13 +4,15 @@ -- educational, current need. -- This is a convenient way of building documents of that kind. module Data.ByteString.IsoBaseFileFormat.Brands.Dash- (Dash, SingleAudioTrackInit(..), mkSingleTrackInit, module X)+ (Dash, dash) where+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.MediaFile+import Data.ByteString.IsoBaseFileFormat.Boxes+import Data.ByteString.IsoBaseFileFormat.ReExports -import Data.ByteString.IsoBaseFileFormat.Brands.Types-import Data.ByteString.IsoBaseFileFormat.Boxes as X hiding (All)-import Data.Kind (Type, Constraint) +-- TODO rename dash to iso5 -- | A phantom type to indicate this branding. Version can be 0 or 1 it is used -- in some boxes to switch between 32/64 bits. data Dash (version :: Nat)@@ -20,11 +22,16 @@ dash = Proxy -- | A 'BoxLayout' which contains the stuff needed for the 'dash' brand.--- TODO incomplete+-- TODO add iso1 iso2 iso3 iso5 isom formats instance IsMediaFileFormat (Dash v) where type BoxLayout (Dash v) =+ OneOf '[ MovieLayout v+ , SegmentLayout]++type MovieLayout v = Boxes '[ OM_ FileType+ , OM_ Skip , OM Movie '[ OM_ (MovieHeader v) , SomeMandatoryX@@ -33,8 +40,10 @@ , TrackLayout v 'HintTrack , TrackLayout v 'TimedMetaDataTrack , TrackLayout v 'AuxilliaryVideoTrack])+ , OO MovieExtends+ '[ OO_ (MovieExtendsHeader v)+ , OM_ TrackExtends ] ]- , SO_ Skip ] type TrackLayout version handlerType =@@ -52,58 +61,27 @@ (OneOf '[ OM_ DataEntryUrl , OM_ DataEntryUrn])]] , OM SampleTable- '[ OM (SampleDescription handlerType)+ '[ OM SampleDescription '[ SomeMandatoryX (MatchSampleEntry handlerType) ] , OM_ TimeToSample- -- , OM_ (SampleToChunk version)- -- , OO_ (SampleSizes version)- -- , OM_ (SampleChunkOffset version)+ , OM_ SampleToChunk+ , OM_ SampleSize+ , OneOf '[ OM_ ChunkOffset32+ , OM_ ChunkOffset64 ] ] ] ] ]) ---- Missing Boxes--- stts--- stsc--- stsz--- stco--- esds--- mvex--- trex--- For media--- styp--- moof--- mfhd--- traf--- tfhd--- trun--- | A record which contains the stuff needed for a single track initialization--- document according to the 'Dash' brand. TODO incomplete--- TODO take this out into its own module, make a new package for specific file formats-data SingleAudioTrackInit =- SingleAudioTrackInit {mvhd :: MovieHeader 0- ,tkhd :: TrackHeader 0- ,mdhd :: MediaHeader 0- ,hdlr :: Handler 'AudioTrack- ,smhd :: SoundMediaHeader}---- | Convert a 'SingleAudioTrackInit' record to a generic 'Boxes' collection.-mkSingleTrackInit- :: SingleAudioTrackInit -> Builder-mkSingleTrackInit doc = mediaBuilder dash $- fileTypeBox (FileType "dash" 0 ["isom","iso5","mp42"])- :| movie- ( movieHeader (mvhd doc)- :| track- ( trackHeader (tkhd doc)- :| media- ( mediaHeader (mdhd doc)- :. handler (hdlr doc)- :| mediaInformation- ( soundMediaHeader (smhd doc)- :. (dataInformation $: localMediaDataReference)- :| sampleTable- ((sampleDescription $: audioSampleEntry Mpeg4Aac 1 def)- :| timeToSample [] )))))+type SegmentLayout =+ Boxes '[ OM_ SegmentType+ , OM MovieFragment+ '[ OM_ MovieFragmentHeader+ , OM TrackFragment+ '[ OM_ TrackFragmentHeader+ , OO_ (TrackFragBaseMediaDecodeTime 1)+ , SO_ TrackRun+ ]+ ]+ , SM_ MediaData+ ]
− src/Data/ByteString/IsoBaseFileFormat/Brands/Types.hs
@@ -1,17 +0,0 @@--- | Brand/Box-validation-module Data.ByteString.IsoBaseFileFormat.Brands.Types- where--import Data.ByteString.IsoBaseFileFormat.Boxes.Box-import Data.ByteString.IsoBaseFileFormat.Util.TypeLayout ()---- TODO move this to general module merge with Box.hs--- | A class that describes (on the type level) how a box can be nested into--- other boxes (see 'Boxes).-class IsMediaFileFormat brand where- -- | The layout that an IsBoxContent instance has to have, before 'packMedia' accepts it- type BoxLayout brand- mediaBuilder- :: forall t proxy . (IsBoxContent t, IsRuleConform t (BoxLayout brand) ~ 'True)- => proxy brand -> t -> Builder- mediaBuilder _ t = boxBuilder t
+ src/Data/ByteString/IsoBaseFileFormat/MediaFile.hs view
@@ -0,0 +1,18 @@+-- | Brand/Box-validation+module Data.ByteString.IsoBaseFileFormat.MediaFile+ where++import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.TypeLayout+import Data.ByteString.IsoBaseFileFormat.ReExports++-- TODO move this to general module merge with Box.hs+-- | A class that describes (on the type level) how a box can be nested into+-- other boxes (see 'Boxes).+class IsMediaFileFormat brand where+ -- | The layout that an IsBoxContent instance has to have, before 'packMedia' accepts it+ type BoxLayout brand+ mediaBuilder+ :: forall t proxy . (IsBoxContent t, IsRuleConform t (BoxLayout brand) ~ 'True)+ => proxy brand -> t -> Builder+ mediaBuilder _ t = boxBuilder t
+ src/Data/ByteString/IsoBaseFileFormat/ReExports.hs view
@@ -0,0 +1,41 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}++-- | A module of re-exports and orphan instances+module Data.ByteString.IsoBaseFileFormat.ReExports (module X) where+++import Data.Bits as X+import qualified Data.ByteString as B+import Data.ByteString.Builder as X+import Data.ByteString.IsoBaseFileFormat.Util.TypeLayout as X+import Data.Default as X+import Data.Foldable as X (fold)+import Data.Int as X+import Data.Kind as X (Constraint,+ Type)+import Data.Kind.Extra as X+import Data.Maybe as X+import Data.Monoid as X+import Data.Proxy as X+import Data.String as X+import Data.Tagged as X+import qualified Data.Text as T+import Data.Type.Bool as X+import Data.Type.BitRecords as X+import Data.Type.Equality as X+import Data.Type.Pretty as X+import Data.Word as X+import GHC.TypeLits as X+import Test.TypeSpecCrazy as X hiding+ (type Not)+import Text.Printf as X+import Debug.Trace as X++instance Default B.ByteString where+ def = mempty++instance Default T.Text where+ def = ""++instance Default c => Default (Tagged s c) where+ def = Tagged def
− src/Data/ByteString/IsoBaseFileFormat/Util/BitRecords.hs
@@ -1,214 +0,0 @@-{-# LANGUAGE UndecidableInstances #-}-module Data.ByteString.IsoBaseFileFormat.Util.BitRecords where--import Data.Kind-import Data.Word-import Data.Type.Bool-import GHC.TypeLits-import Data.Bits-import Data.Proxy-import Test.TypeSpecCrazy--data Field :: Nat -> Type-data (:=>) :: k -> Type -> Type-data (:*:) :: Type -> Type -> Type-type FieldPosition = (Nat, Nat)--type Flag = Field 1--infixr 6 :=>-infixl 5 :*:---- nested fields-data (:/) :: Symbol -> k -> Type-infixr 7 :/---type family- GetFieldSize (f :: l) :: Nat where- GetFieldSize (label :=> f) = GetFieldSize f- GetFieldSize (Field n ) = n- GetFieldSize (l :*: r) = GetFieldSize l + GetFieldSize r--type family- HasField (f :: fk) (l :: lk) :: Bool where- HasField (l :=> f) l = 'True- HasField (l :=> f) (l :/ p) = HasField f p- HasField (f1 :*: f2) l = HasField f1 l || HasField f2 l- HasField f l = 'False--type family- HasFieldConstraint (label :: lk) (field :: fk) :: Constraint where- HasFieldConstraint l f =- If (HasField f l)- (HasField f l ~ 'True)- (TypeError ('Text "Label not found: '"- ':<>: 'ShowType l- ':<>: 'Text "' in:"- ':$$: 'ShowType f ))--type family- FocusOn (l :: lk) (f :: fk) :: Result fk where- FocusOn l f =- If (HasField f l)- ('Right (FocusOnUnsafe l f))- ('Left ('Text "Label not found. Cannot focus '"- ':<>: 'ShowType l- ':<>: 'Text "' in:"- ':$$: 'ShowType f ))--type family- FocusOnUnsafe (l :: lk) (f :: fk) :: fk where- FocusOnUnsafe l (l :=> f) = f- FocusOnUnsafe (l :/ p) (l :=> f) = FocusOnUnsafe p f- FocusOnUnsafe l (f :*: f') = FocusOnUnsafe l (If (HasField f l) f f')---- field location and access--type family- GetFieldPosition (f :: field) (l :: label) :: Result FieldPosition where- GetFieldPosition f l =- If (HasField f l)- ('Right (GetFieldPositionUnsafe f l))- ('Left ('Text "Label not found. Cannot get bit range for '"- ':<>: 'ShowType l- ':<>: 'Text "' in:"- ':$$: 'ShowType f ))--type family- GetFieldPositionUnsafe (f :: field) (l :: label) :: FieldPosition where- GetFieldPositionUnsafe (l :=> f) l = '(0, GetFieldSize f - 1)- GetFieldPositionUnsafe (l :=> f) (l :/ p) = GetFieldPositionUnsafe f p- GetFieldPositionUnsafe (f :*: f') l =- If (HasField f l)- (GetFieldPositionUnsafe f l)- (AddToFieldPosition (GetFieldSize f) (GetFieldPositionUnsafe f' l))--type family- AddToFieldPosition (v :: Nat) (e :: (Nat, Nat)) :: (Nat, Nat) where- AddToFieldPosition v '(a,b) = '(a + v, b + v)--type family- IsFieldPostition (pos :: FieldPosition) :: Constraint where- IsFieldPostition '(a, b) =- If (a <=? b)- (a <= b, KnownNat a, KnownNat b)- (TypeError- ('Text "Bad field position: " ':<>: 'ShowType '(a,b)- ':$$: 'Text "First index greater than last: "- ':<>: 'ShowType a- ':<>: 'Text " > "- ':<>: 'ShowType b ))--type family- FieldPostitionToList (pos :: FieldPosition) :: [Nat] where- FieldPostitionToList '(a, a) = '[a]- FieldPostitionToList '(a, b) = (a ': (FieldPostitionToList '(a+1, b)))--type family- AlignField (a :: Nat) (f :: field) :: Result field where- AlignField 0 f = 'Left ('Text "Invalid alignment of 0")- AlignField a f = 'Right (AddPadding ((a - (GetFieldSize f `Rem` a)) `Rem` a) f)--type family- AddPadding (n :: Nat) (f :: field) :: field where- AddPadding 0 f = f- AddPadding n f = f :*: Field n---- | Get the remainder of the integer division of x and y, such that @forall x--- y. exists k. (Rem x y) == x - y * k@ The algorithm is: count down x--- until zero, incrementing the accumulator at each step. Whenever the--- accumulator is equal to y set it to zero.------ If the accumulator has reached y reset it. It is important to do this--- BEFORE checking if x == y and then returning the accumulator, for the case--- where x = k * y with k > 0. For example:------ @--- 6 `Rem` 3 = RemImpl 6 3 0--- RemImpl 6 3 0 = RemImpl (6-1) 3 (0+1) -- RemImpl Clause 4--- RemImpl 5 3 1 = RemImpl (5-1) 3 (1+1) -- RemImpl Clause 4--- RemImpl 4 3 2 = RemImpl (4-1) 3 (2+1) -- RemImpl Clause 4--- RemImpl 3 3 3 = RemImpl 3 3 0 -- RemImpl Clause 2 !!!--- RemImpl 3 3 0 = 0 -- RemImpl Clause 3 !!!--- @----type Rem (x :: Nat) (y :: Nat) = RemImpl x y 0-type family- RemImpl (x :: Nat) (y :: nat) (acc :: Nat) :: Nat where- -- finished if x was < y:- RemImpl 0 y acc = acc- RemImpl x y y = RemImpl x y 0- -- finished if x was >= y:- RemImpl y y acc = acc- -- the base case- RemImpl x y acc = RemImpl (x - 1) y (acc + 1)--getFlag- :: forall a (path :: k) (first :: Nat) field p1 p2- . ( IsFieldC path field first first- , Bits a )- => p1 path -> p2 field -> a -> Bool-getFlag _ _ a = testBit a pos- where pos = fromIntegral $ natVal (Proxy :: Proxy first)--setFlag- :: forall a (path :: k) (first :: Nat) field p1 p2- . ( IsFieldC path field first first- , Bits a )- => p1 path -> p2 field -> Bool -> a -> a-setFlag _ _ v a = modifyBit a pos- where pos = fromIntegral $ natVal (Proxy :: Proxy first)- modifyBit = if v then setBit else clearBit--getField- :: forall a b (path :: k) (first :: Nat) (last :: Nat) field pxy1 pxy2- . ( IsFieldC path field first last- , Integral a- , Bits a- , Num b)- => pxy1 path -> pxy2 field -> a -> b-getField _ _ a = fromIntegral ((a `shiftR` posFirst) .&. bitMask)- where- bitMask =- let bitCount = 1 + posLast - posFirst- in (2 ^ bitCount) - 1- posFirst = fromIntegral $ natVal (Proxy :: Proxy first)- posLast = fromIntegral $ natVal (Proxy :: Proxy last)--setField- :: forall a b (path :: k) (first :: Nat) (last :: Nat) field pxy1 pxy2- . ( IsFieldC path field first last- , Num a- , Bits a- , Integral b)- => pxy1 path -> pxy2 field -> b -> a -> a-setField _ _ v x = (x .&. bitMaskField) .|. (v' `shiftL` posFirst)- where- v' = bitMaskValue .&. fromIntegral v- bitMaskField = complement (bitMaskValue `shiftL` posFirst)- bitMaskValue =- let bitCount = 1 + posLast - posFirst- in (2 ^ bitCount) - 1- posFirst = fromIntegral $ natVal (Proxy :: Proxy first)- posLast = fromIntegral $ natVal (Proxy :: Proxy last)----type Foo =- "foo" :=> Flag- :*: Field 4- :*: "bar" :=> Field 2- :*: Field 4- :*: "baz" :=> Field 17--type IsFieldC name field first last =- ( name `HasFieldConstraint` field- , KnownNat first- , KnownNat last- , 'Right '(first, last) ~ (GetFieldPosition field name)- )--getFooField :: IsFieldC name Foo first last- => proxy name -> Word64 -> Word64-getFooField px = getField px (Proxy :: Proxy Foo)
+ src/Data/ByteString/IsoBaseFileFormat/Util/BoxFields.hs view
@@ -0,0 +1,304 @@+{-# LANGUAGE UndecidableInstances #-}+-- | Mini EDSL for labelled box fields. The boxfields can be 'Scalar' or+-- 'ScalarArray's.+module Data.ByteString.IsoBaseFileFormat.Util.BoxFields+ where++import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.ReExports+import Data.Singletons++import Data.Singletons.Prelude.List+import qualified Data.Vector as Vec+import qualified Data.Text as T+import qualified Data.Text.Encoding as T+import qualified Data.ByteString as B+++-- * Scalar box fields++type U64 label = Scalar Word64 label++type I64 label = Scalar Int64 label++u64 :: Word64 -> U64 label+u64 = Scalar++i64 :: Int64 -> I64 label+i64 = Scalar++type U32 label = Scalar Word32 label+type I32 label = Scalar Int32 label++u32 :: Word32 -> U32 label+u32 = Scalar++i32 :: Int32 -> I32 label+i32 = Scalar++type U16 label = Scalar Word16 label++type I16 label = Scalar Int16 label++u16 :: Word16 -> U16 label+u16 = Scalar++i16 :: Int16 -> I16 label+i16 = Scalar++type U8 label = Scalar Word8 label++type I8 label = Scalar Int8 label++u8 :: Word8 -> U8 label+u8 = Scalar++i8 :: Int8 -> I8 label+i8 = Scalar++-- | A numeric box field with a type level label. Note that it has a 'Num'+-- instance. Use the type aliases above, e.g.+-- 'U8','I8','U16','I16','U32','I32','U64','I64' from above. Use either the+-- smart constructors, e.g. 'u8','i8','u16','i16','u32','i32','u64','i64' or the+-- 'Num' instance, whereas the constructors might give a bit more safety.+newtype Scalar scalartype (label :: k) =+ Scalar {fromScalar :: scalartype}+ deriving (Show, Read, Ord, Eq, Num, Default)++-- | Relabel a scalar value, e.g. convert a @Scalar U32 "foo"@ to a @Scalar U32+-- "bar"@.+relabelScalar :: Scalar t l -> Scalar t l'+relabelScalar (Scalar !x) = Scalar x++instance IsBoxContent (Scalar Word8 label) where+ boxSize _ = 1+ boxBuilder (Scalar !v) = word8 v++instance IsBoxContent (Scalar Word16 label) where+ boxSize _ = 2+ boxBuilder (Scalar !v) = word16BE v++instance IsBoxContent (Scalar Word32 label) where+ boxSize _ = 4+ boxBuilder (Scalar !v) = word32BE v++instance IsBoxContent (Scalar Word64 label) where+ boxSize _ = 8+ boxBuilder (Scalar !v) = word64BE v++instance IsBoxContent (Scalar Int8 label) where+ boxSize _ = 1+ boxBuilder (Scalar !v) = int8 v++instance IsBoxContent (Scalar Int16 label) where+ boxSize _ = 2+ boxBuilder (Scalar !v) = int16BE v++instance IsBoxContent (Scalar Int32 label) where+ boxSize _ = 4+ boxBuilder (Scalar !v) = int32BE v++instance IsBoxContent (Scalar Int64 label) where+ boxSize _ = 8+ boxBuilder (Scalar !v) = int64BE v++instance (KnownNat scalar,Num o) => FromTypeLit (Scalar o label) scalar where+ fromTypeLit _ = Scalar $ fromIntegral $ natVal (Proxy :: Proxy scalar)++-- * Array fields++type U64Arr label size = ScalarArray label size Word64++u64Arr :: (KnownNat size,KnownSymbol label)+ => [Word64] -> U64Arr label size+u64Arr = fromList++type I64Arr label size = ScalarArray label size Int64++i64Arr :: (KnownNat size,KnownSymbol label)+ => [Int64] -> I64Arr label size+i64Arr = fromList++type U32Arr label size = ScalarArray label size Word32++u32Arr :: (KnownNat size,KnownSymbol label)+ => [Word32] -> U32Arr label size+u32Arr = fromList++type I32Arr label size = ScalarArray label size Int32++i32Arr :: (KnownNat size,KnownSymbol label)+ => [Int32] -> I32Arr label size+i32Arr = fromList++type U16Arr label size = ScalarArray label size Word16++u16Arr :: (KnownNat size,KnownSymbol label)+ => [Word16] -> U16Arr label size+u16Arr = fromList++type I16Arr label size = ScalarArray label size Int16++i16Arr :: (KnownNat size,KnownSymbol label)+ => [Int16] -> I16Arr label size+i16Arr = fromList++type U8Arr label size = ScalarArray label size Word8++u8Arr :: (KnownNat size,KnownSymbol label)+ => [Word8] -> U8Arr label size+u8Arr = fromList++type I8Arr label size = ScalarArray label size Int8++i8Arr :: (KnownNat size,KnownSymbol label)+ => [Int8] -> I8Arr label size+i8Arr = fromList++-- | A box field that is an array of 'Scalar's with a type level label. Use the+-- type aliases, e.g.+-- 'U8Arr','I8Arr','U16Arr','I16Arr','U32Arr','I32Arr','U64Arr','I64Arr' from+-- above. Use the smart constructors, e.g.+-- 'u8Arr','i8Arr','u16Arr','i16Arr','u32Arr','i32Arr','u64Arr','i64Arr' .+newtype ScalarArray (label :: k) (len :: Nat) o where+ ScalarArray :: Vec.Vector o -> ScalarArray label n o+ deriving (Show,Eq)++instance (Default o,KnownNat (len :: Nat))+ => Default (ScalarArray label len o) where+ def = ScalarArray $ Vec.replicate (fromIntegral (natVal (Proxy @len))) def++instance (Num o,IsBoxContent (Scalar o label))+ => IsBoxContent (ScalarArray label len o) where+ boxSize (ScalarArray !vec) =+ fromIntegral (Vec.length vec) * boxSize (Scalar 0 :: Scalar o label)+ boxBuilder (ScalarArray !vec) =+ Vec.foldl' mappend+ mempty+ (Vec.map (boxBuilder . mkScalar) vec)+ where mkScalar :: o -> Scalar o label+ !mkScalar = Scalar++-- | Internal function+fromList :: forall label n o.+ (KnownSymbol label,KnownNat n)+ => [o] -> ScalarArray label n o+fromList l =+ ScalarArray $+ if natVal (Proxy @n) /= toInteger (length l)+ then+ error $ printf "Invalid number of array elements for array %s. Got length: %d elments, expected %d."+ (show (symbolVal (Proxy :: Proxy label)))+ (length l)+ (natVal (Proxy :: Proxy n))+ else+ Vec.fromList l++-- * Constant fields++-- | Wrapper around a field, e.g. a 'Scalar' or 'ScalarArray', with a type level+-- value. The wrapped content must implement 'FromTypeLit'. To get the value of+-- a 'Constant' use 'fromTypeLit'.+data Constant o v where+ Constant :: Constant o v++instance (IsBoxContent o,FromTypeLit o v) => IsBoxContent (Constant o v) where+ boxSize = boxSize . fromTypeLit+ boxBuilder = boxBuilder . fromTypeLit++instance Default (Constant o v) where+ def = Constant++-- * Template Fields++-- | Fields with default values that can be overriden with custom value. Like+-- 'Constant' this is a wrapper around a field, e.g. a 'Scalar' or+-- 'ScalarArray', with a type level default value. The wrapped content must+-- implement 'FromTypeLit'.+data Template o v where -- TODO replace with newtype and replace the 'Template'+ -- case with the 'Default' instance.+ Template :: Template o v+ Custom :: !o -> Template o v++instance Default (Template o v) where+ def = Template++-- | Get a value from a 'Template'.+templateValue :: FromTypeLit o v => Template o v -> o+templateValue d@Template = fromTypeLit d+templateValue (Custom !v) = v++instance (IsBoxContent o,FromTypeLit o v) => IsBoxContent (Template o v) where+ boxSize = boxSize . templateValue+ boxBuilder = boxBuilder . templateValue++-- * Conversion from type-level numbers and lists to values++-- | Types that can be constructed from type level value representations.+class FromTypeLit o v where+ fromTypeLit :: proxy o v -> o++instance forall arr o len (label :: Symbol) .+ (KnownSymbol label,SingI arr,Num o,SingKind [Nat],KnownNat len,len ~ Length arr)+ => FromTypeLit (ScalarArray label len o) (arr :: [Nat]) where+ fromTypeLit _ =+ let s = sing :: Sing arr+ vs :: [Integer]+ !vs = fromSing s+ vs' :: [o]+ !vs' = fromIntegral <$> vs+ in (fromList vs' :: ScalarArray label len o)++instance KnownSymbol str => FromTypeLit T.Text (str :: Symbol) where+ fromTypeLit = T.pack . symbolVal++-- * String/Text field types++-- | A fixed size string, the first byte is the string length, after the String,+-- the field is padded with @0@ bytes. The string must be in UTF8 format.+newtype FixSizeText (len :: Nat) (label :: Symbol) where+ FixSizeText :: T.Text -> FixSizeText len label++-- | A constraint that matches type level numbers that are valid text sizes for+-- 'FixSizeText's.+type IsTextSize len = (KnownNat len, 1 <= len, len <= 255)++instance IsTextSize len => IsBoxContent (FixSizeText len label) where+ boxSize _ = fromIntegral (natVal (Proxy :: Proxy len))+ boxBuilder (FixSizeText !t) =+ let+ -- leave room for the size byte+ !maxSize = fromIntegral (natVal (Proxy :: Proxy len) - 1)+ !displayableText = B.take maxSize (T.encodeUtf8 t)+ !displayableTextSize = B.length displayableText+ !paddingSize = max 0 (maxSize - displayableTextSize)+ in word8 (fromIntegral displayableTextSize)+ <> byteString displayableText+ <> fold (replicate paddingSize (word8 0))++instance IsTextSize len => Default (FixSizeText len label) where+ def = FixSizeText ""++-- | Four character strings embedded in a uint32.+newtype U32Text (label :: Symbol) where+ U32Text :: Word32 -> U32Text label++instance IsString (U32Text label) where+ fromString !str = U32Text $+ let cw !s !c = (0xFF .&. fromIntegral (fromEnum c)) `shiftL` s+ in case str of+ [] -> 0x20202020+ [!a] -> cw 24 a .|. 0x00202020+ [!a,!b] -> cw 24 a .|. cw 16 b .|. 0x00002020+ [!a,!b,!c] -> cw 24 a .|. cw 16 b .|. cw 8 c .|. 0x20+ (!a : (!b) : (!c) : (!d) :_) -> cw 24 a .|. cw 16 b .|. cw 8 c .|. cw 0 d++instance IsBoxContent (U32Text label) where+ boxSize _ = 4+ boxBuilder (U32Text !t) = word32BE t++instance KnownSymbol str => FromTypeLit (U32Text label) (str :: Symbol) where+ fromTypeLit = fromString . symbolVal++instance Default (U32Text label) where+ def = U32Text 0x20202020
+ src/Data/ByteString/IsoBaseFileFormat/Util/FullBox.hs view
@@ -0,0 +1,93 @@+-- | Full Boxes+module Data.ByteString.IsoBaseFileFormat.Util.FullBox+ (FullBox(..), fullBox, BoxFlags(..))+ where++import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.ReExports++-- | A 'FullBox' contains an extra version and a flags field. In this+-- implementation it is wrapped around the rest of the box content. This+-- enforces that the 'FullBox' header fields are always at the beginning - at+-- least as long as this module hides the 'FullBox' constructor ;)+data FullBox t (version :: Nat) where+ FullBox :: (KnownNat version, IsBox t)+ => !(BoxFlags 24)+ -> !(BoxContent t)+ -> FullBox t version++instance (KnownNat version, IsBox t, Default (BoxContent t))+ => Default (FullBox t version) where+ def = FullBox 0 def++instance (KnownNat v, IsBox t) => IsBox (FullBox t v) where+ type BoxContent (FullBox t v) = FullBox t v++type instance BoxTypeSymbol (FullBox t v) = BoxTypeSymbol t++instance (IsBox t, KnownNat v) => IsBoxContent (FullBox t v) where+ boxSize (FullBox f c) = 1 + boxSize f + boxSize c+ boxBuilder (FullBox f c) =+ word8 (fromIntegral (natVal (Proxy :: Proxy v)))+ <> boxBuilder f+ <> boxBuilder c++-- | Create a 'FullBox' from a 'BoxVersion' and 'BoxFlags'+fullBox+ :: (KnownNat v, IsBox t)+ => BoxFlags 24 -> BoxContent t -> Box (FullBox t v)+fullBox f c = Box (FullBox f c)++-- | In addition to a version there can be 24 bits for custom flags etc in+-- a 'FullBox'.+newtype BoxFlags bits =+ BoxFlags Integer+ deriving (Eq,Show,Num)++-- | Internal function that creates a bit mask with all bits in a 'BoxFlags' set+-- to 1.+boxFlagBitMask :: KnownNat bits+ => BoxFlags bits -> Integer+boxFlagBitMask px = 2 ^ natVal px - 1++-- | Internal function that masks-out all bits higher than 'bits'.+cropBits :: KnownNat bits+ => BoxFlags bits -> BoxFlags bits+cropBits f@(BoxFlags b) = BoxFlags (b .&. boxFlagBitMask f)++-- | Get the number of bytes required to store a number of bits.+instance KnownNat bits => IsBoxContent (BoxFlags bits) where+ boxSize f =+ let minBytes = fromInteger $ natVal f `div` 8+ modBytes = fromInteger $ natVal f `mod` 8+ in BoxSize $ minBytes + signum modBytes+ boxBuilder f@(BoxFlags b) =+ let bytes =+ let (BoxSize bytes') = boxSize f+ in fromIntegral bytes'+ wordSeq n+ | n <= bytes =+ word8 (fromIntegral (shiftR b ((bytes - n) * 8) .&. 255)) <>+ wordSeq (n + 1)+ | otherwise = mempty+ in wordSeq 1++instance KnownNat bits => Bits (BoxFlags bits) where+ (.&.) (BoxFlags l) (BoxFlags r) = cropBits $ BoxFlags $ l .&. r+ (.|.) (BoxFlags l) (BoxFlags r) = cropBits $ BoxFlags $ l .&. r+ xor (BoxFlags l) (BoxFlags r) = cropBits $ BoxFlags $ xor l r+ complement (BoxFlags x) = cropBits $ BoxFlags $ complement x+ shift (BoxFlags x) = cropBits . BoxFlags . shift x+ rotateL = error "TODO rotateL"+ rotateR = error "TODO rotateR"+ bitSize = fromInteger . natVal+ bitSizeMaybe = Just . fromInteger . natVal+ isSigned _ = False+ testBit f n =+ let (BoxFlags b) = cropBits f+ in testBit b n+ bit = cropBits . BoxFlags . bit+ popCount f =+ let (BoxFlags b) = cropBits f+ in popCount b+ zeroBits = BoxFlags 0
+ src/Data/ByteString/IsoBaseFileFormat/Util/Time.hs view
@@ -0,0 +1,140 @@+-- | Time and timing utilities.+module Data.ByteString.IsoBaseFileFormat.Util.Time+ (referenceTime, utcToMp4, mp4CurrentTime, durationFromSeconds,+ oneSecond32, oneSecond64, diffTimeToTicks,ticksToDiffTime,+ TimeScale(..), Timing, TS(..), type TS32, type TS64, Ticks(..), Ticks32(..))+ where++import Data.Time.Clock+import Data.Time.Calendar+import Data.Ratio+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.BoxFields+import Data.ByteString.IsoBaseFileFormat.Util.Versioned+import Data.ByteString.IsoBaseFileFormat.ReExports+import Data.Typeable+import Foreign.Storable++-- * Absolute Dates+-- | According to the standard, fields with absolute dates and times are in+-- seconds since 1904/01/01 at midnight (UTC). This is this reference time.+referenceTime :: UTCTime+referenceTime =+ let startDay = fromGregorian 1904 1 1+ startTime = 0+ in UTCTime startDay startTime++-- | Convert a 'UTCTime' to a number of seconds since 'referenceTime'.+utcToMp4 :: Num t+ => UTCTime -> t+utcToMp4 u =+ let picoSecondsDiff = toRational $ diffUTCTime u referenceTime+ picoSecondsDiffNumerator = numerator picoSecondsDiff+ picoSecondsDiffDenominator = denominator picoSecondsDiff+ secondsSinceReferenceTime =+ div picoSecondsDiffNumerator picoSecondsDiffDenominator+ in fromIntegral secondsSinceReferenceTime+++-- | Convert a 'NominalDiffTime' to the number of 'Ticks' with respect+-- to a given 'TimeScale'.+diffTimeToTicks :: Integral t+ => NominalDiffTime -> TimeScale -> t+diffTimeToTicks !diff (TimeScale !scale) =+ round (diff * (fromIntegral scale))++-- | Convert a 'NominalDiffTime' to the number of 'Ticks' with respect+-- to a given 'TimeScale'.+ticksToDiffTime :: Integral t+ => t -> TimeScale -> NominalDiffTime+ticksToDiffTime !t (TimeScale !scale) =+ fromRational (toInteger t % toInteger scale)+++-- | Get the current time as number of seconds since 'referenceTime'+mp4CurrentTime :: Num t+ => IO t+mp4CurrentTime = utcToMp4 <$> getCurrentTime++-- * Time-Scale and Durations+-- | Default time-scale value+-- Based on history and tradition this value is @90000@.+-- MPEG-2 TS defines a single clock for each program, running at 27MHz. The+-- timescale of MPEG-2 TS Hint Tracks should be divisable by 90000.+newtype TimeScale = TimeScale {fromTimeScale :: Word32}+ deriving (Show,Eq,Num,Bounded,Ord,Bits,Integral,Typeable,Storable,Enum,Real)++instance Default TimeScale where+ def = TimeScale 90000++instance IsBoxContent TimeScale where+ boxSize = boxSize . fromTimeScale+ boxBuilder = boxBuilder . fromTimeScale++-- | Utility function to convert seconds (Integers) to any 'Num' using a+-- 'TimeScale', Since 'Scalar' has a 'Num' instance this can be used to generate+-- @duration@ fields.+durationFromSeconds :: Num t+ => TimeScale -> Integer -> t+durationFromSeconds timeScale seconds =+ let timeScaleI = fromIntegral timeScale+ in timeScaleI * fromInteger seconds++-- | Utility function to generate the equivalent of one second (@1 s@)+oneSecond32 = Scalar . flip durationFromSeconds 1+oneSecond32 :: TimeScale -> TS32 label++-- | Utility function to generate the equivalent of one second (@1 s@)+oneSecond64 :: TimeScale -> TS64 label+oneSecond64 = Scalar . flip durationFromSeconds 1++-- | A type that denotes a time relative to a 'TimeScale' which is included in+-- its type. 'Ticks' is the number of time units passed, where each time unit+-- has a physical duration of @timescale * 1/s@ i.e. @timescale@ 'Ticks' last+-- about @1 s@.+-- TODO use this instead of raw Word32s+newtype Ticks (timeScale :: Nat) = MkTicks {fromTicks :: Word64}+ deriving (Show,Eq,Num,Bounded,Ord,Bits,Integral,Typeable,Storable,Enum,Real)++instance IsBoxContent (Ticks n) where+ boxSize = boxSize . fromTicks+ boxBuilder = boxBuilder . fromTicks++newtype Ticks32 (timeScale :: Nat) = MkTicks32 {fromTicks32 :: Word32}+ deriving (Show,Eq,Num,Bounded,Ord,Bits,Integral,Typeable,Storable,Enum,Real)++instance IsBoxContent (Ticks32 n) where+ boxSize = boxSize . fromTicks32+ boxBuilder = boxBuilder . fromTicks32++-- | Time and timing information about a movie.+--+-- The creation/modification times are in seconds since midnight, Jan. 1, 1904,+-- in UTC time. Time scale declares the time coordinate system, it specifies the+-- number of time units that pass one second. The time coordinate system is used+-- by e.g. the duration field, which by the way contains the duration of the+-- longest track, if known, or simply the equivalent of 1s.+type Timing (version :: Nat) = Versioned TimingV0 TimingV1 version++type TS32 = Scalar Word32+type TS64 = Scalar Word64++data TS (version :: Nat) (label :: Symbol) where+ TSv0 :: !Word32 -> TS 0 label+ TSv1 :: !Word64 -> TS 1 label++instance IsBoxContent (TS v n) where+ boxSize (TSv0 _t) = 4+ boxSize (TSv1 _t) = 8+ boxBuilder (TSv0 !t) = word32BE t+ boxBuilder (TSv1 !t) = word64BE t++type TimingV0 = TimingImpl (Scalar Word32) (TS 0 "duration")++type TimingV1 = TimingImpl (Scalar Word64) (TS 1 "duration")++type TimingImpl uint dur =+ uint "creation_time"+ :+ uint "modification_time"+ :+ TimeScale+ :+ dur
+ src/Data/ByteString/IsoBaseFileFormat/Util/Versioned.hs view
@@ -0,0 +1,25 @@+{-# LANGUAGE UndecidableInstances #-}+-- | A binary version 0/1 field with seperate content for each version.+module Data.ByteString.IsoBaseFileFormat.Util.Versioned+ (Versioned(..))+ where++import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.ReExports++-- TODO rewrite/cleanup the versioned mess++-- | Two alternative representations based on a /version/ index.+-- Use this for box content that can be either 32 or 64 bit.+data Versioned v0 v1 (version :: Nat) where+ V0 :: IsBoxContent v0 => !v0 -> Versioned v0 v1 0+ V1 :: IsBoxContent v1 => !v1 -> Versioned v0 v1 1++instance (version ~ 0,IsBoxContent v0,Default v0) => Default (Versioned v0 v1 (version :: Nat)) where+ def = V0 def++instance IsBoxContent (Versioned v0 v1 version) where+ boxSize (V0 c) = boxSize c+ boxSize (V1 c) = boxSize c+ boxBuilder (V0 c) = boxBuilder c+ boxBuilder (V1 c) = boxBuilder c
+ src/Data/ByteString/Mp4/AudioStreaming.hs view
@@ -0,0 +1,292 @@+-- | A single-track AAC audio streaming utility wrapping 'AudioFile' for+-- streaming via e.g. DASH.+module Data.ByteString.Mp4.AudioStreaming+ ( Segment(..)+ , InitSegment(..)+ , StreamingContext, AacMp4StreamConfig(..)+ , AacMp4TrackFragment(..)+ , numberOfChannels+ , buildAacMp4TrackFragment+ , buildAacMp4StreamInit+ , getStreamConfig, getStreamBaseTime, getStreamSequence+ , addToBaseTime, getSegmentDuration+ , streamInitINTERNAL_TESTING, streamInitUtc, streamNextSample, streamFlush+ , module X)++where++import Data.Time.Clock+import qualified Data.ByteString as BS+import qualified Data.ByteString.Lazy as BL+import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Boxes+import Data.ByteString.IsoBaseFileFormat.Brands.Dash as X+import Data.ByteString.IsoBaseFileFormat.MediaFile as X+import Data.ByteString.IsoBaseFileFormat.ReExports as X+import Data.ByteString.IsoBaseFileFormat.Util.BoxFields as X+import Data.ByteString.IsoBaseFileFormat.Util.Time as X+import Data.ByteString.IsoBaseFileFormat.Util.Versioned+import Data.ByteString.Mp4.Boxes.AudioSpecificConfig as X+import Data.ByteString.Mp4.Boxes.Mp4AudioSampleEntry as X+import qualified Data.Text as T+import qualified Data.Text.Encoding as TE++-- | Contains a sample in the ISO14496 style interpretation, i.e.+-- a smallish buffer of e.g. 20ms audio data or a single video frame.+-- A sample has some kind of time or at least order associated to it.+-- TODO not right now, add it+--+-- Also a sample has a duration measured as the sampleCount. TODO make this a+-- real data type, and possible refactor this to be a seperate issue from+-- filling stream gaps and determining the offsets and the decoding time stamp.++-- | Contains the configuration and state for the creation of a DASH audio+-- stream.+data StreamingContext =+ StreamingContext { acConfig :: !AacMp4StreamConfig+ , acSegmentDuration :: !Word64 -- (in ticks)+ , acSequence :: !Word32+ , acBaseTime :: !Word64+ , acSegments :: ![(Word32, BS.ByteString)]+ }++-- | Initialisation segment parameters of an aac audio stream mp4 file.+data AacMp4StreamConfig =+ AacMp4StreamConfig { creationTime :: !(TS32 "creation_time")+ , trackName :: !String+ , useHeAac :: !Bool+ , sampleRate :: !SamplingFreqTable+ , channelConfig :: !ChannelConfigTable}++data Segment =+ Segment+ { segmentSequence :: !Word32+ , segmentTime :: !Word64+ , segmentData :: !BS.ByteString+ }++newtype InitSegment =+ InitSegment+ { fromInitSegment :: BS.ByteString }++-- | Media fragment segment parameters of an aac audio stream mp4 file.+data AacMp4TrackFragment =+ AacMp4TrackFragment { fragmentSampleSequence :: !Word32+ , fragmentBaseMediaDecodeTime :: !Word64+ , fragmentSamples :: ![(Word32, BS.ByteString)]+ }++numberOfChannels :: Num a => StreamingContext -> a+numberOfChannels = channelConfigToNumber . channelConfig . acConfig++addToBaseTime :: StreamingContext -> NominalDiffTime -> StreamingContext+addToBaseTime !sc !dt =+ sc { acSequence = newSequence+ , acBaseTime = diffTimeToTicks newBaseTime timeScale}+ where+ !timeScale = getAacMp4StreamConfigTimeScale (acConfig sc)+ !newSequence = round (newBaseTime / segmentDuration)+ where+ !segmentDuration = ticksToDiffTime (acSegmentDuration sc) timeScale+ !newBaseTime = dt + baseTime+ where+ !baseTime = ticksToDiffTime (acBaseTime sc) timeScale+++-- | Return the 'AacMp4StreamConfig' from an 'StreamingContext'+getStreamConfig :: StreamingContext -> AacMp4StreamConfig+getStreamConfig StreamingContext{..} = acConfig++-- | Return the current base decoding time+getStreamBaseTime :: StreamingContext -> Word64+getStreamBaseTime StreamingContext{..} = acBaseTime++-- | Return the current sequence number+getStreamSequence :: StreamingContext -> Word32+getStreamSequence StreamingContext{..} = acSequence++instance Show Segment where+ show (Segment !s !t !d) =+ printf "SEGMENT - seq: %14d - time: %14d - size: %14d" s t (BS.length d)+++getSegmentDuration :: StreamingContext -> NominalDiffTime+getSegmentDuration !sc = segmentDuration+ where+ !segmentDuration = ticksToDiffTime (acSegmentDuration sc) timeScale+ !timeScale = getAacMp4StreamConfigTimeScale (acConfig sc)++sampleCountDuration :: AacMp4StreamConfig -> Word32 -> Word64+sampleCountDuration (AacMp4StreamConfig _ _ _ _ _c) r =+ fromIntegral r -- `div` channelConfigToNumber c TODO clean this whole mess up and remove all Word32/Word64++getAacMp4StreamConfigTimeScale :: AacMp4StreamConfig -> TimeScale+getAacMp4StreamConfigTimeScale AacMp4StreamConfig{..} =+ TimeScale (sampleRateToNumber sampleRate)++-- | Initiate the 'StreamingContext' and create the /MP4 init segment/.+-- This lives in 'IO' because it read the current time from the real world.+streamInitINTERNAL_TESTING+ :: String+ -> NominalDiffTime+ -> Bool+ -> SamplingFreqTable+ -> ChannelConfigTable+ -> IO (InitSegment, StreamingContext)+streamInitINTERNAL_TESTING !trackTitle !segmentDuration !sbr !rate !channels = do+ t <- mp4CurrentTime+ let !cfg = AacMp4StreamConfig t trackTitle sbr rate channels+ !dur = diffTimeToTicks segmentDuration timeScale+ !timeScale = getAacMp4StreamConfigTimeScale cfg+ return (InitSegment+ (BL.toStrict (toLazyByteString (buildAacMp4StreamInit cfg)))+ , StreamingContext cfg dur 0 0 [])++instance Show InitSegment where+ show (InitSegment !d) =+ printf "INIT SEGMENT - size: %14d" (BS.length d)++-- | Initiate the 'StreamingContext' and create the /MP4 init segment/.+-- This lives in 'IO' because it read the current time from the real world.+streamInitUtc -- TODO remove 'streamInit' in favor of this ??+ :: String+ -> UTCTime+ -> UTCTime+ -> NominalDiffTime+ -> Bool+ -> SamplingFreqTable+ -> ChannelConfigTable+ -> (InitSegment, StreamingContext)+streamInitUtc !trackTitle !availabilityStartTime !refTime !segmentDuration !sbr !rate !channels =+ let !cfg = AacMp4StreamConfig t0 trackTitle sbr rate channels+ !t0 = utcToMp4 availabilityStartTime+ !secondsSinceRef = diffUTCTime availabilityStartTime refTime+ !dur = diffTimeToTicks segmentDuration timeScale+ !timeScale = getAacMp4StreamConfigTimeScale cfg+ in (InitSegment+ (BL.toStrict (toLazyByteString (buildAacMp4StreamInit cfg)))+ , addToBaseTime (StreamingContext cfg dur 0 0 []) secondsSinceRef)++-- | Enqueue a sample, if enough samples are accumulated, generate the next segment+streamNextSample+ :: Word32+ -> BS.ByteString+ -> StreamingContext+ -> (Maybe Segment, StreamingContext)+streamNextSample !sampleCount !sample !ctx@StreamingContext{..} =+ let !segments = (sampleCount, sample) : acSegments+ !currentEndTime = sampleCountDuration acConfig (sum (fst <$> segments)) + acBaseTime+ !nextBaseTime = (fromIntegral acSequence + 1) * acSegmentDuration64+ !acSegmentDuration64 = fromIntegral acSegmentDuration+ in+ if currentEndTime >= nextBaseTime then+ let !ctx' =+ ctx { acSequence = fromIntegral (currentEndTime `div` acSegmentDuration64)+ , acBaseTime = currentEndTime+ , acSegments = []+ }+ -- Output to write into fragment:+ !tf = buildAacMp4TrackFragment $+ AacMp4TrackFragment acSequence acBaseTime (reverse segments)++ in (Just (Segment acSequence acBaseTime (BL.toStrict (toLazyByteString tf))), ctx')+ else+ (Nothing, ctx{ acSegments = segments })++-- | Enqueue a sample, if enough samples are accumulated, generate the next segment+streamFlush+ :: StreamingContext+ -> (Maybe Segment, StreamingContext)+streamFlush !ctx@StreamingContext{..} =+ let currentEndTime =+ sampleCountDuration acConfig (sum (fst <$> acSegments)) + acBaseTime+ in+ if not (null acSegments) then+ let !tf = buildAacMp4TrackFragment $+ AacMp4TrackFragment acSequence acBaseTime (reverse acSegments)+ !ctx' = ctx { acSequence = fromIntegral+ (currentEndTime `div` fromIntegral acSegmentDuration)+ , acBaseTime = currentEndTime+ , acSegments = []}+ in (Just (Segment acSequence acBaseTime (BL.toStrict (toLazyByteString tf))), ctx')+ else (Nothing, ctx)++-- | Convert a 'AacMp4StreamConfig' record to a generic 'Boxes' collection.+buildAacMp4StreamInit+ :: AacMp4StreamConfig -> Builder+buildAacMp4StreamInit AacMp4StreamConfig{..} =+ let+ timeScaleForSampleRate = TimeScale (sampleRateToNumber sampleRate)+ in+ mediaBuilder dash $+ -- TODO must be iso5 for the way we use elementary stream descriptors+ fileTypeBox (FileType "iso5" 0 ["isom","iso5","dash","mp42"])+ :. skipBox (Skip (TE.encodeUtf8 (T.pack "Lindenbaum GmbH isobmff-builder, Sven Heyll 2016")))+ :| movie+ ( movieHeader+ (MovieHeader $+ V0 (creationTime+ :+ relabelScalar creationTime+ :+ def+ :+ TSv0 0)+ :+ def :+ def :+def :+ def :+ def :+ def :+ Custom (Scalar 2))+ :. track+ (trackHeader+ TrackInMovieAndPreview+ (TrackHeader $+ V0 (creationTime+ :+ relabelScalar creationTime+ :+ 1+ :+ Constant+ :+ 0) :++ def)+ :| media+ (mediaHeader (MediaHeader $+ V0 (creationTime+ :+ relabelScalar creationTime+ :+ timeScaleForSampleRate+ :+ TSv0 0)+ :+ def)+ :. handler (namedAudioTrackHandler (T.pack trackName))+ :| mediaInformation+ ( soundMediaHeader (SoundMediaHeader def)+ :. (dataInformation $: localMediaDataReference)+ :| sampleTable+ ((sampleDescription+ $: audioSampleEntry 1 (aacAudioSampleEntrySimple+ useHeAac+ sampleRate+ channelConfig+ (Scalar 16))+ :. timeToSample []+ :. sampleToChunk []+ :. fixedSampleSize 0 0+ :| chunkOffset32 [])))))+ :| (movieExtends $: trackExtendsUnknownDuration 1 1))++-- | Convert a 'AacMp4TrackFragment record to a generic 'Boxes' collection.+buildAacMp4TrackFragment+ :: AacMp4TrackFragment -> Builder+buildAacMp4TrackFragment AacMp4TrackFragment{..} =+ mediaBuilder dash+ ( styp+ :. movieFragment+ ( mfhd+ :| trackFragment+ ( tfhd+ :. tfdt+ :| trun))+ :| mdat)+ where+ !styp = segmentTypeBox (SegmentType "msdh" 0 ["msdh","dash"])+ !mfhd = movieFragmentHeader (MovieFragmentHeader (Scalar fragmentSampleSequence))+ !tfhd = trackFragmentHeader def+ !tfdt = trackFragBaseMediaDecodeTime (TSv1 fragmentBaseMediaDecodeTime)+ !trun = trackRunIso5 mdatOffset fragmentSamples+ where+ !mdatOffset = movieFragmentStaticSize+ + movieFragmentHeaderStaticSize+ + trackFragmentStaticSize+ + trackFragmentHeaderStaticSize+ + trackFragBaseMediaDecodeTimeStaticSize64+ !mdat = mediaData (MediaData (BS.concat (snd <$> fragmentSamples)))
+ src/Data/ByteString/Mp4/Boxes/AudioSpecificConfig.hs view
@@ -0,0 +1,310 @@+{-# LANGUAGE UndecidableInstances #-}+-- | @mp4a@ Audio sample entry according to ISO 14496-14+module Data.ByteString.Mp4.Boxes.AudioSpecificConfig where++import Data.ByteString.IsoBaseFileFormat.ReExports+import Data.ByteString.Mp4.Boxes.DecoderSpecificInfo++-- * Decoder Configuration for ISO 14496-3 (Audio)++-- | A audio config using 'AudioConfigAacMinimal' for AAC-LC.+type AudioConfigAacLc freq channels =+ AudioConfigAacMinimal 'AacLc DefaultGASpecificConfig freq channels++-- | A audio config using 'AudioConfigSbrExplicitHierachical' for HE-AAC (v1) in+-- dual rate mode.+type AudioConfigHeAac freq channels =+ AudioConfigSbrExplicitHierachical+ 'AacLc DefaultGASpecificConfig freq channels freq++-- | A minimalistic audio config without sync and error protection+data AudioConfigAacMinimal+ :: AudioObjectTypeId+ -> IsAn AudioSubConfig+ -> IsAn (EnumOf SamplingFreqTable)+ -> IsAn (EnumOf ChannelConfigTable)+ -> IsA (DecoderSpecificInfo 'AudioIso14496_3 'AudioStream)++type instance+ Eval (AudioConfigAacMinimal+ aoId+ subCfg+ freq+ channels) =+ ('MkDecoderSpecificInfo+ (AudioConfigCommon aoId freq channels (BitRecordOfAudioSubConfig subCfg)))++-- | A audio config with SBR signalled explicit and hierachical+data AudioConfigSbrExplicitHierachical+ :: AudioObjectTypeId+ -> IsAn AudioSubConfig+ -> IsAn (EnumOf SamplingFreqTable)+ -> IsAn (EnumOf ChannelConfigTable)+ -> IsAn (EnumOf SamplingFreqTable) -- extension SamplingFrequency+ -> IsA (DecoderSpecificInfo 'AudioIso14496_3 'AudioStream)++type instance+ Eval (AudioConfigSbrExplicitHierachical+ aoId+ subCfg+ freq+ channels+ extFreq+ ) =+ ('MkDecoderSpecificInfo+ (AudioConfigCommon 'Sbr freq channels+ ("SBR audio object type" <:> PutHex8 (FromEnum AudioObjectTypeId aoId)+ #+: BitRecordOfEnum extFreq+ :+: AudioObjectTypeRec aoId+ :+: BitRecordOfAudioSubConfig subCfg)))++-- | Common header for audio specific config+type AudioConfigCommon aoId samplingFrequencyIndex channels rest =+ ("audio-specific-config" <:> PutHex8 (FromEnum AudioObjectTypeId aoId))+ #+$ (AudioObjectTypeRec aoId+ :+: BitRecordOfEnum samplingFrequencyIndex+ :+: BitRecordOfEnum channels+ :+: rest)++-- ** Audio Object Type++data AudioObjectTypeId =+ AacMain -- ^ ISO 14496-4 subpart 4+ | AacLc -- ^ ISO 14496-4 subpart 4+ | AacSsr -- ^ ISO 14496-4 subpart 4+ | AacLtp -- ^ ISO 14496-4 subpart 4+ | Sbr -- ^ ISO 14496-4 subpart 4+ | AacScalable -- ^ ISO 14496-4 subpart 4+ | TwinVq -- ^ ISO 14496-4 subpart 4+ | Celp -- ^ ISO 14496-4 subpart 3+ | Hvxc -- ^ ISO 14496-4 subpart 2+ | AoReserved1+ | AoReserved2+ | Ttsi -- ^ ISO 14496-4 subpart 6+ | MainSunthetic -- ^ ISO 14496-4 subpart 5+ | WavetableSynthesis -- ^ ISO 14496-4 subpart 5+ | GeneralMidi -- ^ ISO 14496-4 subpart 5+ | AlgorithmicSynthesisAndAudioFx -- ^ ISO 14496-4 subpart 5+ | ErAacLc -- ^ ISO 14496-4 subpart 4+ | AoReserved3+ | ErAacLtp -- ^ ISO 14496-4 subpart 4+ | ErAacScalable -- ^ ISO 14496-4 subpart 4+ | ErTwinVq -- ^ ISO 14496-4 subpart 4+ | ErBsac -- ^ ISO 14496-4 subpart 4+ | ErAacLd -- ^ ISO 14496-4 subpart 4+ | ErCelp -- ^ ISO 14496-4 subpart 3+ | ErHvxc -- ^ ISO 14496-4 subpart 2+ | ErHiln -- ^ ISO 14496-4 subpart 7+ | ErParametric -- ^ ISO 14496-4 subpart 2 or 7+ | Ssc -- ^ ISO 14496-4 subpart 8+ | AoReserved4+ | AoReserved5+ | AoCustom+ | AoLayer1 -- ^ ISO 14496-4 subpart 9+ | AoLayer2 -- ^ ISO 14496-4 subpart 9+ | AoLayer3 -- ^ ISO 14496-4 subpart 9+ | AoDst -- ^ ISO 14496-4 subpart 10+ | AotInvalid++type instance FromEnum AudioObjectTypeId 'AotInvalid = 0+type instance FromEnum AudioObjectTypeId 'AacMain = 1+type instance FromEnum AudioObjectTypeId 'AacLc = 2+type instance FromEnum AudioObjectTypeId 'AacSsr = 3+type instance FromEnum AudioObjectTypeId 'AacLtp = 4+type instance FromEnum AudioObjectTypeId 'Sbr = 5+type instance FromEnum AudioObjectTypeId 'AacScalable = 6+type instance FromEnum AudioObjectTypeId 'TwinVq = 7+type instance FromEnum AudioObjectTypeId 'Celp = 8+type instance FromEnum AudioObjectTypeId 'Hvxc = 9+type instance FromEnum AudioObjectTypeId 'AoReserved1 = 10+type instance FromEnum AudioObjectTypeId 'AoReserved2 = 11+type instance FromEnum AudioObjectTypeId 'Ttsi = 12+type instance FromEnum AudioObjectTypeId 'MainSunthetic = 13+type instance FromEnum AudioObjectTypeId 'WavetableSynthesis = 14+type instance FromEnum AudioObjectTypeId 'GeneralMidi = 15+type instance FromEnum AudioObjectTypeId 'AlgorithmicSynthesisAndAudioFx = 16+type instance FromEnum AudioObjectTypeId 'ErAacLc = 17+type instance FromEnum AudioObjectTypeId 'AoReserved3 = 18+type instance FromEnum AudioObjectTypeId 'ErAacLtp = 19+type instance FromEnum AudioObjectTypeId 'ErAacScalable = 20+type instance FromEnum AudioObjectTypeId 'ErTwinVq = 21+type instance FromEnum AudioObjectTypeId 'ErBsac = 22+type instance FromEnum AudioObjectTypeId 'ErAacLd = 23+type instance FromEnum AudioObjectTypeId 'ErCelp = 24+type instance FromEnum AudioObjectTypeId 'ErHvxc = 25+type instance FromEnum AudioObjectTypeId 'ErHiln = 26+type instance FromEnum AudioObjectTypeId 'ErParametric = 27+type instance FromEnum AudioObjectTypeId 'Ssc = 28+type instance FromEnum AudioObjectTypeId 'AoReserved4 = 29+type instance FromEnum AudioObjectTypeId 'AoReserved5 = 30+type instance FromEnum AudioObjectTypeId 'AoCustom = 31+type instance FromEnum AudioObjectTypeId 'AoLayer1 = 32+type instance FromEnum AudioObjectTypeId 'AoLayer2 = 33+type instance FromEnum AudioObjectTypeId 'AoLayer3 = 34+type instance FromEnum AudioObjectTypeId 'AoDst = 35++type AudioObjectTypeRec n =+ (If ((FromEnum AudioObjectTypeId n) <=? 30)+ "AudioObjectType"+ "ExtAudioObjectType") <:> PutHex8 (FromEnum AudioObjectTypeId n)+ #+$ AudioObjectTypeField1 (FromEnum AudioObjectTypeId n)+ .+: AudioObjectTypeField2 (FromEnum AudioObjectTypeId n)++type family AudioObjectTypeField1 (n :: Nat)+ :: IsA (BitRecordField ('MkFieldBits :: BitField (B 5) Nat 5)) where+ AudioObjectTypeField1 n =+ If (n <=? 30) (Field 5 := n) (Field 5 := 31)++type family AudioObjectTypeField2 (n :: Nat) :: BitRecord where+ AudioObjectTypeField2 n =+ If (n <=? 30) 'EmptyBitRecord ('BitRecordMember (Field 6 := (n - 31)))++-- *** Sampling Frequency++type SamplingFreq = ExtEnum SamplingFreqTable 4 'SFCustom (Field 24)++data SamplingFreqTable =+ SF96000+ | SF88200+ | SF64000+ | SF48000+ | SF44100+ | SF32000+ | SF24000+ | SF22050+ | SF16000+ | SF12000+ | SF11025+ | SF8000+ | SF7350+ | SFReserved1+ | SFReserved2+ | SFCustom++type instance FromEnum SamplingFreqTable 'SF96000 = 0+type instance FromEnum SamplingFreqTable 'SF88200 = 1+type instance FromEnum SamplingFreqTable 'SF64000 = 2+type instance FromEnum SamplingFreqTable 'SF48000 = 3+type instance FromEnum SamplingFreqTable 'SF44100 = 4+type instance FromEnum SamplingFreqTable 'SF32000 = 5+type instance FromEnum SamplingFreqTable 'SF24000 = 6+type instance FromEnum SamplingFreqTable 'SF22050 = 7+type instance FromEnum SamplingFreqTable 'SF16000 = 8+type instance FromEnum SamplingFreqTable 'SF12000 = 9+type instance FromEnum SamplingFreqTable 'SF11025 = 0xa+type instance FromEnum SamplingFreqTable 'SF8000 = 0xb+type instance FromEnum SamplingFreqTable 'SF7350 = 0xc+type instance FromEnum SamplingFreqTable 'SFReserved1 = 0xd+type instance FromEnum SamplingFreqTable 'SFReserved2 = 0xe+type instance FromEnum SamplingFreqTable 'SFCustom = 0xf++sampleRateToNumber :: Num a => SamplingFreqTable -> a+sampleRateToNumber SF96000 = 96000+sampleRateToNumber SF88200 = 88200+sampleRateToNumber SF64000 = 64000+sampleRateToNumber SF48000 = 48000+sampleRateToNumber SF44100 = 44100+sampleRateToNumber SF32000 = 32000+sampleRateToNumber SF24000 = 24000+sampleRateToNumber SF22050 = 22050+sampleRateToNumber SF16000 = 16000+sampleRateToNumber SF12000 = 12000+sampleRateToNumber SF11025 = 11025+sampleRateToNumber SF8000 = 8000+sampleRateToNumber SF7350 = 7350+sampleRateToNumber _ = 0++sampleRateToEnum :: SamplingFreqTable -> EnumValue SamplingFreqTable+sampleRateToEnum SF96000 = MkEnumValue (Proxy @'SF96000)+sampleRateToEnum SF88200 = MkEnumValue (Proxy @'SF88200)+sampleRateToEnum SF64000 = MkEnumValue (Proxy @'SF64000)+sampleRateToEnum SF48000 = MkEnumValue (Proxy @'SF48000)+sampleRateToEnum SF44100 = MkEnumValue (Proxy @'SF44100)+sampleRateToEnum SF32000 = MkEnumValue (Proxy @'SF32000)+sampleRateToEnum SF24000 = MkEnumValue (Proxy @'SF24000)+sampleRateToEnum SF22050 = MkEnumValue (Proxy @'SF22050)+sampleRateToEnum SF16000 = MkEnumValue (Proxy @'SF16000)+sampleRateToEnum SF12000 = MkEnumValue (Proxy @'SF12000)+sampleRateToEnum SF11025 = MkEnumValue (Proxy @'SF11025)+sampleRateToEnum SF8000 = MkEnumValue (Proxy @'SF8000)+sampleRateToEnum SF7350 = MkEnumValue (Proxy @'SF7350)+sampleRateToEnum SFReserved1 = MkEnumValue (Proxy @'SFReserved1)+sampleRateToEnum SFReserved2 = MkEnumValue (Proxy @'SFReserved2)+sampleRateToEnum SFCustom = MkEnumValue (Proxy @'SFCustom)++-- *** Channel Config (Mono, Stereo, 7-1 Surround, ...)++type ChannelConfig = FixedEnum ChannelConfigTable 4++data ChannelConfigTable =+ GasChannelConfig+ | SingleChannel+ | ChannelPair+ | SinglePair+ | SinglePairSingle+ | SinglePairPair+ | SinglePairPairLfe+ | SinglePairPairPairLfe++type instance FromEnum ChannelConfigTable 'GasChannelConfig = 0+type instance FromEnum ChannelConfigTable 'SingleChannel = 1+type instance FromEnum ChannelConfigTable 'ChannelPair = 2+type instance FromEnum ChannelConfigTable 'SinglePair = 3+type instance FromEnum ChannelConfigTable 'SinglePairSingle = 4+type instance FromEnum ChannelConfigTable 'SinglePairPair = 5+type instance FromEnum ChannelConfigTable 'SinglePairPairLfe = 6+type instance FromEnum ChannelConfigTable 'SinglePairPairPairLfe = 7++channelConfigToNumber :: Num a => ChannelConfigTable -> a+channelConfigToNumber GasChannelConfig = 0+channelConfigToNumber SingleChannel = 1+channelConfigToNumber ChannelPair = 2+channelConfigToNumber SinglePair = 3+channelConfigToNumber SinglePairSingle = 4+channelConfigToNumber SinglePairPair = 5+channelConfigToNumber SinglePairPairLfe = 6+channelConfigToNumber SinglePairPairPairLfe = 7++channelConfigToEnum :: ChannelConfigTable -> EnumValue ChannelConfigTable+channelConfigToEnum GasChannelConfig = MkEnumValue (Proxy @'GasChannelConfig)+channelConfigToEnum SingleChannel = MkEnumValue (Proxy @'SingleChannel)+channelConfigToEnum ChannelPair = MkEnumValue (Proxy @'ChannelPair)+channelConfigToEnum SinglePair = MkEnumValue (Proxy @'SinglePair)+channelConfigToEnum SinglePairSingle = MkEnumValue (Proxy @'SinglePairSingle)+channelConfigToEnum SinglePairPair = MkEnumValue (Proxy @'SinglePairPair)+channelConfigToEnum SinglePairPairLfe = MkEnumValue (Proxy @'SinglePairPairLfe)+channelConfigToEnum SinglePairPairPairLfe = MkEnumValue (Proxy @'SinglePairPairPairLfe)++-- ** More Specific audio decoder config++data AudioSubConfig :: Type++type family BitRecordOfAudioSubConfig (x :: IsA AudioSubConfig) :: BitRecord++data GASpecificConfig+ (frameLenFlag :: IsA (FieldValue "frameLenFlag" Bool))+ (coreCoderDelay :: Maybe (IsA (FieldValue "coreCoderDelay" Nat)))+ (extension :: IsA GASExtension)+ :: IsA AudioSubConfig++type DefaultGASpecificConfig =+ GASpecificConfig (StaticFieldValue "frameLenFlag" 'False) 'Nothing MkGASExtension++type instance Eval (GASpecificConfig fl cd ext)+ = TypeError ('Text "AudioSubConfig is abstract!")+++type instance+ BitRecordOfAudioSubConfig (GASpecificConfig fl cd ext) =+ ( Flag :~ fl+ .+: FlagJust cd+ .+: Field 14 :+? cd+ :+: BitRecordOfGASExtension ext+ )++-- | TODO implment that GAS extensions+data GASExtension+data MkGASExtension :: IsA GASExtension++type BitRecordOfGASExtension (x :: IsA GASExtension) =+ 'BitRecordMember ("has-gas-extension" @: Flag := 'False)
+ src/Data/ByteString/Mp4/Boxes/BaseDescriptor.hs view
@@ -0,0 +1,72 @@+{-# LANGUAGE UndecidableInstances #-}+module Data.ByteString.Mp4.Boxes.BaseDescriptor where++import Data.ByteString.IsoBaseFileFormat.ReExports+import Data.ByteString.Mp4.Boxes.Expandable++-- * Static base constructor++-- | Abstract class of /descriptors/ as recognized by ISO/IEC 14496-1 (Systems).+-- A specifc descriptor is identified by the 'ClassTag'.+data Descriptor :: ClassTag n -> Type where+ MkDescriptor :: BitRecord -> Descriptor tag++-- TODO ok... this fixed the current problem in DecoderSpecificInfo .. but remove this instances ... or the above ... or ... I dunno++data BitRecordOfDescriptor :: IsA (Descriptor c :-> BitRecord)++type instance+ BitRecordOfDescriptor $~ ('MkDescriptor body :: Descriptor (tag :: ClassTag tagInd)) =+ ("base-descriptor" <:> PutHex8 tagInd)+ #+$ FieldU8 := tagInd+ .+: Eval (StaticExpandableContent body)++type family GetClassTag (c :: ClassTag n) :: Nat where+ GetClassTag (c :: ClassTag n) = n++-- | Base Descriptor Class Tags TODO rename to xxxTag+data ClassTag (tag :: Nat) where+ ObjectDescr :: ClassTag 0x01+ InitialObjectDescr :: ClassTag 0x02+ ES_Descr :: ClassTag 0x03+ DecoderConfigDescr :: ClassTag 0x04+ DecSpecificInfo :: ClassTag 0x05+ SLConfigDescr :: ClassTag 0x06+ ContentIdentDescr :: ClassTag 0x07+ SupplContentIdentDescr :: ClassTag 0x08+ IPI_DescrPointer :: ClassTag 0x09+ IPMP_DescrPointer :: ClassTag 0x0A+ IPMP_Descr :: ClassTag 0x0B+ QoS_Descr :: ClassTag 0x0C+ RegistrationDescr :: ClassTag 0x0D+ ES_ID_Ref :: ClassTag 0x0F+ MP4_IOD_ :: ClassTag 0x10+ MP4_OD_ :: ClassTag 0x11+ IPL_DescrPointerRef :: ClassTag 0x12+ ExtensionProfileLevelDescr :: ClassTag 0x13+ ProfileLevelIndicationIndexDescr :: ClassTag 0x14+ ContentClassificationDescr :: ClassTag 0x40+ KeyWordDescr :: ClassTag 0x41+ RatingDescr :: ClassTag 0x42+ LanguageDescr :: ClassTag 0x43+ ShortTextualDescr :: ClassTag 0x44+ ExpandedTextualDescr :: ClassTag 0x45+ ContentCreatorNameDescr :: ClassTag 0x46+ ContentCreationDateDescr :: ClassTag 0x47+ OCICreatorNameDescr :: ClassTag 0x48+ OCICreationDateDescr :: ClassTag 0x49+ SmpteCameraPositionDescr :: ClassTag 0x4A+ SegmentDescr :: ClassTag 0x4B+ MediaTimeDescr :: ClassTag 0x4C+ IPMP_ToolsListDescr :: ClassTag 0x60+ IPMP_Tool :: ClassTag 0x61+ M4MuxTimingDescr :: ClassTag 0x62+ M4MuxCodeTableDescr :: ClassTag 0x63+ ExtSLConfigDescr :: ClassTag 0x64+ M4MuxBufferSizeDescr :: ClassTag 0x65+ M4MuxIdentDescr :: ClassTag 0x66+ DependencyPointer :: ClassTag 0x67+ DependencyMarker :: ClassTag 0x68+ M4MuxChannelDescr :: ClassTag 0x69+ ExtDescrTag :: forall (n :: Nat) . (0x6A <= n, n <= 0xFE) => ClassTag n+ OCIDescrTag :: forall (n :: Nat) . (0x40 <= n, n <= 0x5F) => ClassTag n
+ src/Data/ByteString/Mp4/Boxes/DecoderConfigDescriptor.hs view
@@ -0,0 +1,55 @@+{-# LANGUAGE UndecidableInstances #-}+module Data.ByteString.Mp4.Boxes.DecoderConfigDescriptor where++import Data.ByteString.Mp4.Boxes.BaseDescriptor+import Data.ByteString.Mp4.Boxes.DecoderSpecificInfo+import Data.Type.BitRecords+import Data.Type.Pretty+import Data.Kind.Extra+import GHC.TypeLits++-- | Information about what decoder is required for the an elementary stream.+-- The stream type indicates the general category of the stream and.+data DecoderConfigDescriptor+ (ot :: ObjectTypeIndication)+ (st :: StreamType)+ :: [IsA (DecoderSpecificInfo ot st)]+ -> [IsA (Descriptor 'ProfileLevelIndicationIndexDescr)]+ -> IsA (Descriptor 'DecoderConfigDescr)++type instance Eval (DecoderConfigDescriptor ot st di ps) =+ 'MkDescriptor (DecoderConfigDescriptorBody ot st di ps)++type family+ DecoderConfigDescriptorBody+ ot st+ (di :: [IsA (DecoderSpecificInfo ot st)])+ (ps :: [IsA (Descriptor 'ProfileLevelIndicationIndexDescr)])+ :: BitRecord+ where+ DecoderConfigDescriptorBody ot st di ps =+ PutStr "decoder-config-descriptor"+ #+$ (BitRecordOfEnum (SetEnum "objectTypeIndication" ObjectTypeIndicationEnum ot)+ :+: BitRecordOfEnum (SetEnum "objectTypeIndication" StreamTypeEnum st)+ :+: "upstream" @: Flag+ .+: "reserved" @: Field 1 := 1+ .+: "bufferSizeDB" @: Field 24+ .+: "maxBitrate" @: FieldU32+ .+: "avgBitrate" @: FieldU32+ .+: Eval (BitRecordOfList+ (DescriptorOfDecoderSpecificInfo+ :^>>>: BitRecordOfDescriptor)+ (di ?:: LengthIn 0 1))+ :+: Eval (BitRecordOfList+ (Extract :>>>: BitRecordOfDescriptor)+ (ps ?:: LengthIn 0 255)))++-- ** 'ProfileLevelIndicationIndexDescriptor'++data ProfileLevelIndicationIndexDescriptor+ :: IsA (FieldValue "profileLevelIndicationIndex" Nat)+ -> IsA (Descriptor 'ProfileLevelIndicationIndexDescr)++type instance Eval (ProfileLevelIndicationIndexDescriptor val) =+ 'MkDescriptor+ ('BitRecordMember (FieldU8 :~ val))
+ src/Data/ByteString/Mp4/Boxes/DecoderSpecificInfo.hs view
@@ -0,0 +1,112 @@+{-# LANGUAGE UndecidableInstances #-}+module Data.ByteString.Mp4.Boxes.DecoderSpecificInfo where++import Data.ByteString.Mp4.Boxes.BaseDescriptor+import Data.Type.BitRecords+import Data.Type.Pretty+import Data.Kind.Extra+import Data.Kind (type Type)++-- * Abstract class for opaque object- and stream type dependent decoder+-- settings.++-- | Base type of decoders+data DecoderSpecificInfo :: ObjectTypeIndication -> StreamType -> Type where+ MkDecoderSpecificInfo :: BitRecord -> DecoderSpecificInfo o s++data DescriptorOfDecoderSpecificInfo+ :: IsA (DecoderSpecificInfo ot st :-> Descriptor 'DecSpecificInfo)++type instance DescriptorOfDecoderSpecificInfo $~ 'MkDecoderSpecificInfo body =+ 'MkDescriptor (PutStr "decoder-specific-info" #+$ body)++type ObjectTypeIndicationEnum = FixedEnum ObjectTypeIndication 8++data ObjectTypeIndication =+ SystemsIso14496_1_a+ | SystemsIso14496_1_b+ | InteractionStreamObjInd+ | SystemsIso14496_1_ExtendedBifs+ | SystemsIso14496_1_Afx+ | FontDataStream+ | SynthesizedTextureStream+ | StreamingTextStream+ | VisualIso14496_2+ | VisualH264+ | VisualH264ParameterSets+ | AudioIso14496_3+ | VisualIso13818_2_SimpleProfile+ | VisualIso13818_2_MainProfile+ | VisualIso13818_2_SnrProfile+ | VisualIso13818_2_SpatialProfile+ | VisualIso13818_2_HighProfile+ | VisualIso13818_2_422Profile+ | AudioIso13818_7_MainProfile+ | AudioIso13818_7_LowComplexityProfile+ | AudioIso13818_7_ScalableSamplingRateProfile+ | AudioIso13818_3+ | VisualIso11172_2+ | AudioIso11172_3+ | VisualIso10918_1+ | VisualIso15444_1+ | NoObjectTypeSpecified++type instance FromEnum ObjectTypeIndication 'SystemsIso14496_1_a = 0x01+type instance FromEnum ObjectTypeIndication 'SystemsIso14496_1_b = 0x02+type instance FromEnum ObjectTypeIndication 'InteractionStreamObjInd = 0x03+type instance FromEnum ObjectTypeIndication 'SystemsIso14496_1_ExtendedBifs = 0x04+type instance FromEnum ObjectTypeIndication 'SystemsIso14496_1_Afx = 0x05+type instance FromEnum ObjectTypeIndication 'FontDataStream = 0x06+type instance FromEnum ObjectTypeIndication 'SynthesizedTextureStream = 0x07+type instance FromEnum ObjectTypeIndication 'StreamingTextStream = 0x08+type instance FromEnum ObjectTypeIndication 'VisualIso14496_2 = 0x20+type instance FromEnum ObjectTypeIndication 'VisualH264 = 0x21+type instance FromEnum ObjectTypeIndication 'VisualH264ParameterSets = 0x22+type instance FromEnum ObjectTypeIndication 'AudioIso14496_3 = 0x40+type instance FromEnum ObjectTypeIndication 'VisualIso13818_2_SimpleProfile = 0x60+type instance FromEnum ObjectTypeIndication 'VisualIso13818_2_MainProfile = 0x61+type instance FromEnum ObjectTypeIndication 'VisualIso13818_2_SnrProfile = 0x62+type instance FromEnum ObjectTypeIndication 'VisualIso13818_2_SpatialProfile = 0x63+type instance FromEnum ObjectTypeIndication 'VisualIso13818_2_HighProfile = 0x64+type instance FromEnum ObjectTypeIndication 'VisualIso13818_2_422Profile = 0x65+type instance FromEnum ObjectTypeIndication 'AudioIso13818_7_MainProfile = 0x66+type instance FromEnum ObjectTypeIndication 'AudioIso13818_7_LowComplexityProfile = 0x67+type instance FromEnum ObjectTypeIndication 'AudioIso13818_7_ScalableSamplingRateProfile = 0x68+type instance FromEnum ObjectTypeIndication 'AudioIso13818_3 = 0x69+type instance FromEnum ObjectTypeIndication 'VisualIso11172_2 = 0x6A+type instance FromEnum ObjectTypeIndication 'AudioIso11172_3 = 0x6B+type instance FromEnum ObjectTypeIndication 'VisualIso10918_1 = 0x6C+type instance FromEnum ObjectTypeIndication 'VisualIso15444_1 = 0x6E+type instance FromEnum ObjectTypeIndication 'NoObjectTypeSpecified = 0xFF++-- * Stream Type++type family+ GetStreamType (t :: k) :: StreamType++type StreamTypeEnum = FixedEnum StreamType 6++data StreamType =+ ObjectDescriptorStream+ | ClockReferenceStream+ | SceneDescriptionStream_Iso14496_11+ | VisualStream+ | AudioStream+ | Mpeg7Stream+ | IpmpStream+ | ObjectContentInfoStream+ | MpegJStream+ | InteractionStream+ | IpmpToolStream_Iso14496_13++type instance FromEnum StreamType 'ObjectDescriptorStream = 1+type instance FromEnum StreamType 'ClockReferenceStream = 2+type instance FromEnum StreamType 'SceneDescriptionStream_Iso14496_11 = 3+type instance FromEnum StreamType 'VisualStream = 4+type instance FromEnum StreamType 'AudioStream = 5+type instance FromEnum StreamType 'Mpeg7Stream = 6+type instance FromEnum StreamType 'IpmpStream = 7+type instance FromEnum StreamType 'ObjectContentInfoStream = 8+type instance FromEnum StreamType 'MpegJStream = 9+type instance FromEnum StreamType 'InteractionStream = 0xa+type instance FromEnum StreamType 'IpmpToolStream_Iso14496_13 = 0xb
+ src/Data/ByteString/Mp4/Boxes/ElementaryStreamDescriptor.hs view
@@ -0,0 +1,80 @@+{-# LANGUAGE UndecidableInstances #-}+{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}+module Data.ByteString.Mp4.Boxes.ElementaryStreamDescriptor where++import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Util.FullBox+import Data.ByteString.IsoBaseFileFormat.ReExports+import Data.ByteString.Mp4.Boxes.BaseDescriptor+import Data.ByteString.Mp4.Boxes.SyncLayerConfigDescriptor++-- * Esd Box++type EsdBox = Box (FullBox Esd 0)+newtype Esd = Esd BuilderBox deriving (IsBoxContent)+instance IsBox Esd++type instance BoxTypeSymbol Esd = "esds"++esdBox :: forall (record :: IsA (Descriptor 'ES_Descr)) (rendered :: BitRecord) .+ ( BitStringBuilderHoley (Proxy rendered) EsdBox+ , rendered ~ (RenderEsDescr record))+ => Proxy record -> ToBitStringBuilder (Proxy rendered) EsdBox+esdBox =+ runHoley+ . esdBoxHoley++esdBoxHoley :: forall (record :: IsA (Descriptor 'ES_Descr)) r (rendered :: BitRecord) .+ ( BitStringBuilderHoley (Proxy rendered) r+ , rendered ~ (RenderEsDescr record)+ )+ => Proxy record -> Holey EsdBox r (ToBitStringBuilder (Proxy rendered) r)+esdBoxHoley _p =+ hoistM (fullBox 0 . Esd) $+ bitBuilderBoxHoley (Proxy @rendered)++type RenderEsDescr (d :: IsA (Descriptor 'ES_Descr)) =+ BitRecordOfDescriptor $~ (Eval d)++-- * Esd Record++data ESDescriptor+ :: IsA (FieldValue "esId" Nat)+ -> Maybe (IsA (FieldValue "depEsId" Nat))+ -- TODO Improve the custom field and also the sizedstring API+ -> Maybe (IsA (BitRecordField ('MkFieldCustom :: BitField ASizedString ASizedString (urlSize :: Nat))))+ -> Maybe (IsA (FieldValue "ocrEsId" Nat))+ -> IsA (FieldValue "streamPrio" Nat)+ -> IsA (Descriptor 'DecoderConfigDescr)+ -> IsA (Descriptor 'SLConfigDescr)+ -> IsA (Descriptor 'ES_Descr)++-- | ISO-14496-14 section 3.1.2 defines restrictions of the elementary stream+-- descriptor.+-- TODO seperate this and other modules so theres the same seperation as in between+-- the parts of the standard.+type ESDescriptorMp4File esId decConfigDescr =+ ESDescriptor esId 'Nothing 'Nothing+ 'Nothing DefaultStreamPrio+ decConfigDescr Mp4SyncLayerDescriptor++type DefaultEsId = StaticFieldValue "esId" 1+type DefaultStreamPrio = StaticFieldValue "streamPrio" 0++type instance+ Eval (ESDescriptor esId depEsId url ocrEsId streamPrio decConfig slConfig) =+ 'MkDescriptor+ (PutStr "elementary-stream-descriptor"+ #+$ "esId" @: FieldU16 :~ esId+ .+: "depEsIdFlag" @: FlagJust depEsId+ .+: "urlFlag" @: FlagJust url+ .+: "ocrEsIdFlag" @: FlagJust ocrEsId+ .+: "streamPriority" @: Field 5 :~ streamPrio+ .+: ("depEsId" @: FieldU16 :+? depEsId)+ :+: (PutStr "url" #+: (Eval (OptionalRecordOf (Fun1 RecordField) url)))+ :+: ("ocrEsId" @: FieldU16 :+? ocrEsId)+ :+: (BitRecordOfDescriptor $~ Eval decConfig)+ :+: (BitRecordOfDescriptor $~ Eval slConfig)++ -- TODO add the rest of the ESDescriptor+ )
+ src/Data/ByteString/Mp4/Boxes/Expandable.hs view
@@ -0,0 +1,73 @@+{-# LANGUAGE UndecidableInstances #-}+{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}++module Data.ByteString.Mp4.Boxes.Expandable where++import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.ReExports++-- * Static Expandable++data StaticExpandableContent :: BitRecord -> IsA BitRecord++type StaticExpandableContentMaxBits = 32++type instance Eval (StaticExpandableContent record) =+ (("expandable-content-size" <:>+ PutHex32 (ShiftR StaticExpandableContentMaxBits (BitRecordSize record) 3)+ #+$ ExpandableSize (ShiftR StaticExpandableContentMaxBits (BitRecordSize record) 3))+ :+: record)++type family ExpandableSize (s :: Nat) :: BitRecord where+ ExpandableSize 0 = 'EmptyBitRecord+ ExpandableSize s =+ If (s <=? 127)+ (ExpandableSizeLastChunk s)+ (ExpandableSizeNext (ShiftR StaticExpandableContentMaxBits s 7)+ :+: ExpandableSizeLastChunk s)++type ExpandableSizeLastChunk (s :: Nat) = Field 1 := 0 .+. Field 7 := s++type family ExpandableSizeNext (s :: Nat) :: BitRecord where+ ExpandableSizeNext 0 = 'EmptyBitRecord+ ExpandableSizeNext s =+ If (s <=? 127)+ (ExpandableSizeNextChunk s)+ (ExpandableSizeNext (ShiftR StaticExpandableContentMaxBits s 7)+ :+: ExpandableSizeNextChunk s)++type ExpandableSizeNextChunk (s :: Nat) = Field 1 := 1 .+. Field 7 := s+++-- * Runtime-value Expandable+-- TODO remove "runtime" Expandable?+newtype Expandable t where+ Expandable :: t -> Expandable t++instance IsBoxContent t => IsBoxContent (Expandable t) where+ boxSize (Expandable x) = expandableSizeSize (boxSize x) + boxSize x+ boxBuilder (Expandable x) = expandableSizeBuilder (boxSize x) <> boxBuilder x++expandableSizeSize :: BoxSize -> BoxSize+expandableSizeSize UnlimitedSize = error "Unlimited size not supported by expandable"+expandableSizeSize (BoxSize s)+ | s >= 2^(28 :: Int) = error "Expandable size >= 2^(28 :: Int)"+ | s >= 2^(21 :: Int) = 4+ | s >= 2^(14 :: Int) = 3+ | s >= 2^(7 :: Int) = 2+ | otherwise = 1++expandableSizeBuilder :: BoxSize -> Builder+expandableSizeBuilder UnlimitedSize = error "Unlimited size not supported by expandable"+expandableSizeBuilder (BoxSize s)+ | s >= 2 ^( 28 :: Int) = error "Expandable size >= 2^(28 :: Int)"+ | s >= 2 ^( 21 :: Int) = word8 (fromIntegral (0x80 .|. (s `unsafeShiftR` 21))) <>+ word8 (fromIntegral (0x80 .|. ((s `unsafeShiftR` 14) .&. 0x7F))) <>+ word8 (fromIntegral (0x80 .|. ((s `unsafeShiftR` 7) .&. 0x7F))) <>+ word8 (fromIntegral (s .&. 0x7F))+ | s >= 2 ^( 14 :: Int) = word8 (fromIntegral (0x80 .|. (s `unsafeShiftR` 14))) <>+ word8 (fromIntegral (0x80 .|. ((s `unsafeShiftR` 7) .&. 0x7F))) <>+ word8 (fromIntegral (s .&. 0x7F))+ | s >= 2 ^( 7 :: Int) = word8 (fromIntegral (0x80 .|. (s `unsafeShiftR` 7))) <>+ word8 (fromIntegral (s .&. 0x7F))+ | otherwise = word8 (fromIntegral s)
+ src/Data/ByteString/Mp4/Boxes/Mp4AudioSampleEntry.hs view
@@ -0,0 +1,90 @@+{-# LANGUAGE UndecidableInstances #-}+-- | @mp4a@ Audio sample entry according to ISO 14496-14+module Data.ByteString.Mp4.Boxes.Mp4AudioSampleEntry where++import Data.ByteString.IsoBaseFileFormat.Box+import Data.ByteString.IsoBaseFileFormat.Boxes+import Data.ByteString.IsoBaseFileFormat.ReExports+import Data.ByteString.IsoBaseFileFormat.Util.BoxFields+import Data.ByteString.Mp4.Boxes.ElementaryStreamDescriptor+import Data.ByteString.Mp4.Boxes.DecoderSpecificInfo+import Data.ByteString.Mp4.Boxes.DecoderConfigDescriptor+import Data.ByteString.Mp4.Boxes.AudioSpecificConfig++-- | A /body/ for 'AudioSampleEntry'. This 'IsBoxContent' with an+-- 'ElementaryStreamDescriptor' for ISO-14496-3 audio, with audio decoder+-- specific info.++-- | Create an 'AudioSampleEntry' with an 'AudioEsd'+audioSampleEntry+ :: U16 "data_reference_index"+ -> AudioSampleEntry AudioEsd+ -> Box (SampleEntry (AudioSampleEntry AudioEsd))+audioSampleEntry drefIndex ase =+ sampleEntry drefIndex ase++type instance BoxTypeSymbol AudioEsd = "mp4a"++-- | Create an mp4 audio elementary stream descriptor full box+aacAudioSampleEntrySimple+ :: Bool+ -> SamplingFreqTable+ -> ChannelConfigTable+ -> U16 "samplesize"+ -> AudioSampleEntry AudioEsd+aacAudioSampleEntrySimple sbr sf cc sampleSize =+ AudioSampleEntry+ (Constant+ :+ Custom (Scalar (channelConfigToNumber cc))+ :+ Custom sampleSize+ :+ 0+ :+ Constant+ :+ Custom (Scalar (sampleRateToNumber sf * 65536))+ :+ mkAudioEsdAacLcOrHeAac sbr sf cc)++mkAudioEsdAacLcOrHeAac+ :: Bool+ -> SamplingFreqTable+ -> ChannelConfigTable+ -> AudioEsd+mkAudioEsdAacLcOrHeAac False sf cc =+ AudioEsd+ (esdBox+ (Proxy @Mp4AacLcEsDescriptor)+ False 0 0 0+ (sampleRateToEnum sf)+ (channelConfigToEnum cc))+mkAudioEsdAacLcOrHeAac True sf cc =+ AudioEsd+ (esdBox+ (Proxy @Mp4HeAacEsDescriptor)+ False 0 0 0+ (sampleRateToEnum sf)+ (channelConfigToEnum cc)+ (sampleRateToEnum sf))++-- | Consists of an 'ElementaryStreamDescriptor' derived from a 'DecoderSpecificInfo'.+newtype AudioEsd =+ AudioEsd EsdBox+ deriving (IsBoxContent)++type Mp4AacLcEsDescriptor =+ ESDescriptorMp4File DefaultEsId+ (Mp4AacAudioDecoderConfigDescriptor+ (AudioConfigAacLc+ (EnumParam "samplingFreq" SamplingFreq)+ (EnumParam "channelConfig" ChannelConfig)))++type Mp4HeAacEsDescriptor =+ ESDescriptorMp4File DefaultEsId+ (Mp4AacAudioDecoderConfigDescriptor+ (AudioConfigHeAac+ (EnumParam "samplingFreq" SamplingFreq)+ (EnumParam "channelConfig" ChannelConfig)))++type Mp4AacAudioDecoderConfigDescriptor cfg =+ DecoderConfigDescriptor+ 'AudioIso14496_3+ 'AudioStream+ '[cfg]+ '[]
+ src/Data/ByteString/Mp4/Boxes/SyncLayerConfigDescriptor.hs view
@@ -0,0 +1,18 @@+{-# LANGUAGE UndecidableInstances #-}+module Data.ByteString.Mp4.Boxes.SyncLayerConfigDescriptor where++import Data.ByteString.IsoBaseFileFormat.ReExports+import Data.ByteString.Mp4.Boxes.BaseDescriptor++data Mp4SyncLayerDescriptor :: IsA (Descriptor 'SLConfigDescr)++-- | In the holy scripture, ISO-14496-14 section 3.1.2, it is written that there+-- shall be restrictions on the elementary stream descriptor, in there it says:+-- Thou shall use only __two__ as the value for the __predefined__ field in the+-- blessed __SLDescriptor__. Not one, this is a value not big enough, nor three,+-- this value is too much. The righteous one ever only uses __two__. Only a fool+-- will use __256__.+type instance Eval Mp4SyncLayerDescriptor =+ 'MkDescriptor+ (PutStr "mp4-sync-layer-descriptor"+ #+$ ('BitRecordMember ("predefined" @: FieldU8 := 0x02)))
+ src/Data/Kind/Extra.hs view
@@ -0,0 +1,156 @@+{-# LANGUAGE UndecidableInstances #-}+-- | Kind-level utilities to guide and simplify programming at the type level+module Data.Kind.Extra+ ( type A(..)+ , type IsA+ , type IsAn+ , type Return+ , type Pure+ , type Eval+ , type (:->)+ , type Id+ , type Apply+ , type (^*^)+ , type ($~)+ , type (:>>=:)+ , type (:>>>:)+ , type (:^>>>:)+ , type (:>>>^:)+ , type (:^>>>^:)+ , type Extract+ , type Optional+ , type FoldMap+ , type Fun1+ , type Fun2+ , type Fun3+ , type Fun4+ ) where++import Data.Kind (type Type)++-- * Symbolic Types and Type Functions++-- | A /symbolic/ type, i.e. a wrapper around a (poly kinded) type to be+-- produced by 'Eval' instances.+--+-- All data types, e.g. @data Point2 x y :: Type@ can be made into /symbolic+-- representations/ of other types, by adding a /symbolic/ type parameter:+-- @data Point2 x y :: A Vec2 -> Type@.+--+-- Complete example:+--+-- @+-- data PrettyPrinter c where+-- RenderText :: Symbol -> PrettyPrinter Symbol+-- WithColor :: Color -> PrettyPrinter c -> PrettyPrinter c+--+-- data Color = Black | White+--+-- data ColoredText :: Color -> Symbol -> IsA (PrettyPrinter Symbol)+--+-- type instance Eval (ColoredText c txt) = 'WithColor c ('RenderText txt)+-- @+data A :: forall foo . foo -> Type where+ MkA :: A foo++-- | Type alias for 'A' such that @data Point2 x y :: A Vec2 -> Type@ becomes+-- @data Point2 x y :: IsA Vec2@+type IsA (foo :: k) = (A foo -> Type :: Type)++-- | An alias to 'IsA'+type IsAn (oo :: k) = (IsA oo :: Type)++-- | An open type family to turn /symbolic/ type representations created with+-- 'A' or 'IsA' into the actual types.+type family Eval (t :: A foo -> Type) :: foo++-- | A type @foo@, @'IsA' foo@.+data Pure (f :: o) :: IsAn o+type instance Eval (Pure f) = f+type Return f = Pure f++-- | A symbolic type-level function.+data (:->) foo bar++-- | An open family of functions from @foo@ to @bar@+type family (f :: IsA (foo :-> bar)) $~ (x :: foo) :: bar+infixl 0 $~++-- | An alias for '$~'+type Apply f x = f $~ x++-- | Identity+data Id :: IsA (foo :-> foo)+type instance Id $~ x = x++-- | Symbolic function application+type (^*^) (f :: IsA (foo :-> bar)) (x :: IsA foo) = f $~ (Eval x)+infixl 0 ^*^++-- | Compose functions+data (:>>>:) :: IsA (good :-> better) -> IsA (better :-> best) -> IsA (good :-> best)+infixl 1 :>>>:+type instance (f :>>>: g) $~ x = g $~ (f $~ x)++-- | Eval Input & Compose+data (:^>>>:) :: IsA (good :-> better) -> IsA (better :-> best) -> IsA (IsA good :-> best)+infixl 1 :^>>>:+type instance (f :^>>>: g) $~ x = g $~ (f $~ Eval x)++-- | Compose and 'Return'+data (:>>>^:) :: IsA (good :-> better) -> IsA (better :-> best) -> IsA (good :-> IsA best)+infixl 1 :>>>^:+type instance (f :>>>^: g) $~ x = Return (g $~ (f $~ x))++-- | Eval compose and return+data (:^>>>^:) :: IsA (good :-> better) -> IsA (better :-> best) -> IsA (IsA good :-> IsA best)+infixl 1 :^>>>^:+type instance (f :^>>>^: g) $~ x = Return (g $~ (f $~ Eval x))++-- | A function that applies 'Eval'+data Extract :: IsA (IsA x :-> x)+type instance Extract $~ x = Eval x++-- | Eval and ApplyCompose functions+data (:>>=:) :: IsA foo -> IsA (foo :-> IsA bar) -> IsA bar+infixl 1 :>>=:+type instance Eval (x :>>=: f) = Eval (f $~ Eval x)++-- | Either use the value from @Just@ or return a fallback value(types(kinds))+data Optional :: IsA t -> IsA (s :-> IsA t) -> IsA (Maybe s :-> IsA t)++type instance (Optional fallback f) $~ ('Just s) = f $~ s+type instance (Optional fallback f) $~ 'Nothing = fallback++-- | Map over the elements of a list and fold the result.+type family+ FoldMap+ (append :: IsA (bar :-> IsA (bar :-> bar)))+ (zero :: bar)+ (f :: IsA (foo :-> bar))+ (xs :: [(foo :: Type)]) :: (bar :: Type) where+ FoldMap append zero f '[] = zero+ FoldMap append zero f (x ': xs) = append $~ (f $~ x) $~ FoldMap append zero f xs++-- TODONT safe coercions (with undecidable instances) could be done only with a+-- type-level equivilant of a type class dictionary, A good place for that+-- might be 'A'. For now I only had trouble with 'CoerceTo' because it is open+-- and the compiler often used up __all__ main memory when an instance was+-- missing.++-- | Like @TyCon1@ from Data.Singletons+data Fun1 :: (a -> IsA b)+ -> IsA (a :-> IsA b)+type instance (Fun1 f) $~ x = (f x)++data Fun2 :: (a -> b -> IsA c)+ -> IsA (a :-> IsA (b :-> IsA c))+type instance (Fun2 f) $~ x = Fun1 (f x)++data Fun3 :: (a -> b -> c -> IsA d)+ -> IsA (a :-> IsA (b :-> IsA (c :-> IsA d)))+type instance (Fun3 f) $~ x = Fun2 (f x)++data Fun4 :: (a -> b -> c -> d -> IsAn e)+ -> IsA (a :-> IsA (b :-> IsA (c :-> IsA (d :-> IsAn e))))+type instance (Fun4 f) $~ x = Fun3 (f x)
+ src/Data/Type/BitRecords.hs view
@@ -0,0 +1,21 @@+module Data.Type.BitRecords (+ module Data.Type.BitRecords.Arithmetic+ , module Data.Type.BitRecords.Assert+ , module Data.Type.BitRecords.Builder.BitBuffer+ , module Data.Type.BitRecords.Builder.Holey+ , module Data.Type.BitRecords.Builder.LazyByteStringBuilder+ , module Data.Type.BitRecords.Core+ , module Data.Type.BitRecords.Enum+ , module Data.Type.BitRecords.Sized+ , module Data.Type.BitRecords.SizedString+ ) where++import Data.Type.BitRecords.Arithmetic+import Data.Type.BitRecords.Assert+import Data.Type.BitRecords.Builder.BitBuffer+import Data.Type.BitRecords.Builder.Holey+import Data.Type.BitRecords.Builder.LazyByteStringBuilder+import Data.Type.BitRecords.Core+import Data.Type.BitRecords.Enum+import Data.Type.BitRecords.Sized+import Data.Type.BitRecords.SizedString
+ src/Data/Type/BitRecords/Arithmetic.hs view
@@ -0,0 +1,118 @@+{-# LANGUAGE UndecidableInstances #-}+module Data.Type.BitRecords.Arithmetic where++import Data.Type.Bool+import GHC.TypeLits++-- | Get the remainder of the integer division of x and y, such that @forall x+-- y. exists k. (Rem x y) == x - y * k@ The algorithm is: count down x+-- until zero, incrementing the accumulator at each step. Whenever the+-- accumulator is equal to y set it to zero.+--+-- If the accumulator has reached y reset it. It is important to do this+-- BEFORE checking if x == y and then returning the accumulator, for the case+-- where x = k * y with k > 0. For example:+--+-- @+-- 6 `Rem` 3 = RemImpl 6 3 0+-- RemImpl 6 3 0 = RemImpl (6-1) 3 (0+1) -- RemImpl Clause 4+-- RemImpl 5 3 1 = RemImpl (5-1) 3 (1+1) -- RemImpl Clause 4+-- RemImpl 4 3 2 = RemImpl (4-1) 3 (2+1) -- RemImpl Clause 4+-- RemImpl 3 3 3 = RemImpl 3 3 0 -- RemImpl Clause 2 !!!+-- RemImpl 3 3 0 = 0 -- RemImpl Clause 3 !!!+-- @+type family Rem (x :: Nat) (y :: Nat) :: Nat where+ Rem x 1 = 0+ Rem x 0 = TypeError ('Text "divide by zero: " ':<>: 'ShowType x ':<>: 'Text " `Rem` 0")+ Rem x y = RemImpl x y 0+type family+ RemImpl (x :: Nat) (y :: nat) (acc :: Nat) :: Nat where+ -- finished if x was < y:+ RemImpl 0 y acc = acc+ RemImpl x y y = RemImpl x y 0+ -- finished if x was >= y:+ RemImpl y y acc = acc+ -- the base case+ RemImpl x y acc = RemImpl (x - 1) y (acc + 1)++-- | Efficient 'Rem' operation for power of 2 values. Note that x must be+-- representable by 'RemPow2Bits' bits.+type RemPow2 x p =+ FromBits (TakeLastN p (ToBits x RemPow2Bits))++type TakeLastN n xs = TakeLastNImplRev n xs '[]++type family TakeLastNImplRev (n :: Nat) (xs :: [t]) (acc :: [t]) :: [t] where+ TakeLastNImplRev n '[] acc = TakeLastNImplTakeNRev n acc '[]+ TakeLastNImplRev n (x ': xs) acc =+ TakeLastNImplRev n xs (x ': acc)++type family TakeLastNImplTakeNRev (n :: Nat) (rs :: [t]) (acc :: [t]) :: [t] where+ TakeLastNImplTakeNRev n '[] acc = acc+ TakeLastNImplTakeNRev 0 rs acc = acc+ TakeLastNImplTakeNRev n (r ': rs) acc = TakeLastNImplTakeNRev (n-1) rs (r ': acc)+++-- | Maximum number of bits an argument @x@ of 'RemPow2' may occupy.+type RemPow2Bits = 32++-- | Integer division of x and y: @Div x y ==> x / y@,+-- NOTE This only works for small numbers currently+type Div (x :: Nat) (y :: Nat) = DivImpl (x - (x `Rem` y)) y 0+type family+ DivImpl (x :: Nat) (y :: nat) (acc :: Nat) :: Nat where+ DivImpl 0 y acc = acc+ DivImpl x y acc = If (x + 1 <=? y) acc (DivImpl (x - y) y (acc + 1))++-- * Bit manipulation++type family TestHighBit (x :: Nat) (n :: Nat) :: Bool where+ TestHighBit x n = ((2 ^ n) <=? x) -- x > 2^n++type ToBits x n = ToBits_ x n 'False+type family ToBits_ (x :: Nat) (n :: Nat) (started :: Bool) :: [Bool] where+ ToBits_ x 0 started = '[]+ ToBits_ x n started = ToBitsInner (TestHighBit x (n - 1)) x (n - 1) started+type family+ ToBitsInner (highBitSet :: Bool) (x :: Nat) (n :: Nat) (started :: Bool) :: [Bool] where+ ToBitsInner 'True x n started = 'True ': ToBits_ (x - 2^n) n 'True+ ToBitsInner 'False x n 'False = ToBits_ x n 'False+ ToBitsInner 'False x n 'True = 'False ': ToBits_ x n 'True++type FromBits bits = FromBits_ bits 0+type family FromBits_ (bits :: [Bool]) (acc :: Nat) :: Nat where+ FromBits_ '[] acc = acc+ FromBits_ ('False ': rest) acc = FromBits_ rest (acc + acc)+ FromBits_ ('True ': rest) acc = FromBits_ rest (1 + acc + acc)++type family+ ShiftBitsR (bits :: [Bool]) (n :: Nat) :: [Bool] where+ ShiftBitsR bits 0 = bits+ ShiftBitsR '[] n = '[]+ ShiftBitsR '[e] 1 = '[]+ ShiftBitsR (e ': rest) 1 = e ': ShiftBitsR rest 1+ ShiftBitsR (e ': rest) n = ShiftBitsR (ShiftBitsR (e ': rest) 1) (n - 1)++type family+ GetMostSignificantBitIndex (highestBit :: Nat) (n :: Nat) :: Nat where+ GetMostSignificantBitIndex 0 n = 1+ GetMostSignificantBitIndex highestBit n =+ If (2 ^ (highestBit + 1) <=? n)+ (TypeError ('Text "number to big: "+ ':<>: 'ShowType n+ ':<>: 'Text " >= "+ ':<>: 'ShowType (2 ^ (highestBit + 1))))+ (If (2 ^ highestBit <=? n)+ highestBit+ (GetMostSignificantBitIndex (highestBit - 1) n))++-- | Shift a type level natural to the right. This useful for division by powers+-- of two.+type family+ ShiftR (xMaxBits :: Nat) (x :: Nat) (bits :: Nat) :: Nat where+ ShiftR xMaxBits x n =+ FromBits+ (ShiftBitsR+ (ToBits x+ (1 + GetMostSignificantBitIndex xMaxBits x))+ n)
+ src/Data/Type/BitRecords/Assert.hs view
@@ -0,0 +1,91 @@+{-# LANGUAGE UndecidableInstances #-}+-- | Type - level assertion utility leveraging custom 'TypeError's+module Data.Type.BitRecords.Assert+ ( type Assert, type Assertion, type Check+ , type (?::)+ , type (@&&)+ , type NatLE+ , type NatGE+ , type NatIn+ , type LengthIn+ , type CountElementsForLengthIn+ ) where++import GHC.TypeLits+import Data.Kind (type Type)+import Data.Type.Bool++-- | Assert that a given type satisfies some condition defined via 'Check'+-- instances. This is only an alias for 'Assert'+type (?::) x cond = Assert cond x+infixr 0 ?::++-- | Apply an 'Assertion' to some value and return that value if the assertion+-- holds, otherwise throw a 'TypeError'.+type family Assert (cond :: Assertion a) (x :: a) :: a where+ Assert cond x = ProcessCheckResult (Check cond x) x++-- | Make an assertion by creating a phantom data type which contains @TyFun a+-- (Maybe ErrorMessage)@ as last parameter. 'Check' is used by 'Assert' the+-- /apply/ the 'TyFun's which are specialized in this definition to have the+-- return type @Maybe ErrorMessage@.+type Assertion a = TyFun a (Maybe ErrorMessage) -> Type++-- | Apply 'Assertion's to the actual values.+type family Check (f :: Assertion a) (x :: a) :: Maybe ErrorMessage++type family ProcessCheckResult (r :: Maybe ErrorMessage) (x :: a) :: a where+ ProcessCheckResult 'Nothing x = x+ ProcessCheckResult ('Just blah) x =+ TypeError ('Text "Assertion on value " ':<>: 'ShowType x ':<>: 'Text " failed:" ':$$: blah)++-- | Shamelessly stolen from the singletons library.+data TyFun :: Type -> Type -> Type++-- | Assert that two assertions both hold+data (@&&) :: Assertion a -> Assertion a -> Assertion a++type instance Check (a1 @&& a2) x =+ (ProcessCheckResult (Check a2 x)+ (ProcessCheckResult (Check a1 x) x))++-- | Assert that a 'Nat' is greater than or equal to an other 'Nat'.+data NatGE :: Nat -> Assertion Nat++type instance Check (NatGE n) x =+ If (n <=? x) 'Nothing ('Just ( 'Text "Natural too small: " ':<>: 'ShowType x+ ':$$: 'Text "Required: >=" ':<>: 'ShowType n))++-- | Assert that a 'Nat' is less than or equal to an other 'Nat'.+data NatLE :: Nat -> Assertion Nat++type instance Check (NatLE n) x =+ If (x <=? n) 'Nothing ('Just ( 'Text "Natural too big: " ':<>: 'ShowType x+ ':$$: 'Text "Required: <=" ':<>: 'ShowType n))+++-- | Assert that a 'Nat' is in a specific range.+data NatIn :: Nat -> Nat -> Assertion Nat++type instance Check (NatIn from to) n =+ CheckNatInRange (n <=? to) (from <=? n) from to n++type family+ CheckNatInRange+ (lt :: Bool) (gt :: Bool) (from :: Nat) (to :: Nat) (n :: Nat) :: Maybe ErrorMessage where+ CheckNatInRange 'True 'True from to x = 'Nothing+ CheckNatInRange c1 c2 from to x =+ 'Just ('Text "Natural out of range: " ':<>: 'ShowType x+ ':<>: 'Text " not in "+ ':<>: 'ShowType from ':<>: 'Text " .. " ':<>: 'ShowType to)++-- | Assert that a list's length falls into a given range.+-- This is generalized from actual lists; everything with a 'CountElementsForLengthIn'+-- instance can be asserted.+data LengthIn :: Nat -> Nat -> Assertion a++type instance Check (LengthIn from to) xs = Check (NatIn from to) (CountElementsForLengthIn xs)++type family CountElementsForLengthIn (xs :: k) :: Nat+type instance CountElementsForLengthIn ('[]) = 0+type instance CountElementsForLengthIn (x ': xs) = 1 + CountElementsForLengthIn xs
+ src/Data/Type/BitRecords/Builder/BitBuffer.hs view
@@ -0,0 +1,163 @@+{-# LANGUAGE UndecidableInstances #-}+{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}+module Data.Type.BitRecords.Builder.BitBuffer+ ( type BitStringMaxLength+ , type ModuloBitStringMaxLength+ , bitStringMaxLength+ , bitStringMaxLengthBytes+ , BitString()+ , bitStringContent+ , bitStringLength+ , isBitStringEmpty+ , bitStringSpaceLeft+ , bitString+ , emptyBitString+ , bitStringProxyLength+ , BitStringBuilderChunk()+ , bitStringBuilderChunkContent+ , bitStringBuilderChunkLength+ , isBitStringBuilderChunkEmpty+ , bitStringBuilderChunkSpaceLeft+ , bitStringBuilderChunk+ , emptyBitStringBuilderChunk+ , bufferBits+ , type KnownChunkSize+ ) where++import Data.Proxy++import Data.Type.BitRecords.Arithmetic+import Data.Bits+import Data.Word+import Data.Kind ( Constraint )+import GHC.TypeLits++-- | The maximum number of bits a 'BitBuffer' can hold.+type BitStringMaxLength = 64++-- | Calculate the modulus of a number and the 'BitStringMaxLength'.+type family ModuloBitStringMaxLength (len :: Nat) :: Nat where+ ModuloBitStringMaxLength len = len `RemPow2` 6++-- | The maximum number of bits a 'BitBuffer' can hold.+bitStringMaxLength :: Num a => a+bitStringMaxLength = 64++-- | The maximum number of bytes a 'BitBuffer' can hold.+bitStringMaxLengthBytes :: Word64+bitStringMaxLengthBytes = 8++-- | A string of bits with a given length (but always @<= 'bitStringMaxLength'@.+-- The number of bits must be smaller that 'bitStringMaxLength'.+data BitString = BitString !Word64 !Int++bitStringContent :: BitString -> Word64+bitStringContent (BitString !c _) =+ c++bitStringLength :: BitString -> Int+bitStringLength (BitString _ !len) =+ len++isBitStringEmpty :: BitString -> Bool+isBitStringEmpty (BitString _ !len) =+ len == 0++bitStringSpaceLeft :: BitString -> Int+bitStringSpaceLeft (BitString _ !len) =+ bitStringMaxLength - len++-- | Create a 'BitString' containing @len@ bits from LSB to MSB, properly+-- masked, such that only @len@ least significant bits are kept..+bitString :: Int -> Word64 -> BitString+bitString !len !b = BitString (let !s = bitStringMaxLength - len in ((b `unsafeShiftL` s) `unsafeShiftR` s)) len++-- | Create an empty 'BitString'.+emptyBitString :: BitString+emptyBitString = BitString 0 0++-- | A buffer for 64 bits, such that the bits are written MSB to LSB.+--+-- > type TwoFields = "f0" @: Field m .+. "f1" @: Field n+--+-- Writes:+-- @ MSB LSB+-- Bit: |k .. k-(m+1)|k-m .. k-(m+n+1)|k-(m+n) .. 0|+-- Value: |------f0------|--------f1--------|XXXXXXXXXXXXXX|+-- @+--+-- Where @k@ is the current bit offset.+-- The input values are expected to be in the order of the fields, i.e.:+--+-- @+-- runHoley $ bitStringBuilderHoley (Proxy :: Proxy TwoFields) 1 2+-- @+--+-- Will result in:+-- @ MSB LSB+-- Bit: |k .. k-(m+1)|k-m .. k-(m+n+1)| k-(m+n) .. 0|+-- Value: |0 .. 1|0 .. 10| X .. X|+-- @+data BitStringBuilderChunk = BitStringBuilderChunk !Word64 !Int++bitStringBuilderChunkContent :: BitStringBuilderChunk -> Word64+bitStringBuilderChunkContent (BitStringBuilderChunk !c _) =+ c++bitStringBuilderChunkLength :: BitStringBuilderChunk -> Int+bitStringBuilderChunkLength (BitStringBuilderChunk _ !len) =+ len++isBitStringBuilderChunkEmpty :: BitStringBuilderChunk -> Bool+isBitStringBuilderChunkEmpty (BitStringBuilderChunk _ !len) =+ len == 0++bitStringBuilderChunkSpaceLeft :: BitStringBuilderChunk -> Int+bitStringBuilderChunkSpaceLeft (BitStringBuilderChunk _ !len) =+ bitStringMaxLength - len++-- | Create a 'BitStringBuilderChunk' containing @len@ bits from LSB to MSB, properly+-- masked, such that only @len@ least significant bits are kept..+bitStringBuilderChunk :: Word64 -> Int -> BitStringBuilderChunk+bitStringBuilderChunk !b !len = BitStringBuilderChunk b len++-- | Create an empty 'BitStringBuilderChunk'.+emptyBitStringBuilderChunk :: BitStringBuilderChunk+emptyBitStringBuilderChunk = BitStringBuilderChunk 0 0++-- | Create a 'BitStringBuilderChunk' with a length given by a 'Proxy' to a type level+-- 'Nat'.+bitStringProxyLength :: (KnownChunkSize n) => Proxy n -> Word64 -> BitString+bitStringProxyLength !plen !v = bitString fieldLen v+ where+ !fieldLen = fromIntegral (natVal plen)+++-- | Copy bits starting at a specific offset from one @a@ the the other.+-- Set bits starting from the most significant bit to the least.+-- For example @writeBits m 1 <> writeBits n 2@ would result in:+--+-- @+-- MSB LSB+-- Bit: |k .. k-(m+1)|k-m .. k-(m+n+1)| k-(m+n) .. 0|+-- Value: |0 .. 1|0 .. 10| ... |+-- -> -> -> (direction of writing)+-- @+--+bufferBits :: BitString -- ^ The value to write (in the lower @length@ bits).+ -> BitStringBuilderChunk -- ^ The input to write to+ -> (BitString, BitStringBuilderChunk) -- ^ The remaining bits that did not fit+ -- in the buffer and the output buffer.+bufferBits (BitString !bits !len) (BitStringBuilderChunk !buff !offset) =+ let !spaceAvailable = bitStringMaxLength - offset+ !writeLen = min spaceAvailable len+ !writeOffset = spaceAvailable - writeLen+ !restLen = len - writeLen+ !restBits = bits .&. (1 `unsafeShiftL` restLen - 1)+ !buff' = buff .|.+ (bits `unsafeShiftR` restLen `unsafeShiftL` writeOffset)+ in+ (BitString restBits restLen, BitStringBuilderChunk buff' (offset + writeLen))++type family KnownChunkSize (s :: Nat) :: Constraint where+ KnownChunkSize size = (KnownNat size, size <= BitStringMaxLength)
+ src/Data/Type/BitRecords/Builder/Holey.hs view
@@ -0,0 +1,49 @@+{-# LANGUAGE Strict #-}+module Data.Type.BitRecords.Builder.Holey where++import Control.Category+import Data.Monoid+import Prelude hiding (id, (.))+import Data.Tagged++newtype Holey m r a = HM {runHM :: (m -> r) -> a }++instance Monoid m => Category (Holey m) where+ (.) (HM f) (HM g) = HM (\k -> (f (\m1 -> g (\m2 -> k (m1 <> m2)))))+ id = HM ($ mempty)++instance Monoid m => Monoid (Holey m r r) where+ mappend = (.)+ mempty = id++hoistM :: (m -> n) -> Holey m a b -> Holey n a b+hoistM into (HM f) = HM (\k -> f (k . into))++hoistR :: (s -> r) -> Holey m r a -> Holey m s a+hoistR outof (HM f) = HM (\k -> f (outof . k))++immediate :: m -> Holey m r r+immediate m =+ HM { runHM = ($ m) }++indirect :: (a -> m) -> Holey m r (a -> r)+indirect f =+ HM { runHM = (. f) }++bind :: Holey m b c+ -> (m -> Holey n a b)+ -> Holey n a c+bind mbc fm = HM $ \ kna -> runHM mbc (($ kna) . runHM . fm)++applyHoley :: Holey m r (a -> b) -> a -> Holey m r b+applyHoley (HM !f) x = HM $ \k -> f k x++taggedHoley :: forall tag m r a x . Holey m r (a -> x) -> Holey m r (Tagged tag a -> x)+taggedHoley = mapHoley (\f -> f . untag)++-- TODO prove Functor law, make functor+mapHoley :: (a -> b) -> Holey m r a -> Holey m r b+mapHoley f (HM !h) = HM $ \k -> f (h k)++runHoley :: Holey m m a -> a+runHoley = ($ id) . runHM
+ src/Data/Type/BitRecords/Builder/LazyByteStringBuilder.hs view
@@ -0,0 +1,322 @@+{-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE TypeApplications #-}+{-# OPTIONS_GHC -fno-warn-redundant-constraints #-}+module Data.Type.BitRecords.Builder.LazyByteStringBuilder where++import Data.Type.BitRecords.Builder.BitBuffer+import Data.Type.BitRecords.Builder.Holey+import Data.Type.BitRecords.Core+import Data.Word+import Data.Int+import Data.Bits+import Data.Kind.Extra+import Data.Proxy+import GHC.TypeLits+import Data.Monoid+import Control.Category+import Prelude hiding ((.), id)+import Data.ByteString.Builder+import qualified Data.ByteString.Lazy as B+import qualified Data.ByteString as SB+import Text.Printf++-- | A wrapper around a builder derived from a 'BitStringBuilderState'+data BuilderBox where+ MkBuilderBox :: !Word64 -> !Builder -> BuilderBox++instance Monoid BuilderBox where+ mempty = MkBuilderBox 0 mempty+ mappend (MkBuilderBox !ls !lb) (MkBuilderBox !rs !rb) =+ MkBuilderBox (ls + rs) (lb <> rb)++-- | Create a 'Builder' from a 'BitRecord' and store it in a 'BuilderBox'+bitBuilderBox ::+ forall (record :: BitRecord) .+ BitStringBuilderHoley (Proxy record) BuilderBox+ => Proxy record+ -> ToBitStringBuilder (Proxy record) BuilderBox+bitBuilderBox = runHoley . bitBuilderBoxHoley++-- | Like 'bitBuilderBox', but 'runHoley' the result and accept as an additional+-- parameter a wrapper function to wrap the final result (the 'BuilderBox') and+-- 'runHoley' the whole machiner.+wrapBitBuilderBox ::+ forall (record :: BitRecord) wrapped .+ BitStringBuilderHoley (Proxy record) wrapped+ => (BuilderBox -> wrapped)+ -> Proxy record+ -> ToBitStringBuilder (Proxy record) wrapped+wrapBitBuilderBox !f !p = runHoley (hoistM f (bitBuilderBoxHoley p))++-- | Create a 'Builder' from a 'BitRecord' and store it in a 'BuilderBox';+-- return a 'Holey' monoid that does that on 'runHoley'+bitBuilderBoxHoley ::+ forall (record :: BitRecord) r .+ BitStringBuilderHoley (Proxy record) r+ => Proxy record+ -> Holey BuilderBox r (ToBitStringBuilder (Proxy record) r)+bitBuilderBoxHoley !p =+ let fromBitStringBuilder !h =+ let (BitStringBuilderState !builder _ !wsize) =+ flushBitStringBuilder+ $ appBitStringBuilder h initialBitStringBuilderState+ !out = MkBuilderBox wsize builder+ in out+ in hoistM fromBitStringBuilder (bitStringBuilderHoley p)++-- * Low-level interface to building 'BitRecord's and other things++newtype BitStringBuilder =+ BitStringBuilder {unBitStringBuilder :: Dual (Endo BitStringBuilderState)}+ deriving (Monoid)++runBitStringBuilder+ :: BitStringBuilder -> Builder+runBitStringBuilder !w =+ getBitStringBuilderStateBuilder $+ flushBitStringBuilder $ appBitStringBuilder w initialBitStringBuilderState++bitStringBuilder :: (BitStringBuilderState -> BitStringBuilderState)+ -> BitStringBuilder+bitStringBuilder = BitStringBuilder . Dual . Endo++appBitStringBuilder :: BitStringBuilder+ -> BitStringBuilderState+ -> BitStringBuilderState+appBitStringBuilder !w = appEndo (getDual (unBitStringBuilder w))++data BitStringBuilderState where+ BitStringBuilderState ::+ !Builder -> !BitStringBuilderChunk -> !Word64 -> BitStringBuilderState++getBitStringBuilderStateBuilder+ :: BitStringBuilderState -> Builder+getBitStringBuilderStateBuilder (BitStringBuilderState !builder _ _) = builder++initialBitStringBuilderState+ :: BitStringBuilderState+initialBitStringBuilderState =+ BitStringBuilderState mempty emptyBitStringBuilderChunk 0++-- | Write the partial buffer contents using any number of 'word8' The unwritten+-- parts of the bittr buffer are at the top. If the+--+-- > 63 ... (63-off-1)(63-off) ... 0+-- > ^^^^^^^^^^^^^^^^^^^+-- > Relevant bits start to the top!+--+flushBitStringBuilder+ :: BitStringBuilderState -> BitStringBuilderState+flushBitStringBuilder (BitStringBuilderState !bldr !buff !totalSize) =+ BitStringBuilderState (writeRestBytes bldr 0)+ emptyBitStringBuilderChunk+ totalSize'+ where !off = bitStringBuilderChunkLength buff+ !off_ = (fromIntegral off :: Word64)+ !totalSize' = totalSize + signum (off_ `rem` 8) + (off_ `div` 8)+ !part = bitStringBuilderChunkContent buff+ -- write bytes from msb to lsb until the offset is reached+ -- > 63 ... (63-off-1)(63-off) ... 0+ -- > ^^^^^^^^^^^^^^^^^^^+ -- > AAAAAAAABBBBBBBBCCC00000+ -- > |byte A| byte B| byte C|+ writeRestBytes !bldr' !flushOffset =+ if off <= flushOffset+ then bldr'+ else let !flushOffset' = flushOffset + 8+ !bldr'' =+ bldr' <>+ word8 (fromIntegral+ ((part `unsafeShiftR`+ (bitStringMaxLength - flushOffset')) .&.+ 0xFF))+ in writeRestBytes bldr'' flushOffset'++-- | Write all the bits, in chunks, filling and writing the 'BitString'+-- in the 'BitStringBuilderState' as often as necessary.+appendBitString :: BitString -> BitStringBuilder+appendBitString !x' =+ bitStringBuilder $+ \(BitStringBuilderState !builder !buff !totalSizeIn) -> go x' builder buff totalSizeIn+ where go !x !builder !buff !totalSize+ | bitStringLength x == 0 = BitStringBuilderState builder buff totalSize+ | otherwise =+ let (!rest, !buff') = bufferBits x buff+ in if bitStringBuilderChunkSpaceLeft buff' > 0+ then BitStringBuilderState builder buff' totalSize+ else let !nextBuilder =+ builder <>+ word64BE (bitStringBuilderChunkContent buff')+ !totalSize' = totalSize + bitStringMaxLengthBytes+ in go rest nextBuilder emptyBitStringBuilderChunk totalSize'++-- | Write all the b*y*tes, into the 'BitStringBuilderState' this allows general+-- purposes non-byte aligned builders.+appendStrictByteString :: SB.ByteString -> BitStringBuilder+appendStrictByteString !sb =+ foldMap (appendBitString . bitString 8 . fromIntegral) (SB.unpack sb)++runBitStringBuilderHoley+ :: Holey BitStringBuilder Builder a -> a+runBitStringBuilderHoley (HM !x) = x runBitStringBuilder++-- * 'BitString' construction from 'BitRecord's++class BitStringBuilderHoley a r where+ type ToBitStringBuilder a r+ type ToBitStringBuilder a r = r+ bitStringBuilderHoley :: a -> Holey BitStringBuilder r (ToBitStringBuilder a r)++instance BitStringBuilderHoley BitString r where+ bitStringBuilderHoley = immediate . appendBitString++-- ** 'BitRecordField' instances++type family UnsignedDemoteRep i where+ UnsignedDemoteRep Int8 = Word8+ UnsignedDemoteRep Int16 = Word16+ UnsignedDemoteRep Int32 = Word32+ UnsignedDemoteRep Int64 = Word64++-- *** Labbeled Fields++instance+ forall nested l a .+ ( BitStringBuilderHoley (Proxy nested) a )+ => BitStringBuilderHoley (Proxy (LabelF l nested)) a where+ type ToBitStringBuilder (Proxy (LabelF l nested)) a =+ ToBitStringBuilder (Proxy nested) a+ bitStringBuilderHoley _ = bitStringBuilderHoley (Proxy @nested)++-- **** Bool++instance forall f a . (BitRecordFieldSize f ~ 1) =>+ BitStringBuilderHoley (Proxy (f := 'True)) a where+ bitStringBuilderHoley _ = immediate (appendBitString (bitString 1 1))++instance forall f a . (BitRecordFieldSize f ~ 1) =>+ BitStringBuilderHoley (Proxy (f := 'False)) a where+ bitStringBuilderHoley _ = immediate (appendBitString (bitString 1 0))++instance forall a .+ BitStringBuilderHoley (Proxy (MkField 'MkFieldFlag)) a where+ type ToBitStringBuilder (Proxy (MkField 'MkFieldFlag)) a = Bool -> a+ bitStringBuilderHoley _ =+ indirect (appendBitString . bitString 1 . (\ !t -> if t then 1 else 0))++-- **** Bits++instance forall (s :: Nat) a . (KnownChunkSize s) =>+ BitStringBuilderHoley (Proxy (MkField ('MkFieldBits :: BitField (B s) Nat s))) a where+ type ToBitStringBuilder (Proxy (MkField ('MkFieldBits :: BitField (B s) Nat s))) a = B s -> a+ bitStringBuilderHoley _ = indirect (appendBitString . bitStringProxyLength (Proxy @s) . unB)++-- **** Naturals++instance forall a .+ BitStringBuilderHoley (Proxy (MkField 'MkFieldU64)) a where+ type ToBitStringBuilder (Proxy (MkField 'MkFieldU64)) a = Word64 -> a+ bitStringBuilderHoley _ = indirect (appendBitString . bitString 64)++instance forall a .+ BitStringBuilderHoley (Proxy (MkField 'MkFieldU32)) a where+ type ToBitStringBuilder (Proxy (MkField 'MkFieldU32)) a = Word32 -> a+ bitStringBuilderHoley _ = indirect (appendBitString . bitString 32 . fromIntegral)++instance forall a .+ BitStringBuilderHoley (Proxy (MkField 'MkFieldU16)) a where+ type ToBitStringBuilder (Proxy (MkField 'MkFieldU16)) a = Word16 -> a+ bitStringBuilderHoley _ = indirect (appendBitString . bitString 16 . fromIntegral)++instance forall a .+ BitStringBuilderHoley (Proxy (MkField 'MkFieldU8)) a where+ type ToBitStringBuilder (Proxy (MkField 'MkFieldU8)) a = Word8 -> a+ bitStringBuilderHoley _ = indirect (appendBitString . bitString 8 . fromIntegral)++-- **** Signed++instance forall a .+ BitStringBuilderHoley (Proxy (MkField 'MkFieldI64)) a where+ type ToBitStringBuilder (Proxy (MkField 'MkFieldI64)) a = Int64 -> a+ bitStringBuilderHoley _ = indirect (appendBitString . bitString 64 . fromIntegral @Int64 @Word64)++instance forall a .+ BitStringBuilderHoley (Proxy (MkField 'MkFieldI32)) a where+ type ToBitStringBuilder (Proxy (MkField 'MkFieldI32)) a = Int32 -> a+ bitStringBuilderHoley _ = indirect (appendBitString . bitString 32 . fromIntegral . fromIntegral @Int32 @Word32)++instance forall a .+ BitStringBuilderHoley (Proxy (MkField 'MkFieldI16)) a where+ type ToBitStringBuilder (Proxy (MkField 'MkFieldI16)) a = Int16 -> a+ bitStringBuilderHoley _ = indirect (appendBitString . bitString 16 . fromIntegral . fromIntegral @Int16 @Word16)++instance forall a .+ BitStringBuilderHoley (Proxy (MkField 'MkFieldI8)) a where+ type ToBitStringBuilder (Proxy (MkField 'MkFieldI8)) a = Int8 -> a+ bitStringBuilderHoley _ = indirect (appendBitString . bitString 8 . fromIntegral . fromIntegral @Int8 @Word8)+++instance forall (f :: IsA (BitRecordField (t :: BitField rt Nat len))) (v :: Nat) a . (KnownNat v, BitStringBuilderHoley (Proxy f) a, ToBitStringBuilder (Proxy f) a ~ (rt -> a), Num rt) =>+ BitStringBuilderHoley (Proxy (f := v)) a where+ bitStringBuilderHoley _ = applyHoley (bitStringBuilderHoley (Proxy @f)) (fromIntegral (natVal (Proxy @v)))++instance forall v f a x . (KnownNat v, BitStringBuilderHoley (Proxy f) a, ToBitStringBuilder (Proxy f) a ~ (x -> a), Num x) =>+ BitStringBuilderHoley (Proxy (f := ('PositiveNat v))) a where+ bitStringBuilderHoley _ = applyHoley (bitStringBuilderHoley (Proxy @f)) (fromIntegral (natVal (Proxy @v)))+++instance forall v f a x . (KnownNat v, BitStringBuilderHoley (Proxy f) a, ToBitStringBuilder (Proxy f) a ~ (x -> a), Num x) =>+ BitStringBuilderHoley (Proxy (f := ('NegativeNat v))) a where+ bitStringBuilderHoley _ = applyHoley (bitStringBuilderHoley (Proxy @f)) (fromIntegral (-1 * (natVal (Proxy @v))))++-- ** 'BitRecord' instances++instance forall (r :: IsA BitRecord) a . BitStringBuilderHoley (Proxy (Eval r)) a =>+ BitStringBuilderHoley (Proxy r) a where+ type ToBitStringBuilder (Proxy r) a =+ ToBitStringBuilder (Proxy (Eval r)) a+ bitStringBuilderHoley _ = bitStringBuilderHoley (Proxy @(Eval r))++-- *** 'BitRecordMember'++instance forall f a . BitStringBuilderHoley (Proxy f) a => BitStringBuilderHoley (Proxy ('BitRecordMember f)) a where+ type ToBitStringBuilder (Proxy ('BitRecordMember f)) a = ToBitStringBuilder (Proxy f) a+ bitStringBuilderHoley _ = bitStringBuilderHoley (Proxy @f)++-- *** 'AppendedBitRecords'++instance forall l r a .+ (BitStringBuilderHoley (Proxy l) (ToBitStringBuilder (Proxy r) a)+ , BitStringBuilderHoley (Proxy r) a)+ => BitStringBuilderHoley (Proxy ('BitRecordAppend l r)) a where+ type ToBitStringBuilder (Proxy ('BitRecordAppend l r)) a =+ ToBitStringBuilder (Proxy l) (ToBitStringBuilder (Proxy r) a)+ bitStringBuilderHoley _ = bitStringBuilderHoley (Proxy @l) . bitStringBuilderHoley (Proxy @r)++-- *** 'EmptyBitRecord' and '...Pretty'++instance forall d r a . BitStringBuilderHoley (Proxy r) a =>+ BitStringBuilderHoley (Proxy ('BitRecordDocNested d r)) a where+ type ToBitStringBuilder (Proxy ('BitRecordDocNested d r)) a =+ ToBitStringBuilder (Proxy r) a+ bitStringBuilderHoley _ = bitStringBuilderHoley (Proxy @r)++instance BitStringBuilderHoley (Proxy ('BitRecordDoc d)) a where+ bitStringBuilderHoley _ = id++instance BitStringBuilderHoley (Proxy 'EmptyBitRecord) a where+ bitStringBuilderHoley _ = id++-- ** Tracing/Debug Printing++-- | Print a 'Builder' to a space seperated series of hexa-decimal bytes.+printBuilder :: Builder -> String+printBuilder b =+ ("<< " ++) $+ (++ " >>") $ unwords $ printf "%0.2x" <$> B.unpack (toLazyByteString b)++bitStringPrinter+ :: BitStringBuilderHoley a String+ => a -> ToBitStringBuilder a String+bitStringPrinter =+ runHoley . hoistM (printBuilder . runBitStringBuilder) . bitStringBuilderHoley
+ src/Data/Type/BitRecords/Core.hs view
@@ -0,0 +1,379 @@+{-# LANGUAGE UndecidableInstances #-}+module Data.Type.BitRecords.Core where++import Data.Int+import Data.Kind (Type)+import Data.Kind.Extra+import Data.Proxy+import Data.Type.Pretty+import Data.Word+import Data.Bits+import GHC.TypeLits+import Text.Printf++-- * Bit-Records++-- ** Bit-Record Type++-- | 'BitRecordField's assembly+data BitRecord where+ EmptyBitRecord :: BitRecord+ BitRecordDoc :: PrettyType -> BitRecord+ BitRecordMember :: IsA (BitRecordField t) -> BitRecord+ BitRecordDocNested :: PrettyType -> BitRecord -> BitRecord+ BitRecordAppend :: BitRecord -> BitRecord -> BitRecord+ -- TODO MissingBitRecord :: ErrorMessage -> BitRecord++-- | A conditional 'BitRecord'+type family WhenR (b :: Bool) (x :: BitRecord) :: BitRecord where+ WhenR 'False r = 'EmptyBitRecord+ WhenR 'True r = r++-- *** Basic Accessor++-- | Eval the size in as a number of bits from a 'BitRecord'+type family BitRecordSize (x :: BitRecord) :: Nat where+ BitRecordSize 'EmptyBitRecord = 0+ BitRecordSize ('BitRecordDoc d) = 0+ BitRecordSize ('BitRecordMember f) = BitRecordFieldSize f+ BitRecordSize ('BitRecordDocNested d r) = BitRecordSize r+ BitRecordSize ('BitRecordAppend l r) = BitRecordSize l + BitRecordSize r++-- | The total number of members in a record.+type family BitRecordMemberCount (b :: BitRecord) :: Nat where+ BitRecordMemberCount 'EmptyBitRecord = 0+ BitRecordMemberCount ('BitRecordDoc r) = 0+ BitRecordMemberCount ('BitRecordMember f) = 1+ BitRecordMemberCount ('BitRecordDocNested d r) = BitRecordMemberCount r+ BitRecordMemberCount ('BitRecordAppend l r) = BitRecordMemberCount l + BitRecordMemberCount r++-- | Return the size of the record.+getRecordSizeFromProxy+ :: forall px (rec :: BitRecord) . KnownNat (BitRecordSize rec) => px rec -> Integer+getRecordSizeFromProxy _ = natVal (Proxy :: Proxy (BitRecordSize rec))++-- | Either use the value from @Just@ or return a 'EmptyBitRecord' value(types(kinds))+type OptionalRecordOf (f :: IsA (s :-> IsA BitRecord)) (x :: Maybe s) =+ (Optional (Pure 'EmptyBitRecord) f $~ x :: IsA BitRecord)++-- TODO remove??++-- ** Record PrettyPrinting++-- | Augment the pretty printed output of a 'BitRecord'+data (prettyTitle :: PrettyType) #: (r :: IsA BitRecord) :: IsA BitRecord+infixr 4 #:+type instance Eval (prettyTitle #: r) = Append ('BitRecordDoc prettyTitle) (Eval r)++-- | Augment the pretty printed output of a 'BitRecord'+type (prettyTitle :: PrettyType) #+: (r :: BitRecord) =+ Append ('BitRecordDoc prettyTitle) r+infixr 4 #+:++-- | Augment the pretty printed output of a 'BitRecord'+data (prettyTitle :: PrettyType) #$ (r :: IsA BitRecord) :: IsA BitRecord+infixr 2 #$+type instance Eval (prettyTitle #$ r) = 'BitRecordDocNested prettyTitle (Eval r)++-- | Augment the pretty printed output of a 'BitRecord'+type (prettyTitle :: PrettyType) #+$ (r :: BitRecord)+ = 'BitRecordDocNested prettyTitle r+infixr 2 #+$++-- ** Record composition++-- | Combine two 'BitRecord's to form a new 'BitRecord'. If the parameters are+-- not of type 'BitRecord' they will be converted.+data (:+^) (l :: BitRecord) (r :: IsA BitRecord) :: IsA BitRecord+infixl 3 :+^+type instance Eval (l :+^ r) = l `Append` Eval r++-- | Combine two 'BitRecord's to form a new 'BitRecord'. If the parameters are+-- not of type 'BitRecord' they will be converted.+data (:^+) (l :: IsA BitRecord) (r :: BitRecord) :: IsA BitRecord+infixl 3 :^++type instance Eval (l :^+ r) = Eval l `Append` r++-- | Combine two 'BitRecord's to form a new 'BitRecord'. If the parameters are+-- not of type 'BitRecord' they will be converted.+type (:+:) (l :: BitRecord) (r :: BitRecord) = ((l `Append` r) :: BitRecord)+infixl 3 :+:++type family Append (l :: BitRecord) (r :: BitRecord) :: BitRecord where+ Append l 'EmptyBitRecord = l+ Append 'EmptyBitRecord r = r+ Append l r = 'BitRecordAppend l r++-- | Append a 'BitRecord' and a 'BitRecordField'+type (:+.) (r :: BitRecord)+ (f :: IsA (BitRecordField t1))+ = Append r ('BitRecordMember f)+infixl 6 :+.++-- | Append a 'BitRecordField' and a 'BitRecord'+type (.+:) (f :: IsA (BitRecordField t1))+ (r :: BitRecord)+ = Append ('BitRecordMember f) r+infixr 6 .+:++-- | Append a 'BitRecordField' and a 'BitRecordField' forming a 'BitRecord' with+-- two members.+type (.+.) (l :: IsA (BitRecordField t1))+ (r :: IsA (BitRecordField t2))+ = Append ('BitRecordMember l) ('BitRecordMember r)+infixr 6 .+.++-- | Set a field to either a static, compile time, value or a dynamic, runtime value.+type family (:~)+ (field :: IsA (BitRecordField (t :: BitField (rt :: Type) (st :: k) (len :: Nat))))+ (value :: IsA (FieldValue (label :: Symbol) st))+ :: IsA (BitRecordField t) where+ fld :~ StaticFieldValue l v = (l @: fld) := v+ fld :~ RuntimeFieldValue l = l @: fld+infixl 7 :~++-- | Like ':~' but for a 'Maybe' parameter. In case of 'Just' it behaves like ':~'+-- in case of 'Nothing' it return an 'EmptyBitRecord'.+type family (:~?)+ (fld :: IsA (BitRecordField (t :: BitField (rt :: Type) (st :: k) (len :: Nat))))+ (value :: Maybe (IsA (FieldValue (label :: Symbol) st)))+ :: IsA BitRecord where+ fld :~? ('Just v) = RecordField (fld :~ v)+ fld :~? 'Nothing = Pure 'EmptyBitRecord+infixl 7 :~?++-- | Like ':~' but for a 'Maybe' parameter. In case of 'Just' it behaves like ':~'+-- in case of 'Nothing' it return an 'EmptyBitRecord'.+type family (:+?)+ (fld :: IsA (BitRecordField (t :: BitField (rt :: Type) (st :: k) (len :: Nat))))+ (value :: Maybe (IsA (FieldValue (label :: Symbol) st)))+ :: BitRecord where+ fld :+? ('Just v) = 'BitRecordMember (fld :~ v)+ fld :+? 'Nothing = 'EmptyBitRecord+infixl 7 :+?++-- | The field value parameter for ':~', either a static, compile time, value or+-- a dynamic, runtime value.+data FieldValue :: Symbol -> staticRep -> Type+data StaticFieldValue (label :: Symbol) :: staticRep -> IsA (FieldValue label staticRep)+data RuntimeFieldValue (label :: Symbol) :: IsA (FieldValue label staticRep)++-- *** Record Arrays and Repitition++-- | An array of records with a fixed number of elements, NOTE: this type is+-- actually not really necessary since 'ReplicateRecord' exists, but this allows+-- to have a different 'showRecord' output.+data RecArray :: BitRecord -> Nat -> IsA BitRecord++type r ^^ n = RecArray r n+infixl 5 ^^++type instance Eval (RecArray (r :: BitRecord) n ) = RecArrayToBitRecord r n++-- | Repeat a bit record @n@ times.+type family RecArrayToBitRecord (r :: BitRecord) (n :: Nat) :: BitRecord where+ RecArrayToBitRecord r 0 = 'EmptyBitRecord+ RecArrayToBitRecord r 1 = r+ RecArrayToBitRecord r n = Append r (RecArrayToBitRecord r (n - 1))++-- *** Lists of Records++-- | Let type level lists also be records+data+ BitRecordOfList+ (f :: IsA (foo :-> BitRecord))+ (xs :: [foo])+ :: IsA BitRecord++type instance Eval (BitRecordOfList f xs) =+ FoldMap BitRecordAppendFun 'EmptyBitRecord f xs++type BitRecordAppendFun = Fun1 BitRecordAppendFun_+data BitRecordAppendFun_ :: BitRecord -> IsA (BitRecord :-> BitRecord)+type instance (BitRecordAppendFun_ l) $~ r = Append l r++-- *** Maybe Record++-- | Either use the value from @Just@ or return a 'EmptyBitRecord' value(types(kinds))+data OptionalRecord :: Maybe BitRecord -> IsA BitRecord+type instance Eval (OptionalRecord ('Just t)) = t+type instance Eval (OptionalRecord 'Nothing) = 'EmptyBitRecord++-- ** Field ADT++-- | A family of bit fields.+--+-- A bit field always has a size, i.e. the number of bits it uses, as well as a+-- term level value type and a type level value type. It also has an optional+-- label, and an optional value assigned to it.+data BitRecordField :: BitField rt st len -> Type++-- | A bit record field with a number of bits+data MkField t :: IsA (BitRecordField t)++-- **** Setting a Label++-- | A bit record field with a number of bits+data LabelF :: Symbol -> IsA (BitRecordField t) -> IsA (BitRecordField t)++-- | A field with a label assigned to it.+type+ (l :: Symbol) @:(f :: IsA (BitRecordField (t :: BitField rt (st :: stk) size)))+ = (LabelF l f :: IsA (BitRecordField t))+infixr 8 @:++-- **** Assignment++-- | A field with a value set at compile time.+data (:=) :: forall st (t :: BitField rt st size) .+ IsA (BitRecordField t)+ -> st+ -> IsA (BitRecordField t)+infixl 7 :=++-- | Types of this kind define the basic type of a 'BitRecordField'. Sure, this+-- could have been an open type, but really, how many actual useful field types+-- exist? Well, from a global perspective, uncountable infinite, but the focus+-- of this library is to blast out bits over the network, using usual Haskell+-- libraries, and hence, there is actually only very little reason to+-- differentiate types of record fields, other than what low-level library+-- function to apply and how to pretty print the field.+data BitField+ (runtimeRep :: Type)+ (staticRep :: k)+ (bitCount :: Nat)+ where+ MkFieldFlag :: BitField Bool Bool 1+ MkFieldBits :: forall (n :: Nat) . BitField (B n) Nat n+ MkFieldBitsXXL :: forall (n :: Nat) . BitField Integer Nat n+ MkFieldU8 :: BitField Word8 Nat 8+ MkFieldU16 :: BitField Word16 Nat 16+ MkFieldU32 :: BitField Word32 Nat 32+ MkFieldU64 :: BitField Word64 Nat 64+ MkFieldI8 :: BitField Int8 SignedNat 8+ MkFieldI16 :: BitField Int16 SignedNat 16+ MkFieldI32 :: BitField Int32 SignedNat 32+ MkFieldI64 :: BitField Int64 SignedNat 64+ -- TODO refactor this MkFieldCustom, it caused a lot of trouble!+ MkFieldCustom :: BitField rt st n++type Flag = MkField 'MkFieldFlag+type Field n = MkField ('MkFieldBits :: BitField (B n) Nat n)+type FieldU8 = MkField 'MkFieldU8+type FieldU16 = MkField 'MkFieldU16+type FieldU32 = MkField 'MkFieldU32+type FieldU64 = MkField 'MkFieldU64+type FieldI8 = MkField 'MkFieldI8+type FieldI16 = MkField 'MkFieldI16+type FieldI32 = MkField 'MkFieldI32+type FieldI64 = MkField 'MkFieldI64++-- | A data type for 'Field' and 'MkFieldBits', that is internally a 'Word64'.+-- It carries the number of relevant bits in its type.+newtype B (size :: Nat) = B {unB :: Word64}+ deriving (Read,Show,Num,Integral,Bits,FiniteBits,Eq,Ord,Bounded,Enum,Real)++instance (PrintfArg Word64, n <= 64) => PrintfArg (B n) where+ formatArg (B x) = formatArg x+ parseFormat (B x) = parseFormat x++-- | A signed field value.+data SignedNat where+ PositiveNat :: Nat -> SignedNat+ NegativeNat :: Nat -> SignedNat++-- *** Composed Fields++-- | A Flag (1-bit) that is true if the type level maybe is 'Just'.+type family FlagJust (a :: Maybe (v :: Type)) :: IsA (BitRecordField 'MkFieldFlag) where+ FlagJust ('Just x) = Flag := 'True+ FlagJust 'Nothing = Flag := 'False++-- | A Flag (1-bit) that is true if the type level maybe is 'Nothing'.+type family FlagNothing (a :: Maybe (v :: Type)) :: IsA (BitRecordField 'MkFieldFlag) where+ FlagNothing ('Just x) = Flag := 'False+ FlagNothing 'Nothing = Flag := 'True++-- | An optional field in a bit record+data MaybeField :: Maybe (IsA (BitRecordField t)) -> IsA BitRecord+type instance Eval (MaybeField ('Just fld)) =+ Append ('BitRecordDoc (PutStr "Just")) ('BitRecordMember fld)+type instance Eval (MaybeField 'Nothing) =+ 'BitRecordDoc (PutStr "Nothing")++-- | A 'BitRecordField' can be used as 'BitRecordMember'+data RecordField :: IsA (BitRecordField t) -> IsA BitRecord+type instance Eval (RecordField f) = 'BitRecordMember f++-- | Calculate the size as a number of bits from a 'BitRecordField'+type family BitRecordFieldSize (x :: IsA (BitRecordField t)) where+ BitRecordFieldSize (x :: IsA (BitRecordField (t :: BitField rt st size))) = size+++-- * Field and Record PrettyType Instances++-- | Render @rec@ to a pretty, human readable form. Internally this is a wrapper+-- around 'ptShow' using 'PrettyRecord'.+showARecord+ :: forall proxy (rec :: IsA BitRecord) . PrettyTypeShow (PrettyRecord (Eval rec))+ => proxy rec -> String+showARecord _ = showPretty (Proxy :: Proxy (PrettyRecord (Eval rec)))++-- | Render @rec@ to a pretty, human readable form. Internally this is a wrapper+-- around 'ptShow' using 'PrettyRecord'.+showRecord+ :: forall proxy (rec :: BitRecord) . PrettyTypeShow (PrettyRecord rec)+ => proxy rec -> String+showRecord _ = showPretty (Proxy :: Proxy (PrettyRecord rec))++type instance ToPretty (rec :: BitRecord) = PrettyRecord rec++type family PrettyRecord (rec :: BitRecord) :: PrettyType where+ PrettyRecord ('BitRecordMember m) = PrettyField m+ PrettyRecord ' EmptyBitRecord = 'PrettyNewline+ PrettyRecord ('BitRecordAppend l r) = PrettyRecord l <$$> PrettyRecord r+ PrettyRecord ('BitRecordDoc p) = p+ PrettyRecord ('BitRecordDocNested p r) = p <$$--> PrettyRecord r++type instance ToPretty (f :: IsA (BitRecordField t)) = PrettyField f++type family PrettyField (f :: IsA (BitRecordField (t :: BitField (rt :: Type) (st :: Type) (size :: Nat)))) :: PrettyType where+ PrettyField (MkField t) = PrettyFieldType t+ PrettyField ((f :: IsA (BitRecordField t)) := v) =+ PrettyField f <+> PutStr ":=" <+> PrettyFieldValue t v+ PrettyField (LabelF l f) = l <:> PrettyField f++type family PrettyFieldType (t :: BitField (rt :: Type) (st :: Type) (size :: Nat)) :: PrettyType where+ PrettyFieldType ('MkFieldFlag) = PutStr "boolean"+ PrettyFieldType ('MkFieldBits :: BitField (B (s :: Nat)) Nat s) = PutStr "bits" <++> PrettyParens (PutNat s)+ PrettyFieldType ('MkFieldBitsXXL :: BitField Integer Nat (s :: Nat)) = PutStr "bits-XXL" <++> PrettyParens (PutNat s)+ PrettyFieldType ('MkFieldU64) = PutStr "U64"+ PrettyFieldType ('MkFieldU32) = PutStr "U32"+ PrettyFieldType ('MkFieldU16) = PutStr "U16"+ PrettyFieldType ('MkFieldU8) = PutStr "U8"+ PrettyFieldType ('MkFieldI64) = PutStr "I64"+ PrettyFieldType ('MkFieldI32) = PutStr "I32"+ PrettyFieldType ('MkFieldI16) = PutStr "I16"+ PrettyFieldType ('MkFieldI8) = PutStr "I8"+ PrettyFieldType ('MkFieldCustom :: BitField rt ct size) = ToPretty rt <++> PrettyParens (PutNat size)++type family PrettyFieldValue (t :: BitField (rt :: Type) (st :: Type) (size :: Nat)) (v :: st) :: PrettyType where+ PrettyFieldValue ('MkFieldFlag) 'True = PutStr "yes"+ PrettyFieldValue ('MkFieldFlag) 'False = PutStr "no"+ PrettyFieldValue ('MkFieldBits :: BitField (B (s :: Nat)) Nat s) v =+ 'PrettyNat 'PrettyUnpadded ('PrettyPrecision s) 'PrettyBit v <+> PrettyParens (("hex" <:> PutHex v) <+> ("dec" <:> PutNat v))+ PrettyFieldValue ('MkFieldU8) v = ("hex" <:> PutHex8 v) <+> PrettyParens ("dec" <:> PutNat v)+ PrettyFieldValue ('MkFieldU16) v = ("hex" <:> PutHex16 v) <+> PrettyParens ("dec" <:> PutNat v)+ PrettyFieldValue ('MkFieldU32) v = ("hex" <:> PutHex32 v) <+> PrettyParens ("dec" <:> PutNat v)+ PrettyFieldValue ('MkFieldU64) v = ("hex" <:> PutHex64 v) <+> PrettyParens ("dec" <:> PutNat v)+ PrettyFieldValue ('MkFieldI8) ('PositiveNat v) = ("hex" <:> (PutStr "+" <++> PutHex8 v)) <+> PrettyParens ("dec" <:> (PutStr "+" <++> PutNat v))+ PrettyFieldValue ('MkFieldI16) ('PositiveNat v) = ("hex" <:> (PutStr "+" <++> PutHex16 v)) <+> PrettyParens ("dec" <:> (PutStr "+" <++> PutNat v))+ PrettyFieldValue ('MkFieldI32) ('PositiveNat v) = ("hex" <:> (PutStr "+" <++> PutHex32 v)) <+> PrettyParens ("dec" <:> (PutStr "+" <++> PutNat v))+ PrettyFieldValue ('MkFieldI64) ('PositiveNat v) = ("hex" <:> (PutStr "+" <++> PutHex64 v)) <+> PrettyParens ("dec" <:> (PutStr "+" <++> PutNat v))+ PrettyFieldValue ('MkFieldI8) ('NegativeNat v) = ("hex" <:> (PutStr "-" <++> PutHex8 v)) <+> PrettyParens ("dec" <:> (PutStr "-" <++> PutNat v))+ PrettyFieldValue ('MkFieldI16) ('NegativeNat v) = ("hex" <:> (PutStr "-" <++> PutHex16 v)) <+> PrettyParens ("dec" <:> (PutStr "-" <++> PutNat v))+ PrettyFieldValue ('MkFieldI32) ('NegativeNat v) = ("hex" <:> (PutStr "-" <++> PutHex32 v)) <+> PrettyParens ("dec" <:> (PutStr "-" <++> PutNat v))+ PrettyFieldValue ('MkFieldI64) ('NegativeNat v) = ("hex" <:> (PutStr "-" <++> PutHex64 v)) <+> PrettyParens ("dec" <:> (PutStr "-" <++> PutNat v))+ PrettyFieldValue ('MkFieldCustom :: BitField rt ct size) v = PrettyCustomFieldValue rt ct size v++type family PrettyCustomFieldValue (rt :: Type) (st :: Type) (size :: Nat) (v :: st) :: PrettyType
+ src/Data/Type/BitRecords/Enum.hs view
@@ -0,0 +1,141 @@+{-# LANGUAGE UndecidableInstances #-}+module Data.Type.BitRecords.Enum where++import Data.Type.BitRecords.Core+import Data.Type.BitRecords.Builder.BitBuffer+import Data.Type.BitRecords.Builder.Holey+import Data.Type.BitRecords.Builder.LazyByteStringBuilder+import Data.Proxy+import Data.Word+import Data.Kind (Type)+import GHC.TypeLits+import Data.Kind.Extra+import Data.Type.Pretty++-- * BitRecordFields containing /enum/-like types++-- | Wrapper around a type that can be represented as a short number, indexing+-- the clauses of the (sum) type.+data EnumOf enum where+ MkEnumOf+ :: IsAn (EnumField enum size)+ -> IsA (FieldValue label enum)+ -> BitRecord+ -> EnumOf enum++type BitRecordOfEnum (e :: IsAn (EnumOf enum)) = (RenderEnumOf (Eval e) :: BitRecord)++type family RenderEnumOf (e :: EnumOf enum) :: BitRecord where+ RenderEnumOf ('MkEnumOf mainField mainFieldVal extra) =+ (BitRecordFieldOfEnumField mainField) :~ mainFieldVal .+: extra++-- | Physical representation of an 'EnumOf', this is an abstract type+data EnumField (enum :: Type) (size :: Nat)++type BitRecordFieldOfEnumField (x :: IsA (EnumField e s)) =+ MkField ('MkFieldCustom :: BitField (EnumValue e) e s)++-- | A fixed size 'EnumField'+data FixedEnum (enum :: Type) (size :: Nat) :: IsAn (EnumField enum size)++-- | An enum that can be extended with an additional 'BitRecordField', following+-- the regular enum field; the extension is optional, i.e. only if the+-- /regular/ field contains a special value (e.g. 0xff).+data ExtEnum (enum :: Type)+ (size :: Nat)+ (extInd :: enum)+ (extField :: IsA (BitRecordField (t :: BitField rt0 (st0 :: k0) len0)))+ :: IsAn (EnumField enum size)++-- | Create an 'EnumOf' that sets an enum to a static value.+data SetEnum (l :: Symbol) (ef :: IsAn (EnumField enum size)) (v :: enum) :: IsAn (EnumOf enum)++type instance Eval (SetEnum (l :: Symbol) (ei :: IsAn (EnumField enum size)) value) =+ 'MkEnumOf+ ei+ (StaticFieldValue l value)+ 'EmptyBitRecord++-- | Create an 'EnumOf' that sets the enum to a runtime value.+data EnumParam+ (label :: Symbol)+ (ef :: IsAn (EnumField (enum :: Type) (size :: Nat)))+ :: IsAn (EnumOf enum)+type instance Eval (EnumParam label (ei :: IsAn (EnumField enum size))) =+ 'MkEnumOf+ ei+ (RuntimeFieldValue label)+ 'EmptyBitRecord++-- | Create an 'EnumOf' that sets an extended enum to an extended static value.+data SetEnumAlt (l :: Symbol) (ef :: IsAn (EnumField (enum :: Type) (size :: Nat))) (v :: k)+ :: IsAn (EnumOf enum)++type instance Eval (SetEnumAlt (l :: Symbol) (ExtEnum enum size extInd extField) value) =+ -- TODO maybe enrich the demoteRep type of 'MkField??+ 'MkEnumOf+ (ExtEnum enum size extInd extField)+ (StaticFieldValue l extInd)+ ('BitRecordMember (extField := value))++type instance Eval (SetEnumAlt (l :: Symbol) (FixedEnum enum size) value) =+ TypeError ('Text "Cannot assign an 'extended' value to the 'FixedEnum' "+ ':<>: 'ShowType enum)++-- | Create an 'EnumOf' that sets the extended enum to a runtime value.+data EnumParamAlt+ (label :: Symbol)+ (ef :: IsAn (EnumField (enum :: Type) (size :: Nat)))+ :: IsAn (EnumOf enum)++type instance Eval (EnumParamAlt label (ExtEnum enum size extInd extField)) =+ 'MkEnumOf+ (ExtEnum enum size extInd extField)+ (StaticFieldValue label extInd)+ ('BitRecordMember (extField :~ RuntimeFieldValue label))++type instance Eval (EnumParamAlt label (FixedEnum enum size)) =+ TypeError ('Text "Cannot assign an extension value to the FixedEnum "+ ':<>: 'ShowType enum)++-- ** Composing BitRecords with enum fields++-- | Return the numeric /index/ of an entry in a table. This emulates 'fromEnum' a bit.+type family FromEnum enum (entry :: enum) :: Nat++-- | An enum value supplied at runtime.+data EnumValue e where+ MkEnumValue :: KnownNat (FromEnum e v) => Proxy (v :: e) -> EnumValue e++-- | Create an 'EnumValue' from a 'Proxy'. TODO remove?+enumValueProxy :: KnownNat (FromEnum e v) => Proxy (v :: e) -> EnumValue e+enumValueProxy = MkEnumValue++fromEnumValue :: EnumValue e -> Word64+fromEnumValue (MkEnumValue p) = enumValue p+ where+ enumValue :: forall proxy (v :: enum) . KnownNat (FromEnum enum v) => proxy v -> Word64+ enumValue _ = fromIntegral (natVal (Proxy @(FromEnum enum v)))++instance+ forall (size :: Nat) r e (v :: e) (f :: IsA (BitRecordField ('MkFieldCustom :: BitField (EnumValue e) e size))) .+ (KnownNat (FromEnum e v), KnownChunkSize size) =>+ BitStringBuilderHoley (Proxy (f := v)) r where+ bitStringBuilderHoley _ =+ immediate (appendBitString+ (bitStringProxyLength (Proxy @size)+ (fromIntegral (natVal (Proxy @(FromEnum e v))))))++instance+ forall (size :: Nat) r e .+ (KnownChunkSize size) =>+ BitStringBuilderHoley (Proxy (MkField ('MkFieldCustom :: BitField (EnumValue e) e size))) r+ where+ type ToBitStringBuilder (Proxy (MkField ('MkFieldCustom :: BitField (EnumValue e) e size))) r =+ EnumValue e -> r+ bitStringBuilderHoley _ =+ indirect (appendBitString . bitStringProxyLength (Proxy @size) . fromEnumValue)++type instance ToPretty (EnumValue e) = PutStr "<<enum>>"+type instance PrettyCustomFieldValue (EnumValue e) e size (v :: e) =+ PutNat (FromEnum e v) <+> ("hex" <:> PutHex (FromEnum e v)) <+> ("bin" <:> PutBits (FromEnum e v))
+ src/Data/Type/BitRecords/Sized.hs view
@@ -0,0 +1,73 @@+-- | Size Fields+{-# LANGUAGE UndecidableInstances #-}+module Data.Type.BitRecords.Sized+ ( type Sized, type Sized8, type Sized16, type Sized32, type Sized64+ , type SizedField, type SizedField8, type SizedField16, type SizedField32, type SizedField64+ , type SizeFieldValue)+ where++import Data.Type.Pretty+import Data.Type.BitRecords.Core+import Data.Word+import GHC.TypeLits+import Data.Kind.Extra+import Data.Kind (type Type)++-- | A record with a /size/ member, and a nested record that can be counted+-- using 'SizeFieldValue'.+data Sized+ (sf :: IsA (BitRecordField (t :: BitField (rt :: Type) Nat (size :: Nat))))+ (r :: BitRecord)+ :: IsA BitRecord+type instance Eval (Sized sf r) =+ PutStr "sized-record" #+$ ("size" @: sf := SizeFieldValue r .+: r)++-- | A convenient alias for a 'Sized' with an 'FieldU8' size field.+type Sized8 t = Sized FieldU8 t++-- | A convenient alias for a 'Sized' with an 'FieldU16' size field.+type Sized16 t = Sized FieldU16 t++-- | A convenient alias for a 'Sized' with an 'FieldU32' size field.+type Sized32 t = Sized FieldU32 t++-- | A convenient alias for a 'Sized' with an 'FieldU64' size field.+type Sized64 t = Sized FieldU64 t++-- | A record with a /size/ member, and a nested field that can be counted+-- using 'SizeFieldValue'.+data SizedField+ (sf :: IsA (BitRecordField (t :: BitField (rt :: Type) Nat (size :: Nat))))+ (r :: IsA (BitRecordField (u :: BitField (rt' :: Type) (st' :: k0) (len0 :: Nat))))+ :: IsA BitRecord+type instance Eval (SizedField sf r) =+ PutStr "sized-field" #+$ "size" @: sf := SizeFieldValue r .+. r++-- | A convenient alias for a 'SizedField' with an 'FieldU8' size field.+type SizedField8 t = SizedField FieldU8 t++-- | A convenient alias for a 'SizedField' with an 'FieldU16' size field.+type SizedField16 t = SizedField FieldU16 t++-- | A convenient alias for a 'SizedField' with an 'FieldU32' size field.+type SizedField32 t = SizedField FieldU32 t++-- | A convenient alias for a 'SizedField' with an 'FieldU64' size field.+type SizedField64 t = SizedField FieldU64 t++-- | For something to be augmented by a size field there must be an instance of+-- this family to generate the value of the size field, e.g. by counting the+-- elements.+type family SizeFieldValue (c :: k) :: Nat++type instance SizeFieldValue (b :: BitRecord) = BitRecordMemberCount b+type instance SizeFieldValue (f := v) = SizeFieldValue v+type instance SizeFieldValue (LabelF l f) = SizeFieldValue f+type instance SizeFieldValue (MkField (t :: BitField (rt:: Type) (st::k) (size::Nat))) = size++type family PrintHexIfPossible t (s :: Nat) :: PrettyType where+ PrintHexIfPossible Word64 s = PutHex64 s+ PrintHexIfPossible Word32 s = PutHex32 s+ PrintHexIfPossible Word16 s = PutHex16 s+ PrintHexIfPossible Word8 s = PutHex8 s+ PrintHexIfPossible x s = TypeError ('Text "Invalid size field type: " ':<>: 'ShowType x)
+ src/Data/Type/BitRecords/SizedString.hs view
@@ -0,0 +1,74 @@+{-# LANGUAGE UndecidableInstances #-}++module Data.Type.BitRecords.SizedString+ (SizedString()+ ,ASizedString()+ ,utf8)+ where++import Data.Type.BitRecords.Core+import Data.Type.BitRecords.Sized+import Data.Type.BitRecords.Builder.Holey+import Data.Type.BitRecords.Builder.LazyByteStringBuilder+import qualified Language.Haskell.TH as TH+import qualified Language.Haskell.TH.Quote as TH+import GHC.TypeLits+import Data.Type.Pretty+import qualified Data.ByteString as B+import qualified Data.Text as T+import qualified Data.Text.Encoding as E+import Data.Proxy+import Data.Kind (type Type)+import Data.Kind.Extra++-- TODO Refactor++-- * String Fields++-- | A type level symbol paired with a type level length, that determines how+-- many characters of the symbol may be used. The first parameter defines the+-- length field.+type SizedString str bytes =+ MkField ('MkFieldCustom :: BitField ASizedString ASizedString (8 * bytes)) := 'MkASizedString str bytes++data ASizedString where+ MkASizedString :: Symbol -> Nat -> ASizedString++type instance+ SizeFieldValue ('MkASizedString str byteCount) = byteCount++type instance+ ToPretty ASizedString = PutStr "utf-8"++type instance PrettyCustomFieldValue ASizedString ASizedString s sr =+ ToPretty sr++type instance+ ToPretty ('MkASizedString str byteCount) =+ PrettySurrounded (PutStr "<<") (PutStr ">>") (PutStr str)+ <+> PutStr "[" <++> PutNat byteCount <++> PutStr " Bytes]"++-- | Create a 'SizedString' from a utf-8 string+utf8 :: TH.QuasiQuoter+utf8 = TH.QuasiQuoter undefined undefined mkSizedStr undefined+ where mkSizedStr :: String -> TH.Q TH.Type+ mkSizedStr str =+ do let strT = TH.LitT (TH.StrTyLit str)+ byteCount =+ fromIntegral (B.length (E.encodeUtf8 (T.pack str)))+ byteCountT = TH.LitT (TH.NumTyLit byteCount)+ return $+ TH.PromotedT ''SizedString `TH.AppT` strT `TH.AppT` byteCountT++instance+ forall (size :: Nat)+ (str :: Symbol)+ (bytes :: Nat)+ (r :: Type)+ (f :: IsA (BitRecordField ('MkFieldCustom :: BitField ASizedString ASizedString size))) .+ (KnownSymbol str)+ => BitStringBuilderHoley (Proxy (f := 'MkASizedString str bytes)) r+ where+ bitStringBuilderHoley _ =+ immediate (appendStrictByteString+ (E.encodeUtf8 (T.pack (symbolVal (Proxy @str)))))
stack.yaml view
@@ -1,70 +1,12 @@-# This file was automatically generated by 'stack init'-#-# Some commonly used options have been documented as comments in this file.-# For advanced use and comprehensive documentation of the format, please see:-# http://docs.haskellstack.org/en/stable/yaml_configuration/--# Resolver to choose a 'specific' stackage snapshot or a compiler version.-# A snapshot resolver dictates the compiler version and the set of packages-# to be used for project dependencies. For example:-#-# resolver: lts-3.5-# resolver: nightly-2015-09-21-# resolver: ghc-7.10.2-# resolver: ghcjs-0.1.0_ghc-7.10.2-# resolver:-# name: custom-snapshot-# location: "./custom-snapshot.yaml"-resolver: nightly-2016-07-30+resolver: lts-7.5 -# User packages to be built.-# Various formats can be used as shown in the example below.-#-# packages:-# - some-directory-# - https://example.com/foo/bar/baz-0.0.2.tar.gz-# - location:-# git: https://github.com/commercialhaskell/stack.git-# commit: e7b331f14bcffb8367cd58fbfc8b40ec7642100a-# - location: https://github.com/commercialhaskell/stack/commit/e7b331f14bcffb8367cd58fbfc8b40ec7642100a-# extra-dep: true-# subdirs:-# - auto-update-# - wai-#-# A package marked 'extra-dep: true' will only be built if demanded by a-# non-dependency (i.e. a user package), and its test suites and benchmarks-# will not be run. This is useful for tweaking upstream packages. packages: - '.' -# Dependency packages to be pulled from upstream that are not in the resolver-# (e.g., acme-missiles-0.3) extra-deps:-- vector-sized-0.3.2.0-- show-type-0.1.1-- type-spec-0.2.0.0+- pretty-types-0.2.3.1+- type-spec-0.3.0.1 -# Override default flag values for local packages and extra-deps flags: {} -# Extra package databases containing global packages extra-package-dbs: []--# Control whether we use the GHC we find on the path-# system-ghc: true-#-# Require a specific version of stack, using version ranges-# require-stack-version: -any # Default-# require-stack-version: ">=1.1"-#-# Override the architecture used by stack, especially useful on Windows-# arch: i386-# arch: x86_64-#-# Extra directories used by stack for building-# extra-include-dirs: [/path/to/dir]-# extra-lib-dirs: [/path/to/dir]-#-# Allow a newer minor version of GHC than the snapshot specifies-# compiler-check: newer-minor