{- |
Copyright  : Will Thompson, Iñaki García Etxebarria and Jonas Platte
License    : LGPL-2.1
Maintainer : Iñaki García Etxebarria (inaki@blueleaf.cc)

The 'GI.Gst.Structs.Meta.Meta' structure should be included as the first member of a 'GI.Gst.Structs.Buffer.Buffer'
metadata structure. The structure defines the API of the metadata and should
be accessible to all elements using the metadata.

A metadata API is registered with 'GI.Gst.Functions.metaApiTypeRegister' which takes a
name for the metadata API and some tags associated with the metadata.
With 'GI.Gst.Functions.metaApiTypeHasTag' one can check if a certain metadata API
contains a given tag.

Multiple implementations of a metadata API can be registered.
To implement a metadata API, 'GI.Gst.Functions.metaRegister' should be used. This
function takes all parameters needed to create, free and transform metadata
along with the size of the metadata. The function returns a 'GI.Gst.Structs.MetaInfo.MetaInfo'
structure that contains the information for the implementation of the API.

A specific implementation can be retrieved by name with 'GI.Gst.Functions.metaGetInfo'.

See 'GI.Gst.Structs.Buffer.Buffer' for how the metadata can be added, retrieved and removed from
buffers.
-}

#define ENABLE_OVERLOADING (MIN_VERSION_haskell_gi_overloading(1,0,0) \
       && !defined(__HADDOCK_VERSION__))

module GI.Gst.Structs.Meta
    (

-- * Exported types
    Meta(..)                                ,
    newZeroMeta                             ,
    noMeta                                  ,


 -- * Methods
-- ** apiTypeGetTags #method:apiTypeGetTags#

    metaApiTypeGetTags                      ,


-- ** apiTypeHasTag #method:apiTypeHasTag#

    metaApiTypeHasTag                       ,


-- ** apiTypeRegister #method:apiTypeRegister#

    metaApiTypeRegister                     ,


-- ** compareSeqnum #method:compareSeqnum#

#if ENABLE_OVERLOADING
    MetaCompareSeqnumMethodInfo             ,
#endif
    metaCompareSeqnum                       ,


-- ** getInfo #method:getInfo#

    metaGetInfo                             ,


-- ** getSeqnum #method:getSeqnum#

#if ENABLE_OVERLOADING
    MetaGetSeqnumMethodInfo                 ,
#endif
    metaGetSeqnum                           ,


-- ** register #method:register#

    metaRegister                            ,




 -- * Properties
-- ** flags #attr:flags#
{- | extra flags for the metadata
-}
    getMetaFlags                            ,
#if ENABLE_OVERLOADING
    meta_flags                              ,
#endif
    setMetaFlags                            ,


-- ** info #attr:info#
{- | pointer to the 'GI.Gst.Structs.MetaInfo.MetaInfo'
-}
    clearMetaInfo                           ,
    getMetaInfo                             ,
#if ENABLE_OVERLOADING
    meta_info                               ,
#endif
    setMetaInfo                             ,




    ) where

import Data.GI.Base.ShortPrelude
import qualified Data.GI.Base.ShortPrelude as SP
import qualified Data.GI.Base.Overloading as O
import qualified Prelude as P

import qualified Data.GI.Base.Attributes as GI.Attributes
import qualified Data.GI.Base.ManagedPtr as B.ManagedPtr
import qualified Data.GI.Base.GClosure as B.GClosure
import qualified Data.GI.Base.GError as B.GError
import qualified Data.GI.Base.GVariant as B.GVariant
import qualified Data.GI.Base.GValue as B.GValue
import qualified Data.GI.Base.GParamSpec as B.GParamSpec
import qualified Data.GI.Base.CallStack as B.CallStack
import qualified Data.GI.Base.Properties as B.Properties
import qualified Data.Text as T
import qualified Data.ByteString.Char8 as B
import qualified Data.Map as Map
import qualified Foreign.Ptr as FP
import qualified GHC.OverloadedLabels as OL

import qualified GI.Gst.Callbacks as Gst.Callbacks
import {-# SOURCE #-} qualified GI.Gst.Flags as Gst.Flags
import {-# SOURCE #-} qualified GI.Gst.Structs.MetaInfo as Gst.MetaInfo

-- | Memory-managed wrapper type.
newtype Meta = Meta (ManagedPtr Meta)
instance WrappedPtr Meta where
    wrappedPtrCalloc = callocBytes 16
    wrappedPtrCopy = \p -> withManagedPtr p (copyBytes 16 >=> wrapPtr Meta)
    wrappedPtrFree = Just ptr_to_g_free

-- | Construct a `Meta` struct initialized to zero.
newZeroMeta :: MonadIO m => m Meta
newZeroMeta = liftIO $ wrappedPtrCalloc >>= wrapPtr Meta

instance tag ~ 'AttrSet => Constructible Meta tag where
    new _ attrs = do
        o <- newZeroMeta
        GI.Attributes.set o attrs
        return o


-- | A convenience alias for `Nothing` :: `Maybe` `Meta`.
noMeta :: Maybe Meta
noMeta = Nothing

{- |
Get the value of the “@flags@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' meta #flags
@
-}
getMetaFlags :: MonadIO m => Meta -> m [Gst.Flags.MetaFlags]
getMetaFlags s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 0) :: IO CUInt
    let val' = wordToGFlags val
    return val'

{- |
Set the value of the “@flags@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' meta [ #flags 'Data.GI.Base.Attributes.:=' value ]
@
-}
setMetaFlags :: MonadIO m => Meta -> [Gst.Flags.MetaFlags] -> m ()
setMetaFlags s val = liftIO $ withManagedPtr s $ \ptr -> do
    let val' = gflagsToWord val
    poke (ptr `plusPtr` 0) (val' :: CUInt)

#if ENABLE_OVERLOADING
data MetaFlagsFieldInfo
instance AttrInfo MetaFlagsFieldInfo where
    type AttrAllowedOps MetaFlagsFieldInfo = '[ 'AttrSet, 'AttrGet]
    type AttrSetTypeConstraint MetaFlagsFieldInfo = (~) [Gst.Flags.MetaFlags]
    type AttrBaseTypeConstraint MetaFlagsFieldInfo = (~) Meta
    type AttrGetType MetaFlagsFieldInfo = [Gst.Flags.MetaFlags]
    type AttrLabel MetaFlagsFieldInfo = "flags"
    type AttrOrigin MetaFlagsFieldInfo = Meta
    attrGet _ = getMetaFlags
    attrSet _ = setMetaFlags
    attrConstruct = undefined
    attrClear _ = undefined

meta_flags :: AttrLabelProxy "flags"
meta_flags = AttrLabelProxy

#endif


{- |
Get the value of the “@info@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.get' meta #info
@
-}
getMetaInfo :: MonadIO m => Meta -> m (Maybe Gst.MetaInfo.MetaInfo)
getMetaInfo s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 8) :: IO (Ptr Gst.MetaInfo.MetaInfo)
    result <- SP.convertIfNonNull val $ \val' -> do
        val'' <- (newPtr Gst.MetaInfo.MetaInfo) val'
        return val''
    return result

{- |
Set the value of the “@info@” field.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.set' meta [ #info 'Data.GI.Base.Attributes.:=' value ]
@
-}
setMetaInfo :: MonadIO m => Meta -> Ptr Gst.MetaInfo.MetaInfo -> m ()
setMetaInfo s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 8) (val :: Ptr Gst.MetaInfo.MetaInfo)

{- |
Set the value of the “@info@” field to `Nothing`.
When <https://github.com/haskell-gi/haskell-gi/wiki/Overloading overloading> is enabled, this is equivalent to

@
'Data.GI.Base.Attributes.clear' #info
@
-}
clearMetaInfo :: MonadIO m => Meta -> m ()
clearMetaInfo s = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 8) (FP.nullPtr :: Ptr Gst.MetaInfo.MetaInfo)

#if ENABLE_OVERLOADING
data MetaInfoFieldInfo
instance AttrInfo MetaInfoFieldInfo where
    type AttrAllowedOps MetaInfoFieldInfo = '[ 'AttrSet, 'AttrGet, 'AttrClear]
    type AttrSetTypeConstraint MetaInfoFieldInfo = (~) (Ptr Gst.MetaInfo.MetaInfo)
    type AttrBaseTypeConstraint MetaInfoFieldInfo = (~) Meta
    type AttrGetType MetaInfoFieldInfo = Maybe Gst.MetaInfo.MetaInfo
    type AttrLabel MetaInfoFieldInfo = "info"
    type AttrOrigin MetaInfoFieldInfo = Meta
    attrGet _ = getMetaInfo
    attrSet _ = setMetaInfo
    attrConstruct = undefined
    attrClear _ = clearMetaInfo

meta_info :: AttrLabelProxy "info"
meta_info = AttrLabelProxy

#endif



#if ENABLE_OVERLOADING
instance O.HasAttributeList Meta
type instance O.AttributeList Meta = MetaAttributeList
type MetaAttributeList = ('[ '("flags", MetaFlagsFieldInfo), '("info", MetaInfoFieldInfo)] :: [(Symbol, *)])
#endif

-- method Meta::compare_seqnum
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "meta1", argType = TInterface (Name {namespace = "Gst", name = "Meta"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GstMeta", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "meta2", argType = TInterface (Name {namespace = "Gst", name = "Meta"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GstMeta", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TBasicType TInt)
-- throws : False
-- Skip return : False

foreign import ccall "gst_meta_compare_seqnum" gst_meta_compare_seqnum ::
    Ptr Meta ->                             -- meta1 : TInterface (Name {namespace = "Gst", name = "Meta"})
    Ptr Meta ->                             -- meta2 : TInterface (Name {namespace = "Gst", name = "Meta"})
    IO Int32

{- |
Meta sequence number compare function. Can be used as 'GI.GLib.Callbacks.CompareFunc'
or a 'GI.GLib.Callbacks.CompareDataFunc'.

/Since: 1.16/
-}
metaCompareSeqnum ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Meta
    {- ^ /@meta1@/: a 'GI.Gst.Structs.Meta.Meta' -}
    -> Meta
    {- ^ /@meta2@/: a 'GI.Gst.Structs.Meta.Meta' -}
    -> m Int32
    {- ^ __Returns:__ a negative number if /@meta1@/ comes before /@meta2@/, 0 if both metas
  have an equal sequence number, or a positive integer if /@meta1@/ comes
  after /@meta2@/. -}
metaCompareSeqnum meta1 meta2 = liftIO $ do
    meta1' <- unsafeManagedPtrGetPtr meta1
    meta2' <- unsafeManagedPtrGetPtr meta2
    result <- gst_meta_compare_seqnum meta1' meta2'
    touchManagedPtr meta1
    touchManagedPtr meta2
    return result

#if ENABLE_OVERLOADING
data MetaCompareSeqnumMethodInfo
instance (signature ~ (Meta -> m Int32), MonadIO m) => O.MethodInfo MetaCompareSeqnumMethodInfo Meta signature where
    overloadedMethod _ = metaCompareSeqnum

#endif

-- method Meta::get_seqnum
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "meta", argType = TInterface (Name {namespace = "Gst", name = "Meta"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GstMeta", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TBasicType TUInt64)
-- throws : False
-- Skip return : False

foreign import ccall "gst_meta_get_seqnum" gst_meta_get_seqnum ::
    Ptr Meta ->                             -- meta : TInterface (Name {namespace = "Gst", name = "Meta"})
    IO Word64

{- |
Gets seqnum for this meta.

/Since: 1.16/
-}
metaGetSeqnum ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    Meta
    {- ^ /@meta@/: a 'GI.Gst.Structs.Meta.Meta' -}
    -> m Word64
metaGetSeqnum meta = liftIO $ do
    meta' <- unsafeManagedPtrGetPtr meta
    result <- gst_meta_get_seqnum meta'
    touchManagedPtr meta
    return result

#if ENABLE_OVERLOADING
data MetaGetSeqnumMethodInfo
instance (signature ~ (m Word64), MonadIO m) => O.MethodInfo MetaGetSeqnumMethodInfo Meta signature where
    overloadedMethod _ = metaGetSeqnum

#endif

-- method Meta::api_type_get_tags
-- method type : MemberFunction
-- Args : [Arg {argCName = "api", argType = TBasicType TGType, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "an API", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TCArray True (-1) (-1) (TBasicType TUTF8))
-- throws : False
-- Skip return : False

foreign import ccall "gst_meta_api_type_get_tags" gst_meta_api_type_get_tags ::
    CGType ->                               -- api : TBasicType TGType
    IO (Ptr CString)

{- |
/No description available in the introspection data./

/Since: 1.2/
-}
metaApiTypeGetTags ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    GType
    {- ^ /@api@/: an API -}
    -> m [T.Text]
    {- ^ __Returns:__ an array of tags as strings. -}
metaApiTypeGetTags api = liftIO $ do
    let api' = gtypeToCGType api
    result <- gst_meta_api_type_get_tags api'
    checkUnexpectedReturnNULL "metaApiTypeGetTags" result
    result' <- unpackZeroTerminatedUTF8CArray result
    return result'

#if ENABLE_OVERLOADING
#endif

-- method Meta::api_type_has_tag
-- method type : MemberFunction
-- Args : [Arg {argCName = "api", argType = TBasicType TGType, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "an API", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "tag", argType = TBasicType TUInt32, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the tag to check", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TBasicType TBoolean)
-- throws : False
-- Skip return : False

foreign import ccall "gst_meta_api_type_has_tag" gst_meta_api_type_has_tag ::
    CGType ->                               -- api : TBasicType TGType
    Word32 ->                               -- tag : TBasicType TUInt32
    IO CInt

{- |
Check if /@api@/ was registered with /@tag@/.
-}
metaApiTypeHasTag ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    GType
    {- ^ /@api@/: an API -}
    -> Word32
    {- ^ /@tag@/: the tag to check -}
    -> m Bool
    {- ^ __Returns:__ 'True' if /@api@/ was registered with /@tag@/. -}
metaApiTypeHasTag api tag = liftIO $ do
    let api' = gtypeToCGType api
    result <- gst_meta_api_type_has_tag api' tag
    let result' = (/= 0) result
    return result'

#if ENABLE_OVERLOADING
#endif

-- method Meta::api_type_register
-- method type : MemberFunction
-- Args : [Arg {argCName = "api", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "an API to register", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "tags", argType = TCArray True (-1) (-1) (TBasicType TUTF8), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "tags for @api", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TBasicType TGType)
-- throws : False
-- Skip return : False

foreign import ccall "gst_meta_api_type_register" gst_meta_api_type_register ::
    CString ->                              -- api : TBasicType TUTF8
    Ptr CString ->                          -- tags : TCArray True (-1) (-1) (TBasicType TUTF8)
    IO CGType

{- |
Register and return a GType for the /@api@/ and associate it with
/@tags@/.
-}
metaApiTypeRegister ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    T.Text
    {- ^ /@api@/: an API to register -}
    -> [T.Text]
    {- ^ /@tags@/: tags for /@api@/ -}
    -> m GType
    {- ^ __Returns:__ a unique GType for /@api@/. -}
metaApiTypeRegister api tags = liftIO $ do
    api' <- textToCString api
    tags' <- packZeroTerminatedUTF8CArray tags
    result <- gst_meta_api_type_register api' tags'
    let result' = GType result
    freeMem api'
    mapZeroTerminatedCArray freeMem tags'
    freeMem tags'
    return result'

#if ENABLE_OVERLOADING
#endif

-- method Meta::get_info
-- method type : MemberFunction
-- Args : [Arg {argCName = "impl", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the name", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "Gst", name = "MetaInfo"}))
-- throws : False
-- Skip return : False

foreign import ccall "gst_meta_get_info" gst_meta_get_info ::
    CString ->                              -- impl : TBasicType TUTF8
    IO (Ptr Gst.MetaInfo.MetaInfo)

{- |
Lookup a previously registered meta info structure by its implementation name
/@impl@/.
-}
metaGetInfo ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    T.Text
    {- ^ /@impl@/: the name -}
    -> m (Maybe Gst.MetaInfo.MetaInfo)
    {- ^ __Returns:__ a 'GI.Gst.Structs.MetaInfo.MetaInfo' with /@impl@/, or
'Nothing' when no such metainfo exists. -}
metaGetInfo impl = liftIO $ do
    impl' <- textToCString impl
    result <- gst_meta_get_info impl'
    maybeResult <- convertIfNonNull result $ \result' -> do
        result'' <- (newPtr Gst.MetaInfo.MetaInfo) result'
        return result''
    freeMem impl'
    return maybeResult

#if ENABLE_OVERLOADING
#endif

-- method Meta::register
-- method type : MemberFunction
-- Args : [Arg {argCName = "api", argType = TBasicType TGType, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the type of the #GstMeta API", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "impl", argType = TBasicType TUTF8, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the name of the #GstMeta implementation", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "size", argType = TBasicType TUInt64, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the size of the #GstMeta structure", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "init_func", argType = TInterface (Name {namespace = "Gst", name = "MetaInitFunction"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GstMetaInitFunction", sinceVersion = Nothing}, argScope = ScopeTypeAsync, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "free_func", argType = TInterface (Name {namespace = "Gst", name = "MetaFreeFunction"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GstMetaFreeFunction", sinceVersion = Nothing}, argScope = ScopeTypeAsync, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "transform_func", argType = TInterface (Name {namespace = "Gst", name = "MetaTransformFunction"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GstMetaTransformFunction", sinceVersion = Nothing}, argScope = ScopeTypeAsync, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Just (TInterface (Name {namespace = "Gst", name = "MetaInfo"}))
-- throws : False
-- Skip return : False

foreign import ccall "gst_meta_register" gst_meta_register ::
    CGType ->                               -- api : TBasicType TGType
    CString ->                              -- impl : TBasicType TUTF8
    Word64 ->                               -- size : TBasicType TUInt64
    FunPtr Gst.Callbacks.C_MetaInitFunction -> -- init_func : TInterface (Name {namespace = "Gst", name = "MetaInitFunction"})
    FunPtr Gst.Callbacks.C_MetaFreeFunction -> -- free_func : TInterface (Name {namespace = "Gst", name = "MetaFreeFunction"})
    FunPtr Gst.Callbacks.C_MetaTransformFunction -> -- transform_func : TInterface (Name {namespace = "Gst", name = "MetaTransformFunction"})
    IO (Ptr Gst.MetaInfo.MetaInfo)

{- |
Register a new 'GI.Gst.Structs.Meta.Meta' implementation.

The same /@info@/ can be retrieved later with 'GI.Gst.Functions.metaGetInfo' by using
/@impl@/ as the key.
-}
metaRegister ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    GType
    {- ^ /@api@/: the type of the 'GI.Gst.Structs.Meta.Meta' API -}
    -> T.Text
    {- ^ /@impl@/: the name of the 'GI.Gst.Structs.Meta.Meta' implementation -}
    -> Word64
    {- ^ /@size@/: the size of the 'GI.Gst.Structs.Meta.Meta' structure -}
    -> Gst.Callbacks.MetaInitFunction
    {- ^ /@initFunc@/: a 'GI.Gst.Callbacks.MetaInitFunction' -}
    -> Gst.Callbacks.MetaFreeFunction
    {- ^ /@freeFunc@/: a 'GI.Gst.Callbacks.MetaFreeFunction' -}
    -> Gst.Callbacks.MetaTransformFunction
    {- ^ /@transformFunc@/: a 'GI.Gst.Callbacks.MetaTransformFunction' -}
    -> m (Maybe Gst.MetaInfo.MetaInfo)
    {- ^ __Returns:__ a 'GI.Gst.Structs.MetaInfo.MetaInfo' that can be used to
access metadata. -}
metaRegister api impl size initFunc freeFunc transformFunc = liftIO $ do
    let api' = gtypeToCGType api
    impl' <- textToCString impl
    ptrinitFunc <- callocMem :: IO (Ptr (FunPtr Gst.Callbacks.C_MetaInitFunction))
    initFunc' <- Gst.Callbacks.mk_MetaInitFunction (Gst.Callbacks.wrap_MetaInitFunction (Just ptrinitFunc) initFunc)
    poke ptrinitFunc initFunc'
    ptrfreeFunc <- callocMem :: IO (Ptr (FunPtr Gst.Callbacks.C_MetaFreeFunction))
    freeFunc' <- Gst.Callbacks.mk_MetaFreeFunction (Gst.Callbacks.wrap_MetaFreeFunction (Just ptrfreeFunc) freeFunc)
    poke ptrfreeFunc freeFunc'
    ptrtransformFunc <- callocMem :: IO (Ptr (FunPtr Gst.Callbacks.C_MetaTransformFunction))
    transformFunc' <- Gst.Callbacks.mk_MetaTransformFunction (Gst.Callbacks.wrap_MetaTransformFunction (Just ptrtransformFunc) transformFunc)
    poke ptrtransformFunc transformFunc'
    result <- gst_meta_register api' impl' size initFunc' freeFunc' transformFunc'
    maybeResult <- convertIfNonNull result $ \result' -> do
        result'' <- (newPtr Gst.MetaInfo.MetaInfo) result'
        return result''
    freeMem impl'
    return maybeResult

#if ENABLE_OVERLOADING
#endif

#if ENABLE_OVERLOADING
type family ResolveMetaMethod (t :: Symbol) (o :: *) :: * where
    ResolveMetaMethod "compareSeqnum" o = MetaCompareSeqnumMethodInfo
    ResolveMetaMethod "getSeqnum" o = MetaGetSeqnumMethodInfo
    ResolveMetaMethod l o = O.MethodResolutionFailed l o

instance (info ~ ResolveMetaMethod t Meta, O.MethodInfo info Meta p) => OL.IsLabel t (Meta -> p) where
#if MIN_VERSION_base(4,10,0)
    fromLabel = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)
#else
    fromLabel _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)
#endif

#endif