{-# LINE 1 "src/Codec/FFmpeg/Types.hsc" #-}
{-# LANGUAGE ForeignFunctionInterface, FlexibleInstances,
{-# LINE 2 "src/Codec/FFmpeg/Types.hsc" #-}
             GeneralizedNewtypeDeriving #-}
module Codec.FFmpeg.Types where
import Codec.FFmpeg.Enums
import Control.Applicative
import Control.Monad (zipWithM_,when)
import Foreign.C.String (CString)
import Foreign.C.Types
import Foreign.Ptr
import Foreign.Storable


{-# LINE 13 "src/Codec/FFmpeg/Types.hsc" #-}

{-# LINE 14 "src/Codec/FFmpeg/Types.hsc" #-}

{-# LINE 15 "src/Codec/FFmpeg/Types.hsc" #-}

{-# LINE 16 "src/Codec/FFmpeg/Types.hsc" #-}

{-# LINE 17 "src/Codec/FFmpeg/Types.hsc" #-}

class HasPtr a where
  getPtr :: a -> Ptr ()

instance HasPtr (Ptr ()) where getPtr = id

newtype AVFormatContext = AVFormatContext (Ptr ()) deriving (Storable, HasPtr)
class HasNumStreams t where
  getNumStreams :: t -> IO CInt
  setNumStreams :: t -> CInt -> IO ()
  hasNumStreams :: t -> Ptr CInt

{-# LINE 25 "src/Codec/FFmpeg/Types.hsc" #-}
class HasStreams t where
  getStreams :: t -> IO (Ptr AVStream)
  setStreams :: t -> (Ptr AVStream) -> IO ()
  hasStreams :: t -> Ptr (Ptr AVStream)

{-# LINE 26 "src/Codec/FFmpeg/Types.hsc" #-}
class HasOutputFormat t where
  getOutputFormat :: t -> IO AVOutputFormat
  setOutputFormat :: t -> AVOutputFormat -> IO ()
  hasOutputFormat :: t -> Ptr AVOutputFormat

{-# LINE 27 "src/Codec/FFmpeg/Types.hsc" #-}
class HasIOContext t where
  getIOContext :: t -> IO AVIOContext
  setIOContext :: t -> AVIOContext -> IO ()
  hasIOContext :: t -> Ptr AVIOContext

{-# LINE 28 "src/Codec/FFmpeg/Types.hsc" #-}
class HasInputFormat t where
  getInputFormat :: t -> IO AVInputFormat
  setInputFormat :: t -> AVInputFormat -> IO ()
  hasInputFormat :: t -> Ptr AVInputFormat

{-# LINE 29 "src/Codec/FFmpeg/Types.hsc" #-}

instance HasNumStreams AVFormatContext where
  getNumStreams = (\hsc_ptr -> peekByteOff hsc_ptr 44) . getPtr
  setNumStreams = (\hsc_ptr -> pokeByteOff hsc_ptr 44) . getPtr
  hasNumStreams = (\hsc_ptr -> hsc_ptr `plusPtr` 44) . getPtr

{-# LINE 31 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasStreams AVFormatContext where
  getStreams = (\hsc_ptr -> peekByteOff hsc_ptr 48) . getPtr
  setStreams = (\hsc_ptr -> pokeByteOff hsc_ptr 48) . getPtr
  hasStreams = (\hsc_ptr -> hsc_ptr `plusPtr` 48) . getPtr

{-# LINE 32 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasOutputFormat AVFormatContext where
  getOutputFormat = (\hsc_ptr -> peekByteOff hsc_ptr 16) . getPtr
  setOutputFormat = (\hsc_ptr -> pokeByteOff hsc_ptr 16) . getPtr
  hasOutputFormat = (\hsc_ptr -> hsc_ptr `plusPtr` 16) . getPtr

{-# LINE 33 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasInputFormat AVFormatContext where
  getInputFormat = (\hsc_ptr -> peekByteOff hsc_ptr 8) . getPtr
  setInputFormat = (\hsc_ptr -> pokeByteOff hsc_ptr 8) . getPtr
  hasInputFormat = (\hsc_ptr -> hsc_ptr `plusPtr` 8) . getPtr

{-# LINE 34 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasIOContext AVFormatContext where
  getIOContext = (\hsc_ptr -> peekByteOff hsc_ptr 32) . getPtr
  setIOContext = (\hsc_ptr -> pokeByteOff hsc_ptr 32) . getPtr
  hasIOContext = (\hsc_ptr -> hsc_ptr `plusPtr` 32) . getPtr

{-# LINE 35 "src/Codec/FFmpeg/Types.hsc" #-}

setFilename :: AVFormatContext -> String -> IO ()
setFilename ctx fn =
    do let ptr  = getPtr ctx
           dst   = ((\hsc_ptr -> hsc_ptr `plusPtr` 56)) ptr
{-# LINE 40 "src/Codec/FFmpeg/Types.hsc" #-}
           bytes = map (fromIntegral . fromEnum) fn
       zipWithM_ (pokeElemOff dst) bytes [(0 :: CInt) ..]


foreign import ccall "av_input_video_device_next"
  av_input_video_device_next :: AVInputFormat -> IO AVInputFormat

setCamera :: AVFormatContext -> IO ()
setCamera ctx = do
    ipt <- getCameraAVInputFormat (AVInputFormat nullPtr)
    setInputFormat ctx ipt
  where
    -- Currently straight-line, but we can filter each 'nxt' based on
    -- predicates, such as device ('avfoundtion', 'v4l2' etc) in the
    -- future, if needed.
    getCameraAVInputFormat :: AVInputFormat -> IO AVInputFormat
    getCameraAVInputFormat p = do
        nxt <- av_input_video_device_next p
        when (nullPtr == getPtr nxt) (error "No video input device found.")
        return nxt

foreign import ccall "avformat_alloc_context"
    avformat_alloc_context :: IO (Ptr ())

mallocAVFormatContext :: IO AVFormatContext
mallocAVFormatContext = AVFormatContext <$> avformat_alloc_context

newtype AVCodecContext = AVCodecContext (Ptr ()) deriving (Storable, HasPtr)

class HasBitRate t where
  getBitRate :: t -> IO CInt
  setBitRate :: t -> CInt -> IO ()
  hasBitRate :: t -> Ptr CInt

{-# LINE 70 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasBitRate AVCodecContext where
  getBitRate = (\hsc_ptr -> peekByteOff hsc_ptr 96) . getPtr
  setBitRate = (\hsc_ptr -> pokeByteOff hsc_ptr 96) . getPtr
  hasBitRate = (\hsc_ptr -> hsc_ptr `plusPtr` 96) . getPtr

{-# LINE 71 "src/Codec/FFmpeg/Types.hsc" #-}

class HasWidth t where
  getWidth :: t -> IO CInt
  setWidth :: t -> CInt -> IO ()
  hasWidth :: t -> Ptr CInt

{-# LINE 73 "src/Codec/FFmpeg/Types.hsc" #-}
class HasHeight t where
  getHeight :: t -> IO CInt
  setHeight :: t -> CInt -> IO ()
  hasHeight :: t -> Ptr CInt

{-# LINE 74 "src/Codec/FFmpeg/Types.hsc" #-}
class HasTimeBase t where
  getTimeBase :: t -> IO AVRational
  setTimeBase :: t -> AVRational -> IO ()
  hasTimeBase :: t -> Ptr AVRational

{-# LINE 75 "src/Codec/FFmpeg/Types.hsc" #-}
class HasGopSize t where
  getGopSize :: t -> IO CInt
  setGopSize :: t -> CInt -> IO ()
  hasGopSize :: t -> Ptr CInt

{-# LINE 76 "src/Codec/FFmpeg/Types.hsc" #-}
class HasPixelFormat t where
  getPixelFormat :: t -> IO AVPixelFormat
  setPixelFormat :: t -> AVPixelFormat -> IO ()
  hasPixelFormat :: t -> Ptr AVPixelFormat

{-# LINE 77 "src/Codec/FFmpeg/Types.hsc" #-}
class HasCodecFlags t where
  getCodecFlags :: t -> IO CodecFlag
  setCodecFlags :: t -> CodecFlag -> IO ()
  hasCodecFlags :: t -> Ptr CodecFlag

{-# LINE 78 "src/Codec/FFmpeg/Types.hsc" #-}
class HasCodecID t where
  getCodecID :: t -> IO AVCodecID
  setCodecID :: t -> AVCodecID -> IO ()
  hasCodecID :: t -> Ptr AVCodecID

{-# LINE 79 "src/Codec/FFmpeg/Types.hsc" #-}
class HasPrivData t where
  getPrivData :: t -> IO (Ptr ())
  setPrivData :: t -> (Ptr ()) -> IO ()
  hasPrivData :: t -> Ptr (Ptr ())

{-# LINE 80 "src/Codec/FFmpeg/Types.hsc" #-}

instance HasWidth AVCodecContext where
  getWidth = (\hsc_ptr -> peekByteOff hsc_ptr 156) . getPtr
  setWidth = (\hsc_ptr -> pokeByteOff hsc_ptr 156) . getPtr
  hasWidth = (\hsc_ptr -> hsc_ptr `plusPtr` 156) . getPtr

{-# LINE 82 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasHeight AVCodecContext where
  getHeight = (\hsc_ptr -> peekByteOff hsc_ptr 160) . getPtr
  setHeight = (\hsc_ptr -> pokeByteOff hsc_ptr 160) . getPtr
  hasHeight = (\hsc_ptr -> hsc_ptr `plusPtr` 160) . getPtr

{-# LINE 83 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasTimeBase AVCodecContext where
  getTimeBase = (\hsc_ptr -> peekByteOff hsc_ptr 140) . getPtr
  setTimeBase = (\hsc_ptr -> pokeByteOff hsc_ptr 140) . getPtr
  hasTimeBase = (\hsc_ptr -> hsc_ptr `plusPtr` 140) . getPtr

{-# LINE 84 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasGopSize AVCodecContext where
  getGopSize = (\hsc_ptr -> peekByteOff hsc_ptr 172) . getPtr
  setGopSize = (\hsc_ptr -> pokeByteOff hsc_ptr 172) . getPtr
  hasGopSize = (\hsc_ptr -> hsc_ptr `plusPtr` 172) . getPtr

{-# LINE 85 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasPixelFormat AVCodecContext where
  getPixelFormat = (\hsc_ptr -> peekByteOff hsc_ptr 176) . getPtr
  setPixelFormat = (\hsc_ptr -> pokeByteOff hsc_ptr 176) . getPtr
  hasPixelFormat = (\hsc_ptr -> hsc_ptr `plusPtr` 176) . getPtr

{-# LINE 86 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasCodecFlags AVCodecContext where
  getCodecFlags = (\hsc_ptr -> peekByteOff hsc_ptr 116) . getPtr
  setCodecFlags = (\hsc_ptr -> pokeByteOff hsc_ptr 116) . getPtr
  hasCodecFlags = (\hsc_ptr -> hsc_ptr `plusPtr` 116) . getPtr

{-# LINE 87 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasCodecID AVCodecContext where
  getCodecID = (\hsc_ptr -> peekByteOff hsc_ptr 56) . getPtr
  setCodecID = (\hsc_ptr -> pokeByteOff hsc_ptr 56) . getPtr
  hasCodecID = (\hsc_ptr -> hsc_ptr `plusPtr` 56) . getPtr

{-# LINE 88 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasPrivData AVCodecContext where
  getPrivData = (\hsc_ptr -> peekByteOff hsc_ptr 72) . getPtr
  setPrivData = (\hsc_ptr -> pokeByteOff hsc_ptr 72) . getPtr
  hasPrivData = (\hsc_ptr -> hsc_ptr `plusPtr` 72) . getPtr

{-# LINE 89 "src/Codec/FFmpeg/Types.hsc" #-}

newtype AVStream = AVStream (Ptr ()) deriving (Storable, HasPtr)

class HasId t where
  getId :: t -> IO CInt
  setId :: t -> CInt -> IO ()
  hasId :: t -> Ptr CInt

{-# LINE 93 "src/Codec/FFmpeg/Types.hsc" #-}
class HasCodecContext t where
  getCodecContext :: t -> IO AVCodecContext
  setCodecContext :: t -> AVCodecContext -> IO ()
  hasCodecContext :: t -> Ptr AVCodecContext

{-# LINE 94 "src/Codec/FFmpeg/Types.hsc" #-}
class HasStreamIndex t where
  getStreamIndex :: t -> IO CInt
  setStreamIndex :: t -> CInt -> IO ()
  hasStreamIndex :: t -> Ptr CInt

{-# LINE 95 "src/Codec/FFmpeg/Types.hsc" #-}

instance HasId AVStream where
  getId = (\hsc_ptr -> peekByteOff hsc_ptr 4) . getPtr
  setId = (\hsc_ptr -> pokeByteOff hsc_ptr 4) . getPtr
  hasId = (\hsc_ptr -> hsc_ptr `plusPtr` 4) . getPtr

{-# LINE 97 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasTimeBase AVStream where
  getTimeBase = (\hsc_ptr -> peekByteOff hsc_ptr 48) . getPtr
  setTimeBase = (\hsc_ptr -> pokeByteOff hsc_ptr 48) . getPtr
  hasTimeBase = (\hsc_ptr -> hsc_ptr `plusPtr` 48) . getPtr

{-# LINE 98 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasCodecContext AVStream where
  getCodecContext = (\hsc_ptr -> peekByteOff hsc_ptr 8) . getPtr
  setCodecContext = (\hsc_ptr -> pokeByteOff hsc_ptr 8) . getPtr
  hasCodecContext = (\hsc_ptr -> hsc_ptr `plusPtr` 8) . getPtr

{-# LINE 99 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasStreamIndex AVStream where
  getStreamIndex = (\hsc_ptr -> peekByteOff hsc_ptr 0) . getPtr
  setStreamIndex = (\hsc_ptr -> pokeByteOff hsc_ptr 0) . getPtr
  hasStreamIndex = (\hsc_ptr -> hsc_ptr `plusPtr` 0) . getPtr

{-# LINE 100 "src/Codec/FFmpeg/Types.hsc" #-}

newtype AVCodec = AVCodec (Ptr ()) deriving (Storable, HasPtr)
class HasLongName t where
  getLongName :: t -> IO CString
  setLongName :: t -> CString -> IO ()
  hasLongName :: t -> Ptr CString

{-# LINE 103 "src/Codec/FFmpeg/Types.hsc" #-}
class HasName t where
  getName :: t -> IO CString
  setName :: t -> CString -> IO ()
  hasName :: t -> Ptr CString

{-# LINE 104 "src/Codec/FFmpeg/Types.hsc" #-}
class HasPixelFormats t where
  getPixelFormats :: t -> IO (Ptr AVPixelFormat)
  setPixelFormats :: t -> (Ptr AVPixelFormat) -> IO ()
  hasPixelFormats :: t -> Ptr (Ptr AVPixelFormat)

{-# LINE 105 "src/Codec/FFmpeg/Types.hsc" #-}

instance HasLongName AVCodec where
  getLongName = (\hsc_ptr -> peekByteOff hsc_ptr 8) . getPtr
  setLongName = (\hsc_ptr -> pokeByteOff hsc_ptr 8) . getPtr
  hasLongName = (\hsc_ptr -> hsc_ptr `plusPtr` 8) . getPtr

{-# LINE 107 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasName AVCodec where
  getName = (\hsc_ptr -> peekByteOff hsc_ptr 0) . getPtr
  setName = (\hsc_ptr -> pokeByteOff hsc_ptr 0) . getPtr
  hasName = (\hsc_ptr -> hsc_ptr `plusPtr` 0) . getPtr

{-# LINE 108 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasCodecID AVCodec where
  getCodecID = (\hsc_ptr -> peekByteOff hsc_ptr 20) . getPtr
  setCodecID = (\hsc_ptr -> pokeByteOff hsc_ptr 20) . getPtr
  hasCodecID = (\hsc_ptr -> hsc_ptr `plusPtr` 20) . getPtr

{-# LINE 109 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasPixelFormats AVCodec where
  getPixelFormats = (\hsc_ptr -> peekByteOff hsc_ptr 40) . getPtr
  setPixelFormats = (\hsc_ptr -> pokeByteOff hsc_ptr 40) . getPtr
  hasPixelFormats = (\hsc_ptr -> hsc_ptr `plusPtr` 40) . getPtr

{-# LINE 110 "src/Codec/FFmpeg/Types.hsc" #-}

newtype AVDictionary = AVDictionary (Ptr ()) deriving (Storable, HasPtr)
newtype AVFrame = AVFrame (Ptr ()) deriving (Storable, HasPtr)
class HasPts t where
  getPts :: t -> IO CLong
  setPts :: t -> CLong -> IO ()
  hasPts :: t -> Ptr CLong

{-# LINE 114 "src/Codec/FFmpeg/Types.hsc" #-}
class HasPktPts t where
  getPktPts :: t -> IO CLong
  setPktPts :: t -> CLong -> IO ()
  hasPktPts :: t -> Ptr CLong

{-# LINE 115 "src/Codec/FFmpeg/Types.hsc" #-}
class HasLineSize t where
  getLineSize :: t -> IO CInt
  setLineSize :: t -> CInt -> IO ()
  hasLineSize :: t -> Ptr CInt

{-# LINE 116 "src/Codec/FFmpeg/Types.hsc" #-}

instance HasPixelFormat AVFrame where
  getPixelFormat = (\hsc_ptr -> peekByteOff hsc_ptr 116) . getPtr
  setPixelFormat = (\hsc_ptr -> pokeByteOff hsc_ptr 116) . getPtr
  hasPixelFormat = (\hsc_ptr -> hsc_ptr `plusPtr` 116) . getPtr

{-# LINE 118 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasWidth AVFrame where
  getWidth = (\hsc_ptr -> peekByteOff hsc_ptr 104) . getPtr
  setWidth = (\hsc_ptr -> pokeByteOff hsc_ptr 104) . getPtr
  hasWidth = (\hsc_ptr -> hsc_ptr `plusPtr` 104) . getPtr

{-# LINE 119 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasHeight AVFrame where
  getHeight = (\hsc_ptr -> peekByteOff hsc_ptr 108) . getPtr
  setHeight = (\hsc_ptr -> pokeByteOff hsc_ptr 108) . getPtr
  hasHeight = (\hsc_ptr -> hsc_ptr `plusPtr` 108) . getPtr

{-# LINE 120 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasLineSize AVFrame where
  getLineSize = (\hsc_ptr -> peekByteOff hsc_ptr 64) . getPtr
  setLineSize = (\hsc_ptr -> pokeByteOff hsc_ptr 64) . getPtr
  hasLineSize = (\hsc_ptr -> hsc_ptr `plusPtr` 64) . getPtr

{-# LINE 121 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasPts AVFrame where
  getPts = (\hsc_ptr -> peekByteOff hsc_ptr 136) . getPtr
  setPts = (\hsc_ptr -> pokeByteOff hsc_ptr 136) . getPtr
  hasPts = (\hsc_ptr -> hsc_ptr `plusPtr` 136) . getPtr

{-# LINE 122 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasPktPts AVFrame where
  getPktPts = (\hsc_ptr -> peekByteOff hsc_ptr 144) . getPtr
  setPktPts = (\hsc_ptr -> pokeByteOff hsc_ptr 144) . getPtr
  hasPktPts = (\hsc_ptr -> hsc_ptr `plusPtr` 144) . getPtr

{-# LINE 123 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasData AVFrame where
  getData = (\hsc_ptr -> peekByteOff hsc_ptr 0) . getPtr
  setData = (\hsc_ptr -> pokeByteOff hsc_ptr 0) . getPtr
  hasData = (\hsc_ptr -> hsc_ptr `plusPtr` 0) . getPtr

{-# LINE 124 "src/Codec/FFmpeg/Types.hsc" #-}

newtype AVPicture = AVPicture (Ptr ()) deriving (Storable, HasPtr)
instance HasData AVPicture where
  getData = (\hsc_ptr -> peekByteOff hsc_ptr 0) . getPtr
  setData = (\hsc_ptr -> pokeByteOff hsc_ptr 0) . getPtr
  hasData = (\hsc_ptr -> hsc_ptr `plusPtr` 0) . getPtr

{-# LINE 127 "src/Codec/FFmpeg/Types.hsc" #-}

newtype SwsContext = SwsContext (Ptr ()) deriving (Storable, HasPtr)
newtype AVOutputFormat = AVOutputFormat (Ptr ()) deriving (Storable, HasPtr)
class HasFormatFlags t where
  getFormatFlags :: t -> IO FormatFlag
  setFormatFlags :: t -> FormatFlag -> IO ()
  hasFormatFlags :: t -> Ptr FormatFlag

{-# LINE 131 "src/Codec/FFmpeg/Types.hsc" #-}
class HasVideoCodecID t where
  getVideoCodecID :: t -> IO AVCodecID
  setVideoCodecID :: t -> AVCodecID -> IO ()
  hasVideoCodecID :: t -> Ptr AVCodecID

{-# LINE 132 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasFormatFlags AVOutputFormat where
  getFormatFlags = (\hsc_ptr -> peekByteOff hsc_ptr 44) . getPtr
  setFormatFlags = (\hsc_ptr -> pokeByteOff hsc_ptr 44) . getPtr
  hasFormatFlags = (\hsc_ptr -> hsc_ptr `plusPtr` 44) . getPtr

{-# LINE 133 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasVideoCodecID AVOutputFormat where
  getVideoCodecID = (\hsc_ptr -> peekByteOff hsc_ptr 36) . getPtr
  setVideoCodecID = (\hsc_ptr -> pokeByteOff hsc_ptr 36) . getPtr
  hasVideoCodecID = (\hsc_ptr -> hsc_ptr `plusPtr` 36) . getPtr

{-# LINE 134 "src/Codec/FFmpeg/Types.hsc" #-}

newtype AVInputFormat = AVInputFormat (Ptr ()) deriving (Storable, HasPtr)
newtype AVClass = AVClass (Ptr ()) deriving (Storable, HasPtr)
class HasAVClass t where
  getAVClass :: t -> IO AVClass
  setAVClass :: t -> AVClass -> IO ()
  hasAVClass :: t -> Ptr AVClass

{-# LINE 138 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasAVClass AVInputFormat where
  getAVClass = (\hsc_ptr -> peekByteOff hsc_ptr 40) . getPtr
  setAVClass = (\hsc_ptr -> pokeByteOff hsc_ptr 40) . getPtr
  hasAVClass = (\hsc_ptr -> hsc_ptr `plusPtr` 40) . getPtr

{-# LINE 139 "src/Codec/FFmpeg/Types.hsc" #-}

getAVCategory :: AVInputFormat -> IO Category
getAVCategory aif =
  do c <- getAVClass aif
     if nullPtr == getPtr c
        then return (Category (-1))
        else Category <$> peek (((\hsc_ptr -> hsc_ptr `plusPtr` 56)) $ castPtr $ getPtr c)
{-# LINE 146 "src/Codec/FFmpeg/Types.hsc" #-}

newtype Category = Category CInt deriving (Eq,Ord,Show,Read,Enum)
avClassCategoryNa :: Category
avClassCategoryNa = Category 0
avClassCategoryInput :: Category
avClassCategoryInput = Category 1
avClassCategoryOutput :: Category
avClassCategoryOutput = Category 2
avClassCategoryMuxer :: Category
avClassCategoryMuxer = Category 3
avClassCategoryDemuxer :: Category
avClassCategoryDemuxer = Category 4
avClassCategoryEncoder :: Category
avClassCategoryEncoder = Category 5
avClassCategoryDecoder :: Category
avClassCategoryDecoder = Category 6
avClassCategoryFilter :: Category
avClassCategoryFilter = Category 7
avClassCategoryBitstreamFilter :: Category
avClassCategoryBitstreamFilter = Category 8
avClassCategorySwscaler :: Category
avClassCategorySwscaler = Category 9
avClassCategorySwresampler :: Category
avClassCategorySwresampler = Category 10
avClassCategoryDeviceVideoOutput :: Category
avClassCategoryDeviceVideoOutput = Category 40
avClassCategoryDeviceVideoInput :: Category
avClassCategoryDeviceVideoInput = Category 41
avClassCategoryDeviceAudioOutput :: Category
avClassCategoryDeviceAudioOutput = Category 42
avClassCategoryDeviceAudioInput :: Category
avClassCategoryDeviceAudioInput = Category 43
avClassCategoryDeviceOutput :: Category
avClassCategoryDeviceOutput = Category 44
avClassCategoryDeviceInput :: Category
avClassCategoryDeviceInput = Category 45
avClassCategoryNb :: Category
avClassCategoryNb = Category 46

{-# LINE 155 "src/Codec/FFmpeg/Types.hsc" #-}

newtype AVIOContext = AVIOContext (Ptr ()) deriving (Storable, HasPtr)

newtype AVPacket = AVPacket (Ptr ()) deriving (Storable, HasPtr)
class HasData t where
  getData :: t -> IO (Ptr ())
  setData :: t -> (Ptr ()) -> IO ()
  hasData :: t -> Ptr (Ptr ())

{-# LINE 160 "src/Codec/FFmpeg/Types.hsc" #-}
class HasSize t where
  getSize :: t -> IO CInt
  setSize :: t -> CInt -> IO ()
  hasSize :: t -> Ptr CInt

{-# LINE 161 "src/Codec/FFmpeg/Types.hsc" #-}
class HasPacketFlags t where
  getPacketFlags :: t -> IO PacketFlag
  setPacketFlags :: t -> PacketFlag -> IO ()
  hasPacketFlags :: t -> Ptr PacketFlag

{-# LINE 162 "src/Codec/FFmpeg/Types.hsc" #-}
class HasDts t where
  getDts :: t -> IO CLong
  setDts :: t -> CLong -> IO ()
  hasDts :: t -> Ptr CLong

{-# LINE 163 "src/Codec/FFmpeg/Types.hsc" #-}

instance HasData AVPacket where
  getData = (\hsc_ptr -> peekByteOff hsc_ptr 24) . getPtr
  setData = (\hsc_ptr -> pokeByteOff hsc_ptr 24) . getPtr
  hasData = (\hsc_ptr -> hsc_ptr `plusPtr` 24) . getPtr

{-# LINE 165 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasSize AVPacket where
  getSize = (\hsc_ptr -> peekByteOff hsc_ptr 32) . getPtr
  setSize = (\hsc_ptr -> pokeByteOff hsc_ptr 32) . getPtr
  hasSize = (\hsc_ptr -> hsc_ptr `plusPtr` 32) . getPtr

{-# LINE 166 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasPacketFlags AVPacket where
  getPacketFlags = (\hsc_ptr -> peekByteOff hsc_ptr 40) . getPtr
  setPacketFlags = (\hsc_ptr -> pokeByteOff hsc_ptr 40) . getPtr
  hasPacketFlags = (\hsc_ptr -> hsc_ptr `plusPtr` 40) . getPtr

{-# LINE 167 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasStreamIndex AVPacket where
  getStreamIndex = (\hsc_ptr -> peekByteOff hsc_ptr 36) . getPtr
  setStreamIndex = (\hsc_ptr -> pokeByteOff hsc_ptr 36) . getPtr
  hasStreamIndex = (\hsc_ptr -> hsc_ptr `plusPtr` 36) . getPtr

{-# LINE 168 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasPts AVPacket where
  getPts = (\hsc_ptr -> peekByteOff hsc_ptr 8) . getPtr
  setPts = (\hsc_ptr -> pokeByteOff hsc_ptr 8) . getPtr
  hasPts = (\hsc_ptr -> hsc_ptr `plusPtr` 8) . getPtr

{-# LINE 169 "src/Codec/FFmpeg/Types.hsc" #-}
instance HasDts AVPacket where
  getDts = (\hsc_ptr -> peekByteOff hsc_ptr 16) . getPtr
  setDts = (\hsc_ptr -> pokeByteOff hsc_ptr 16) . getPtr
  hasDts = (\hsc_ptr -> hsc_ptr `plusPtr` 16) . getPtr

{-# LINE 170 "src/Codec/FFmpeg/Types.hsc" #-}

-- | @sizeof@ the 'AVPacket' structure in bytes.
packetSize :: Int
packetSize = (88)
{-# LINE 174 "src/Codec/FFmpeg/Types.hsc" #-}

pictureSize :: Int
pictureSize = (96)
{-# LINE 177 "src/Codec/FFmpeg/Types.hsc" #-}

-- * Types with Haskell equivalents

data AVRational = AVRational { numerator   :: CInt
                             , denomenator :: CInt } deriving Show

instance Storable AVRational where
  sizeOf _ = (8)
{-# LINE 185 "src/Codec/FFmpeg/Types.hsc" #-}
  alignment _ = (8)
{-# LINE 186 "src/Codec/FFmpeg/Types.hsc" #-}
  peek ptr = AVRational <$> ((\hsc_ptr -> peekByteOff hsc_ptr 0)) ptr
{-# LINE 187 "src/Codec/FFmpeg/Types.hsc" #-}
                        <*> ((\hsc_ptr -> peekByteOff hsc_ptr 4)) ptr
{-# LINE 188 "src/Codec/FFmpeg/Types.hsc" #-}
  poke ptr (AVRational n d) = do ((\hsc_ptr -> pokeByteOff hsc_ptr 0)) ptr n
{-# LINE 189 "src/Codec/FFmpeg/Types.hsc" #-}
                                 ((\hsc_ptr -> pokeByteOff hsc_ptr 4)) ptr d
{-# LINE 190 "src/Codec/FFmpeg/Types.hsc" #-}

foreign import ccall "av_rescale_rnd"
  av_rescale_rnd :: CLong -> CLong -> CLong -> AVRoundMode -> CLong

-- | Convert an 'AVRational' to a 'Double'
av_q2d :: AVRational -> CDouble
av_q2d r = fromIntegral (numerator r) / fromIntegral (denomenator r)

-- | Rescale an integer from one time base to another.
av_rescale_q :: CLong -> AVRational -> AVRational -> CLong
av_rescale_q a bq cq = av_rescale_rnd a b c avRoundNearInf
  where b = fromIntegral (numerator bq) * fromIntegral (denomenator cq)
        c = fromIntegral (numerator cq) * fromIntegral (denomenator bq)

data AVFrac = AVFrac { fracVal :: CLong
                     , fracNum :: CLong
                     , fracDen :: CLong } deriving Show

instance Storable AVFrac where
  sizeOf _ = (24)
{-# LINE 210 "src/Codec/FFmpeg/Types.hsc" #-}
  alignment _ = (24)
{-# LINE 211 "src/Codec/FFmpeg/Types.hsc" #-}
  peek ptr = AVFrac <$> ((\hsc_ptr -> peekByteOff hsc_ptr 0)) ptr
{-# LINE 212 "src/Codec/FFmpeg/Types.hsc" #-}
                    <*> ((\hsc_ptr -> peekByteOff hsc_ptr 8)) ptr
{-# LINE 213 "src/Codec/FFmpeg/Types.hsc" #-}
                    <*> ((\hsc_ptr -> peekByteOff hsc_ptr 16)) ptr
{-# LINE 214 "src/Codec/FFmpeg/Types.hsc" #-}
  poke ptr (AVFrac v n d) = do ((\hsc_ptr -> pokeByteOff hsc_ptr 0)) ptr v
{-# LINE 215 "src/Codec/FFmpeg/Types.hsc" #-}
                               ((\hsc_ptr -> pokeByteOff hsc_ptr 8)) ptr n
{-# LINE 216 "src/Codec/FFmpeg/Types.hsc" #-}
                               ((\hsc_ptr -> pokeByteOff hsc_ptr 16)) ptr d
{-# LINE 217 "src/Codec/FFmpeg/Types.hsc" #-}

-- | The input source can be a file or a camera.  When using 'Camera',
-- frequently in the form @Camera "0:0" defaultCameraConfig@, the first input video device
-- enumerated by libavdevice is selected.
data InputSource = File FilePath | Camera String CameraConfig
            deriving (Eq, Ord, Show, Read)

data CameraConfig =
  CameraConfig { framerate  :: Maybe Int
               , resolution :: Maybe (Int,Int)
               }
          deriving (Eq,Ord,Show,Read)

defaultCameraConfig :: CameraConfig
defaultCameraConfig = CameraConfig (Just 30) Nothing