{-# OPTIONS -fglasgow-exts #-} module AVFormat where import Data.Maybe import Data.Word import Foreign.C.String import Foreign.Ptr import Foreign.Marshal.Alloc import Foreign.Marshal.Array import Foreign.Storable #include "ffmpeg/avformat.h" import AVCodec -- * AVStream newtype AVStream = AVStream (Ptr AVStream) codec :: AVStream -> IO AVCodecContext codec (AVStream avs) = #{peek AVStream, codec} avs >>= return . AVCodecContext -- * AVFormatContext newtype AVFormatContext = AVFormatContext (Ptr AVFormatContext) nbStreams :: AVFormatContext -> IO Int nbStreams (AVFormatContext fmtCtxPtr) = #{peek AVFormatContext, nb_streams} fmtCtxPtr streams :: AVFormatContext -> IO [AVStream] streams fmtCtx@(AVFormatContext fmtCtxPtr) = do numStreams <- nbStreams fmtCtx ptrs <- peekArray numStreams (#{ptr AVFormatContext, streams} fmtCtxPtr) :: IO [Ptr ()] return (map (AVStream . castPtr) ptrs) newtype AVInputFormat = AVInputFormat (Ptr AVInputFormat) newtype AVFormatParameters = AVFormatParameters (Ptr AVFormatParameters) -- * AVPacket newtype AVPacket = AVPacket (Ptr AVPacket) packetData :: AVPacket -> IO (Ptr Word8) packetData (AVPacket ptr) = #{peek AVPacket, data} ptr packetStreamIndex :: AVPacket -> IO Int packetStreamIndex (AVPacket ptr) = #{peek AVPacket, stream_index} ptr packetSize :: AVPacket -> IO Int packetSize (AVPacket ptr) = #{peek AVPacket, size} ptr allocaPacket :: (AVPacket -> IO a) -> IO a allocaPacket f = allocaBytes #{size AVPacket} $ \ptr -> f (AVPacket ptr) foreign import ccall unsafe "av_register_all" registerAll :: IO () foreign import ccall unsafe "av_open_input_file" c_openInputFile :: Ptr AVFormatContext -> CString -> AVInputFormat -> Int -> AVFormatParameters -> IO Int foreign import ccall unsafe "av_find_stream_info" findStreamInfo :: AVFormatContext -> IO Int foreign import ccall unsafe "dump_format" c_dumpFormat :: AVFormatContext -> Int -> CString -> Int -> IO () foreign import ccall unsafe "av_read_packet" readPacket :: AVFormatContext -> AVPacket -> IO Int foreign import ccall unsafe "av_close_input_file" closeInputFile :: AVFormatContext -> IO () openInputFile :: Ptr AVFormatContext -> FilePath -> Maybe AVInputFormat -> Int -> Maybe AVFormatParameters -> IO Int openInputFile avFormatContextPtr filename mFmt bufSize mParameters = do withCString filename $ \cfilename -> c_openInputFile avFormatContextPtr cfilename (fromMaybe (AVInputFormat nullPtr) mFmt) bufSize (fromMaybe (AVFormatParameters nullPtr) mParameters) dumpFormat :: AVFormatContext -> Int -> String -> Bool -> IO () dumpFormat avFormatContext index url isOutput = withCString url $ \curl -> c_dumpFormat avFormatContext index curl (if isOutput then 1 else 0) #def void local_free_packet(pkt) { av_free_packet(pkt); } foreign import ccall unsafe "local_free_packet" local_free_packet :: AVPacket -> IO () freePacket :: AVPacket -> IO () freePacket pkt = local_free_packet pkt