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

A video frame obtained from 'GI.GstVideo.Structs.VideoFrame.videoFrameMap'
-}

module GI.GstVideo.Structs.VideoFrame
    ( 

-- * Exported types
    VideoFrame(..)                          ,
    newZeroVideoFrame                       ,
    noVideoFrame                            ,


 -- * Methods
-- ** copy #method:copy#
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    VideoFrameCopyMethodInfo                ,
#endif
    videoFrameCopy                          ,


-- ** copyPlane #method:copyPlane#
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    VideoFrameCopyPlaneMethodInfo           ,
#endif
    videoFrameCopyPlane                     ,


-- ** map #method:map#
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    VideoFrameMapMethodInfo                 ,
#endif
    videoFrameMap                           ,


-- ** mapId #method:mapId#
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    VideoFrameMapIdMethodInfo               ,
#endif
    videoFrameMapId                         ,


-- ** unmap #method:unmap#
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    VideoFrameUnmapMethodInfo               ,
#endif
    videoFrameUnmap                         ,




 -- * Properties
-- ** buffer #attr:buffer#
    clearVideoFrameBuffer                   ,
    getVideoFrameBuffer                     ,
    setVideoFrameBuffer                     ,
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    videoFrame_buffer                       ,
#endif


-- ** flags #attr:flags#
    getVideoFrameFlags                      ,
    setVideoFrameFlags                      ,
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    videoFrame_flags                        ,
#endif


-- ** id #attr:id#
    getVideoFrameId                         ,
    setVideoFrameId                         ,
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    videoFrame_id                           ,
#endif


-- ** info #attr:info#
    getVideoFrameInfo                       ,
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    videoFrame_info                         ,
#endif


-- ** meta #attr:meta#
    clearVideoFrameMeta                     ,
    getVideoFrameMeta                       ,
    setVideoFrameMeta                       ,
#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
    videoFrame_meta                         ,
#endif




    ) 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.GError as B.GError
import qualified Data.GI.Base.GVariant as B.GVariant
import qualified Data.GI.Base.GParamSpec as B.GParamSpec
import qualified Data.GI.Base.CallStack as B.CallStack
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 GI.Gst.Flags as Gst.Flags
import qualified GI.Gst.Structs.Buffer as Gst.Buffer
import {-# SOURCE #-} qualified GI.GstVideo.Flags as GstVideo.Flags
import {-# SOURCE #-} qualified GI.GstVideo.Structs.VideoInfo as GstVideo.VideoInfo

newtype VideoFrame = VideoFrame (ManagedPtr VideoFrame)
instance WrappedPtr VideoFrame where
    wrappedPtrCalloc = callocBytes 632
    wrappedPtrCopy = \p -> withManagedPtr p (copyBytes 632 >=> wrapPtr VideoFrame)
    wrappedPtrFree = Just ptr_to_g_free

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

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


noVideoFrame :: Maybe VideoFrame
noVideoFrame = Nothing

getVideoFrameInfo :: MonadIO m => VideoFrame -> m GstVideo.VideoInfo.VideoInfo
getVideoFrameInfo s = liftIO $ withManagedPtr s $ \ptr -> do
    let val = ptr `plusPtr` 0 :: (Ptr GstVideo.VideoInfo.VideoInfo)
    val' <- (newBoxed GstVideo.VideoInfo.VideoInfo) val
    return val'

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
data VideoFrameInfoFieldInfo
instance AttrInfo VideoFrameInfoFieldInfo where
    type AttrAllowedOps VideoFrameInfoFieldInfo = '[ 'AttrGet]
    type AttrSetTypeConstraint VideoFrameInfoFieldInfo = (~) (Ptr GstVideo.VideoInfo.VideoInfo)
    type AttrBaseTypeConstraint VideoFrameInfoFieldInfo = (~) VideoFrame
    type AttrGetType VideoFrameInfoFieldInfo = GstVideo.VideoInfo.VideoInfo
    type AttrLabel VideoFrameInfoFieldInfo = "info"
    type AttrOrigin VideoFrameInfoFieldInfo = VideoFrame
    attrGet _ = getVideoFrameInfo
    attrSet _ = undefined
    attrConstruct = undefined
    attrClear _ = undefined

videoFrame_info :: AttrLabelProxy "info"
videoFrame_info = AttrLabelProxy

#endif


getVideoFrameFlags :: MonadIO m => VideoFrame -> m [GstVideo.Flags.VideoFrameFlags]
getVideoFrameFlags s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 120) :: IO CUInt
    let val' = wordToGFlags val
    return val'

setVideoFrameFlags :: MonadIO m => VideoFrame -> [GstVideo.Flags.VideoFrameFlags] -> m ()
setVideoFrameFlags s val = liftIO $ withManagedPtr s $ \ptr -> do
    let val' = gflagsToWord val
    poke (ptr `plusPtr` 120) (val' :: CUInt)

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
data VideoFrameFlagsFieldInfo
instance AttrInfo VideoFrameFlagsFieldInfo where
    type AttrAllowedOps VideoFrameFlagsFieldInfo = '[ 'AttrSet, 'AttrGet]
    type AttrSetTypeConstraint VideoFrameFlagsFieldInfo = (~) [GstVideo.Flags.VideoFrameFlags]
    type AttrBaseTypeConstraint VideoFrameFlagsFieldInfo = (~) VideoFrame
    type AttrGetType VideoFrameFlagsFieldInfo = [GstVideo.Flags.VideoFrameFlags]
    type AttrLabel VideoFrameFlagsFieldInfo = "flags"
    type AttrOrigin VideoFrameFlagsFieldInfo = VideoFrame
    attrGet _ = getVideoFrameFlags
    attrSet _ = setVideoFrameFlags
    attrConstruct = undefined
    attrClear _ = undefined

videoFrame_flags :: AttrLabelProxy "flags"
videoFrame_flags = AttrLabelProxy

#endif


getVideoFrameBuffer :: MonadIO m => VideoFrame -> m (Maybe Gst.Buffer.Buffer)
getVideoFrameBuffer s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 128) :: IO (Ptr Gst.Buffer.Buffer)
    result <- SP.convertIfNonNull val $ \val' -> do
        val'' <- (newBoxed Gst.Buffer.Buffer) val'
        return val''
    return result

setVideoFrameBuffer :: MonadIO m => VideoFrame -> Ptr Gst.Buffer.Buffer -> m ()
setVideoFrameBuffer s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 128) (val :: Ptr Gst.Buffer.Buffer)

clearVideoFrameBuffer :: MonadIO m => VideoFrame -> m ()
clearVideoFrameBuffer s = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 128) (FP.nullPtr :: Ptr Gst.Buffer.Buffer)

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
data VideoFrameBufferFieldInfo
instance AttrInfo VideoFrameBufferFieldInfo where
    type AttrAllowedOps VideoFrameBufferFieldInfo = '[ 'AttrSet, 'AttrGet, 'AttrClear]
    type AttrSetTypeConstraint VideoFrameBufferFieldInfo = (~) (Ptr Gst.Buffer.Buffer)
    type AttrBaseTypeConstraint VideoFrameBufferFieldInfo = (~) VideoFrame
    type AttrGetType VideoFrameBufferFieldInfo = Maybe Gst.Buffer.Buffer
    type AttrLabel VideoFrameBufferFieldInfo = "buffer"
    type AttrOrigin VideoFrameBufferFieldInfo = VideoFrame
    attrGet _ = getVideoFrameBuffer
    attrSet _ = setVideoFrameBuffer
    attrConstruct = undefined
    attrClear _ = clearVideoFrameBuffer

videoFrame_buffer :: AttrLabelProxy "buffer"
videoFrame_buffer = AttrLabelProxy

#endif


getVideoFrameMeta :: MonadIO m => VideoFrame -> m (Ptr ())
getVideoFrameMeta s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 136) :: IO (Ptr ())
    return val

setVideoFrameMeta :: MonadIO m => VideoFrame -> Ptr () -> m ()
setVideoFrameMeta s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 136) (val :: Ptr ())

clearVideoFrameMeta :: MonadIO m => VideoFrame -> m ()
clearVideoFrameMeta s = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 136) (FP.nullPtr :: Ptr ())

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
data VideoFrameMetaFieldInfo
instance AttrInfo VideoFrameMetaFieldInfo where
    type AttrAllowedOps VideoFrameMetaFieldInfo = '[ 'AttrSet, 'AttrGet, 'AttrClear]
    type AttrSetTypeConstraint VideoFrameMetaFieldInfo = (~) (Ptr ())
    type AttrBaseTypeConstraint VideoFrameMetaFieldInfo = (~) VideoFrame
    type AttrGetType VideoFrameMetaFieldInfo = Ptr ()
    type AttrLabel VideoFrameMetaFieldInfo = "meta"
    type AttrOrigin VideoFrameMetaFieldInfo = VideoFrame
    attrGet _ = getVideoFrameMeta
    attrSet _ = setVideoFrameMeta
    attrConstruct = undefined
    attrClear _ = clearVideoFrameMeta

videoFrame_meta :: AttrLabelProxy "meta"
videoFrame_meta = AttrLabelProxy

#endif


getVideoFrameId :: MonadIO m => VideoFrame -> m Int32
getVideoFrameId s = liftIO $ withManagedPtr s $ \ptr -> do
    val <- peek (ptr `plusPtr` 144) :: IO Int32
    return val

setVideoFrameId :: MonadIO m => VideoFrame -> Int32 -> m ()
setVideoFrameId s val = liftIO $ withManagedPtr s $ \ptr -> do
    poke (ptr `plusPtr` 144) (val :: Int32)

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
data VideoFrameIdFieldInfo
instance AttrInfo VideoFrameIdFieldInfo where
    type AttrAllowedOps VideoFrameIdFieldInfo = '[ 'AttrSet, 'AttrGet]
    type AttrSetTypeConstraint VideoFrameIdFieldInfo = (~) Int32
    type AttrBaseTypeConstraint VideoFrameIdFieldInfo = (~) VideoFrame
    type AttrGetType VideoFrameIdFieldInfo = Int32
    type AttrLabel VideoFrameIdFieldInfo = "id"
    type AttrOrigin VideoFrameIdFieldInfo = VideoFrame
    attrGet _ = getVideoFrameId
    attrSet _ = setVideoFrameId
    attrConstruct = undefined
    attrClear _ = undefined

videoFrame_id :: AttrLabelProxy "id"
videoFrame_id = AttrLabelProxy

#endif


-- XXX Skipped attribute for "VideoFrame:data" :: Not implemented: "Don't know how to unpack C array of type TCArray False 4 (-1) (TBasicType TPtr)"
-- XXX Skipped attribute for "VideoFrame:map" :: Not implemented: "Don't know how to unpack C array of type TCArray False 4 (-1) (TInterface (Name {namespace = \"Gst\", name = \"MapInfo\"}))"

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
instance O.HasAttributeList VideoFrame
type instance O.AttributeList VideoFrame = VideoFrameAttributeList
type VideoFrameAttributeList = ('[ '("info", VideoFrameInfoFieldInfo), '("flags", VideoFrameFlagsFieldInfo), '("buffer", VideoFrameBufferFieldInfo), '("meta", VideoFrameMetaFieldInfo), '("id", VideoFrameIdFieldInfo)] :: [(Symbol, *)])
#endif

-- method VideoFrame::copy
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "dest", argType = TInterface (Name {namespace = "GstVideo", name = "VideoFrame"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GstVideoFrame", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "src", argType = TInterface (Name {namespace = "GstVideo", name = "VideoFrame"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GstVideoFrame", 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_video_frame_copy" gst_video_frame_copy :: 
    Ptr VideoFrame ->                       -- dest : TInterface (Name {namespace = "GstVideo", name = "VideoFrame"})
    Ptr VideoFrame ->                       -- src : TInterface (Name {namespace = "GstVideo", name = "VideoFrame"})
    IO CInt

{- |
Copy the contents from /@src@/ to /@dest@/.
-}
videoFrameCopy ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    VideoFrame
    {- ^ /@dest@/: a 'GI.GstVideo.Structs.VideoFrame.VideoFrame' -}
    -> VideoFrame
    {- ^ /@src@/: a 'GI.GstVideo.Structs.VideoFrame.VideoFrame' -}
    -> m Bool
    {- ^ __Returns:__ TRUE if the contents could be copied. -}
videoFrameCopy dest src = liftIO $ do
    dest' <- unsafeManagedPtrGetPtr dest
    src' <- unsafeManagedPtrGetPtr src
    result <- gst_video_frame_copy dest' src'
    let result' = (/= 0) result
    touchManagedPtr dest
    touchManagedPtr src
    return result'

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
data VideoFrameCopyMethodInfo
instance (signature ~ (VideoFrame -> m Bool), MonadIO m) => O.MethodInfo VideoFrameCopyMethodInfo VideoFrame signature where
    overloadedMethod _ = videoFrameCopy

#endif

-- method VideoFrame::copy_plane
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "dest", argType = TInterface (Name {namespace = "GstVideo", name = "VideoFrame"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GstVideoFrame", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "src", argType = TInterface (Name {namespace = "GstVideo", name = "VideoFrame"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GstVideoFrame", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "plane", argType = TBasicType TUInt, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a plane", 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_video_frame_copy_plane" gst_video_frame_copy_plane :: 
    Ptr VideoFrame ->                       -- dest : TInterface (Name {namespace = "GstVideo", name = "VideoFrame"})
    Ptr VideoFrame ->                       -- src : TInterface (Name {namespace = "GstVideo", name = "VideoFrame"})
    Word32 ->                               -- plane : TBasicType TUInt
    IO CInt

{- |
Copy the plane with index /@plane@/ from /@src@/ to /@dest@/.
-}
videoFrameCopyPlane ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    VideoFrame
    {- ^ /@dest@/: a 'GI.GstVideo.Structs.VideoFrame.VideoFrame' -}
    -> VideoFrame
    {- ^ /@src@/: a 'GI.GstVideo.Structs.VideoFrame.VideoFrame' -}
    -> Word32
    {- ^ /@plane@/: a plane -}
    -> m Bool
    {- ^ __Returns:__ TRUE if the contents could be copied. -}
videoFrameCopyPlane dest src plane = liftIO $ do
    dest' <- unsafeManagedPtrGetPtr dest
    src' <- unsafeManagedPtrGetPtr src
    result <- gst_video_frame_copy_plane dest' src' plane
    let result' = (/= 0) result
    touchManagedPtr dest
    touchManagedPtr src
    return result'

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
data VideoFrameCopyPlaneMethodInfo
instance (signature ~ (VideoFrame -> Word32 -> m Bool), MonadIO m) => O.MethodInfo VideoFrameCopyPlaneMethodInfo VideoFrame signature where
    overloadedMethod _ = videoFrameCopyPlane

#endif

-- method VideoFrame::map
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "frame", argType = TInterface (Name {namespace = "GstVideo", name = "VideoFrame"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "pointer to #GstVideoFrame", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "info", argType = TInterface (Name {namespace = "GstVideo", name = "VideoInfo"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GstVideoInfo", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "buffer", argType = TInterface (Name {namespace = "Gst", name = "Buffer"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the buffer to map", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "flags", argType = TInterface (Name {namespace = "Gst", name = "MapFlags"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "#GstMapFlags", 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_video_frame_map" gst_video_frame_map :: 
    Ptr VideoFrame ->                       -- frame : TInterface (Name {namespace = "GstVideo", name = "VideoFrame"})
    Ptr GstVideo.VideoInfo.VideoInfo ->     -- info : TInterface (Name {namespace = "GstVideo", name = "VideoInfo"})
    Ptr Gst.Buffer.Buffer ->                -- buffer : TInterface (Name {namespace = "Gst", name = "Buffer"})
    CUInt ->                                -- flags : TInterface (Name {namespace = "Gst", name = "MapFlags"})
    IO CInt

{- |
Use /@info@/ and /@buffer@/ to fill in the values of /@frame@/. /@frame@/ is usually
allocated on the stack, and you will pass the address to the 'GI.GstVideo.Structs.VideoFrame.VideoFrame'
structure allocated on the stack; 'GI.GstVideo.Structs.VideoFrame.videoFrameMap' will then fill in
the structures with the various video-specific information you need to access
the pixels of the video buffer. You can then use accessor macros such as
@/GST_VIDEO_FRAME_COMP_DATA()/@, @/GST_VIDEO_FRAME_PLANE_DATA()/@,
@/GST_VIDEO_FRAME_COMP_STRIDE()/@, @/GST_VIDEO_FRAME_PLANE_STRIDE()/@ etc.
to get to the pixels.


=== /C code/
>
>  GstVideoFrame vframe;
>  ...
>  // set RGB pixels to black one at a time
>  if (gst_video_frame_map (&amp;vframe, video_info, video_buffer, GST_MAP_WRITE)) {
>    guint8 *pixels = GST_VIDEO_FRAME_PLANE_DATA (vframe, 0);
>    guint stride = GST_VIDEO_FRAME_PLANE_STRIDE (vframe, 0);
>    guint pixel_stride = GST_VIDEO_FRAME_COMP_PSTRIDE (vframe, 0);
>
>    for (h = 0; h < height; ++h) {
>      for (w = 0; w < width; ++w) {
>        guint8 *pixel = pixels + h * stride + w * pixel_stride;
>
>        memset (pixel, 0, pixel_stride);
>      }
>    }
>
>    gst_video_frame_unmap (&amp;vframe);
>  }
>  ...


All video planes of /@buffer@/ will be mapped and the pointers will be set in
/@frame@/->data.

The purpose of this function is to make it easy for you to get to the video
pixels in a generic way, without you having to worry too much about details
such as whether the video data is allocated in one contiguous memory chunk
or multiple memory chunks (e.g. one for each plane); or if custom strides
and custom plane offsets are used or not (as signalled by GstVideoMeta on
each buffer). This function will just fill the 'GI.GstVideo.Structs.VideoFrame.VideoFrame' structure
with the right values and if you use the accessor macros everything will
just work and you can access the data easily. It also maps the underlying
memory chunks for you.
-}
videoFrameMap ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    VideoFrame
    {- ^ /@frame@/: pointer to 'GI.GstVideo.Structs.VideoFrame.VideoFrame' -}
    -> GstVideo.VideoInfo.VideoInfo
    {- ^ /@info@/: a 'GI.GstVideo.Structs.VideoInfo.VideoInfo' -}
    -> Gst.Buffer.Buffer
    {- ^ /@buffer@/: the buffer to map -}
    -> [Gst.Flags.MapFlags]
    {- ^ /@flags@/: 'GI.Gst.Flags.MapFlags' -}
    -> m Bool
    {- ^ __Returns:__ 'True' on success. -}
videoFrameMap frame info buffer flags = liftIO $ do
    frame' <- unsafeManagedPtrGetPtr frame
    info' <- unsafeManagedPtrGetPtr info
    buffer' <- unsafeManagedPtrGetPtr buffer
    let flags' = gflagsToWord flags
    result <- gst_video_frame_map frame' info' buffer' flags'
    let result' = (/= 0) result
    touchManagedPtr frame
    touchManagedPtr info
    touchManagedPtr buffer
    return result'

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
data VideoFrameMapMethodInfo
instance (signature ~ (GstVideo.VideoInfo.VideoInfo -> Gst.Buffer.Buffer -> [Gst.Flags.MapFlags] -> m Bool), MonadIO m) => O.MethodInfo VideoFrameMapMethodInfo VideoFrame signature where
    overloadedMethod _ = videoFrameMap

#endif

-- method VideoFrame::map_id
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "frame", argType = TInterface (Name {namespace = "GstVideo", name = "VideoFrame"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "pointer to #GstVideoFrame", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "info", argType = TInterface (Name {namespace = "GstVideo", name = "VideoInfo"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GstVideoInfo", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "buffer", argType = TInterface (Name {namespace = "Gst", name = "Buffer"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the buffer to map", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "id", argType = TBasicType TInt, direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "the frame id to map", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing},Arg {argCName = "flags", argType = TInterface (Name {namespace = "Gst", name = "MapFlags"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "#GstMapFlags", 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_video_frame_map_id" gst_video_frame_map_id :: 
    Ptr VideoFrame ->                       -- frame : TInterface (Name {namespace = "GstVideo", name = "VideoFrame"})
    Ptr GstVideo.VideoInfo.VideoInfo ->     -- info : TInterface (Name {namespace = "GstVideo", name = "VideoInfo"})
    Ptr Gst.Buffer.Buffer ->                -- buffer : TInterface (Name {namespace = "Gst", name = "Buffer"})
    Int32 ->                                -- id : TBasicType TInt
    CUInt ->                                -- flags : TInterface (Name {namespace = "Gst", name = "MapFlags"})
    IO CInt

{- |
Use /@info@/ and /@buffer@/ to fill in the values of /@frame@/ with the video frame
information of frame /@id@/.

When /@id@/ is -1, the default frame is mapped. When /@id@/ != -1, this function
will return 'False' when there is no GstVideoMeta with that id.

All video planes of /@buffer@/ will be mapped and the pointers will be set in
/@frame@/->data.
-}
videoFrameMapId ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    VideoFrame
    {- ^ /@frame@/: pointer to 'GI.GstVideo.Structs.VideoFrame.VideoFrame' -}
    -> GstVideo.VideoInfo.VideoInfo
    {- ^ /@info@/: a 'GI.GstVideo.Structs.VideoInfo.VideoInfo' -}
    -> Gst.Buffer.Buffer
    {- ^ /@buffer@/: the buffer to map -}
    -> Int32
    {- ^ /@id@/: the frame id to map -}
    -> [Gst.Flags.MapFlags]
    {- ^ /@flags@/: 'GI.Gst.Flags.MapFlags' -}
    -> m Bool
    {- ^ __Returns:__ 'True' on success. -}
videoFrameMapId frame info buffer id flags = liftIO $ do
    frame' <- unsafeManagedPtrGetPtr frame
    info' <- unsafeManagedPtrGetPtr info
    buffer' <- unsafeManagedPtrGetPtr buffer
    let flags' = gflagsToWord flags
    result <- gst_video_frame_map_id frame' info' buffer' id flags'
    let result' = (/= 0) result
    touchManagedPtr frame
    touchManagedPtr info
    touchManagedPtr buffer
    return result'

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
data VideoFrameMapIdMethodInfo
instance (signature ~ (GstVideo.VideoInfo.VideoInfo -> Gst.Buffer.Buffer -> Int32 -> [Gst.Flags.MapFlags] -> m Bool), MonadIO m) => O.MethodInfo VideoFrameMapIdMethodInfo VideoFrame signature where
    overloadedMethod _ = videoFrameMapId

#endif

-- method VideoFrame::unmap
-- method type : OrdinaryMethod
-- Args : [Arg {argCName = "frame", argType = TInterface (Name {namespace = "GstVideo", name = "VideoFrame"}), direction = DirectionIn, mayBeNull = False, argDoc = Documentation {rawDocText = Just "a #GstVideoFrame", sinceVersion = Nothing}, argScope = ScopeTypeInvalid, argClosure = -1, argDestroy = -1, argCallerAllocates = False, transfer = TransferNothing}]
-- Lengths : []
-- returnType : Nothing
-- throws : False
-- Skip return : False

foreign import ccall "gst_video_frame_unmap" gst_video_frame_unmap :: 
    Ptr VideoFrame ->                       -- frame : TInterface (Name {namespace = "GstVideo", name = "VideoFrame"})
    IO ()

{- |
Unmap the memory previously mapped with gst_video_frame_map.
-}
videoFrameUnmap ::
    (B.CallStack.HasCallStack, MonadIO m) =>
    VideoFrame
    {- ^ /@frame@/: a 'GI.GstVideo.Structs.VideoFrame.VideoFrame' -}
    -> m ()
videoFrameUnmap frame = liftIO $ do
    frame' <- unsafeManagedPtrGetPtr frame
    gst_video_frame_unmap frame'
    touchManagedPtr frame
    return ()

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
data VideoFrameUnmapMethodInfo
instance (signature ~ (m ()), MonadIO m) => O.MethodInfo VideoFrameUnmapMethodInfo VideoFrame signature where
    overloadedMethod _ = videoFrameUnmap

#endif

#if defined(ENABLE_OVERLOADING) && !defined(__HADDOCK_VERSION__)
type family ResolveVideoFrameMethod (t :: Symbol) (o :: *) :: * where
    ResolveVideoFrameMethod "copy" o = VideoFrameCopyMethodInfo
    ResolveVideoFrameMethod "copyPlane" o = VideoFrameCopyPlaneMethodInfo
    ResolveVideoFrameMethod "map" o = VideoFrameMapMethodInfo
    ResolveVideoFrameMethod "mapId" o = VideoFrameMapIdMethodInfo
    ResolveVideoFrameMethod "unmap" o = VideoFrameUnmapMethodInfo
    ResolveVideoFrameMethod l o = O.MethodResolutionFailed l o

instance (info ~ ResolveVideoFrameMethod t VideoFrame, O.MethodInfo info VideoFrame p) => O.IsLabelProxy t (VideoFrame -> p) where
    fromLabelProxy _ = O.overloadedMethod (O.MethodProxy :: O.MethodProxy info)

#if MIN_VERSION_base(4,9,0)
instance (info ~ ResolveVideoFrameMethod t VideoFrame, O.MethodInfo info VideoFrame p) => O.IsLabel t (VideoFrame -> 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

#endif