hs-ffmpeg 0.2.3 → 0.3.2
raw patch · 21 files changed
+1253/−1043 lines, 21 filesdep +bytestring
Dependencies added: bytestring
Files
- hs-ffmpeg.cabal +13/−12
- src/Media/FFMpeg.hs +5/−3
- src/Media/FFMpeg/Codec.hsc +407/−0
- src/Media/FFMpeg/CodecEnums_.hsc +299/−0
- src/Media/FFMpeg/Common.hsc +51/−0
- src/Media/FFMpeg/Format.hsc +143/−9
- src/Media/FFMpeg/Internals.hsc +0/−20
- src/Media/FFMpeg/Internals/AVCodec.hsc +0/−541
- src/Media/FFMpeg/Internals/AVFormat.hsc +0/−142
- src/Media/FFMpeg/Internals/SWScale.hsc +0/−87
- src/Media/FFMpeg/Internals/Types.hsc +0/−25
- src/Media/FFMpeg/Internals/Utils.hsc +0/−126
- src/Media/FFMpeg/Internals/_c_utils.c +0/−6
- src/Media/FFMpeg/SWScale.hsc +86/−0
- src/Media/FFMpeg/SWScaleEnums_.hsc +31/−0
- src/Media/FFMpeg/Scale.hs +0/−14
- src/Media/FFMpeg/Types.hsc +0/−12
- src/Media/FFMpeg/Util.hsc +126/−0
- src/Media/FFMpeg/UtilEnums_.hsc +86/−0
- src/Media/FFMpeg/Version.hsc +0/−46
- src/Media/FFMpeg/_c_utils.c +6/−0
hs-ffmpeg.cabal view
@@ -1,5 +1,5 @@ name: hs-ffmpeg-version: 0.2.3+version: 0.3.2 cabal-version: >= 1.6 license: BSD3 author: Vasyl Pasternak@@ -7,29 +7,30 @@ maintainer: vasylpasternak@gmail.com description: Bindings to FFMPEG library copyright: (c) 2009 Vasyl Pasternak+homepage: http://patch-tag.com/r/VasylPasternak/hs-ffmpeg+bug-reports: http://code.google.com/p/hs-ffmpeg/issues/list stability: alpha category: Media + build-type: Simple extra-source-files: src/macros.hsc2hs.h library- build-depends: base < 4, haskell98+ build-depends: base < 4, haskell98, bytestring hs-source-dirs: src include-dirs: /usr/local/include src exposed-modules: Media.FFMpeg- Media.FFMpeg.Types Media.FFMpeg.Format- Media.FFMpeg.Version- Media.FFMpeg.Scale- other-modules: Media.FFMpeg.Internals- Media.FFMpeg.Internals.Types- Media.FFMpeg.Internals.Utils- Media.FFMpeg.Internals.AVFormat- Media.FFMpeg.Internals.AVCodec- Media.FFMpeg.Internals.SWScale- c-sources: src/Media/FFMpeg/Internals/_c_utils.c+ Media.FFMpeg.SWScale+ Media.FFMpeg.Util+ Media.FFMpeg.Codec+ other-modules: Media.FFMpeg.UtilEnums_+ Media.FFMpeg.CodecEnums_+ Media.FFMpeg.SWScaleEnums_+ Media.FFMpeg.Common+ c-sources: src/Media/FFMpeg/_c_utils.c extra-lib-dirs: /usr/local/lib extra-libraries: avformat, avcodec, avutil, avfilter, avdevice, swscale, vorbisfile, vorbis, vorbisenc,
src/Media/FFMpeg.hs view
@@ -6,11 +6,13 @@ module Media.FFMpeg (- module Media.FFMpeg.Version- ,module Media.FFMpeg.Format+ module Media.FFMpeg.Format+ ,module Media.FFMpeg.Codec+ ,module Media.FFMpeg.Util ) where -import Media.FFMpeg.Version import Media.FFMpeg.Format+import Media.FFMpeg.Codec+import Media.FFMpeg.Util
+ src/Media/FFMpeg/Codec.hsc view
@@ -0,0 +1,407 @@+-- -*- haskell -*-+{-# LANGUAGE ForeignFunctionInterface #-}++{- |Module 'Media.FFMpeg.Codec' implements bindings to AVCodec library++ (c) 2009 Vasyl Pasternak+ -}++module Media.FFMpeg.Codec + (+ libAVCodecVersion++ ,module Media.FFMpeg.CodecEnums_++ ,WithCodecId (..)+ ,WithCodecType (..)+ ,WithVideoProps (..)+ ,WithAudioProps (..)++ ,CodecContext+ ,toCodecContext++ ,Codec+ ,openCodec+ ,findDecoder+ ,decodeVideo+ ,decodeAudio+ ,decodeAudioPacket+ ,maxAudioFrameSize+ ,decodeAudioPacket'++ ,CommonPicture (..)+ ,pictureGetSize++ ,Frame+ ,allocFrame++ ,Packet+ ,allocPacket+ ,newPacket+ ,cleanPacket+ ,dupPacket+ ,packetGetStreamIndex+ ,packetGetSize+ ,packetGetBuffer+ ,packetSetBuffer+ )where++#include "libavcodec/avcodec.h"++import Foreign+import Foreign.C.Types+import Foreign.C.String+import Control.Monad (liftM)+import Text.Printf+import Data.Version+import Data.ByteString (ByteString, append, packCStringLen)++import Media.FFMpeg.Common+import Media.FFMpeg.Util+import Media.FFMpeg.CodecEnums_++libAVCodecVersion :: Version+libAVCodecVersion = Version {+ versionBranch = [+ #{const LIBAVCODEC_VERSION_MAJOR},+ #{const LIBAVCODEC_VERSION_MINOR},+ #{const LIBAVCODEC_VERSION_MICRO}+ ],+ versionTags = []+ }++--+-- | properties classes+--+class WithCodecId a where+ getCodecId :: a -> CodecId++class WithCodecType a where+ getCodecType :: a -> CodecType++class WithVideoProps a where+ getVideoWidth :: a -> Int+ getVideoHeight :: a -> Int+ getPixelFormat :: a -> PixelFormat++class WithAudioProps a where+ getAudioSampleRate :: a -> Int+ getAudioChannels :: a -> Int+ getAudioSampleFormat :: a -> SampleFormat++-- +-- | CodecContext -- wrapper to AVCodecContext+--+newtype CodecContext = CodecContext (ForeignPtr CodecContext)++instance ExternalPointer CodecContext where+ withThis (CodecContext ctx) io = withForeignPtr ctx (io . castPtr)++--+-- | convert poiner to CodecContext+toCodecContext :: Ptr a -> IO CodecContext+toCodecContext = liftM CodecContext . newForeignPtr_ . castPtr++_unsafeGetValue :: ExternalPointer p => p -> (Ptr a -> IO b) -> b+_unsafeGetValue extp io = unsafePerformIO $ withThis extp io++instance WithCodecId CodecContext where+ getCodecId ctx = _unsafeGetValue ctx $ \ctx' ->+ liftM cToEnum + (#{peek AVCodecContext, codec_id} ctx' :: IO #{type enum CodecID})++instance WithCodecType CodecContext where+ getCodecType ctx = _unsafeGetValue ctx $ \ctx' ->+ liftM cToEnum + (#{peek AVCodecContext, codec_type} ctx' :: IO #{type enum CodecType})++instance WithVideoProps CodecContext where+ getVideoWidth ctx = _unsafeGetValue ctx $ \ctx' ->+ liftM cToInt + (#{peek AVCodecContext, width} ctx' :: IO CInt)+ ++ getVideoHeight ctx = _unsafeGetValue ctx $ \ctx' -> + liftM cToInt + (#{peek AVCodecContext, height} ctx' :: IO CInt)++ getPixelFormat ctx = _unsafeGetValue ctx $ \ctx' -> + liftM cToEnum+ (#{peek AVCodecContext, pix_fmt} ctx' :: IO #{type enum PixelFormat})++instance WithAudioProps CodecContext where+ getAudioSampleRate ctx = _unsafeGetValue ctx $ \ctx' ->+ liftM cToInt (#{peek AVCodecContext, sample_rate} ctx' :: IO CInt)++ getAudioChannels ctx = _unsafeGetValue ctx $ \ctx' ->+ liftM cToInt (#{peek AVCodecContext, channels} ctx' :: IO CInt)++ getAudioSampleFormat ctx = _unsafeGetValue ctx $ \ctx' ->+ liftM cToEnum + (#{peek AVCodecContext, sample_fmt} ctx' :: IO #{type enum SampleFormat})++--+-- | Codec - implementation of AVCodec+--+newtype Codec = Codec (Ptr Codec)++instance ExternalPointer Codec where+ withThis (Codec c) io = io (castPtr c)++instance WithCodecId Codec where+ getCodecId c = _unsafeGetValue c $ \c' ->+ liftM cToEnum + (#{peek AVCodec, id} c' :: IO #{type enum CodecID})++instance WithCodecType Codec where+ getCodecType c = _unsafeGetValue c $ \c' ->+ liftM cToEnum+ (#{peek AVCodec, type} c' :: IO #{type enum CodecType})++--+-- | openCodec - opens codec due to CodecContext+--+foreign import ccall "avcodec_open" _avcodec_open :: Ptr () -> Ptr () -> IO CInt+foreign import ccall "avcodec_close" _avcodec_close :: Ptr () -> IO ()++openCodec :: CodecContext -> Codec -> IO ()+openCodec ctx @ (CodecContext ct) codec =+ withThis ctx $ \ctx' ->+ withThis codec $ \codec' -> do+ throwIf_ (<0)+ (printf "openCodec: fails to open codec '%s' - errocode %d\n" (show (getCodecId codec)) . cToInt) + (_avcodec_open ctx' codec')+ finalizer <- mkFinalizerPtr _avcodec_close+ addForeignPtrFinalizer finalizer (castForeignPtr ct)++--+-- |findDecoder - finds decoder by CodecId+--+foreign import ccall "avcodec_find_decoder" _avcodec_find_decoder :: + #{type enum CodecID} -> IO (Ptr ())++findDecoder :: CodecId -> IO (Maybe Codec)+findDecoder cid = do+ liftM (maybe Nothing (Just . Codec . castPtr) . justPtr)+ (_avcodec_find_decoder (cFromEnum cid))+++--+-- |decodeVideo -- decodes video frame, returns True if+-- complete picture is decompressed+--+foreign import ccall "avcodec_decode_video2" _avcodec_decode_video :: + Ptr () -> Ptr () -> (Ptr CInt) -> Ptr () -> IO CInt++decodeVideo :: CodecContext -> Frame -> Packet -> IO Bool+decodeVideo ctx frm pkt =+ withThis ctx $ \ctx' -> + withThis frm $ \frm' -> + withThis pkt $ \pkt' ->+ alloca $ \gotPic' -> do+ throwIf (<0)+ (printf "decodeVideo: failed to decode video packet: %d" . cToInt)+ (_avcodec_decode_video ctx' frm' gotPic' pkt')+ liftM (>0) (peek gotPic')+++--+-- |decodeAudio - decodes audio frame to the existing buffer+-- return (ReadBytes, DecodedBytes)+--+foreign import ccall "avcodec_decode_audio3" _avcodec_decode_audio :: + Ptr () -> Ptr () -> (Ptr CInt) -> Ptr () -> IO CInt++decodeAudio :: CodecContext -> Buffer -> Packet -> IO (Int, Int)+decodeAudio ctx buf pkt = + withThis ctx $ \ctx' -> + withThis buf $ \buf' ->+ withThis pkt $ \pkt' -> + with bufSize $ \frm_size -> do+ result <- throwIf (<0)+ (printf "decodeAudio: decode packet failed. Return value is %d" . cToInt)+ (liftM cToInt $ _avcodec_decode_audio ctx' buf' frm_size pkt')+ liftM ((,) result . cToInt) $ peek frm_size+ where bufSize = cFromInt $ bufferSize buf :: CInt+++--+-- | decodeAudio is very complex to use, the another version of the +-- same function is decode audio packet. It decodes packets into a list of+-- buffers with max size is set to 'size'. +--++decodeAudioPacket :: Int -> CodecContext -> Packet -> IO ByteString+decodeAudioPacket buffSize ctx pkt = dupPacket pkt >> fillBuffer + where + shiftPacket size = packetSetBuffer pkt =<< + shiftBuffer size (packetGetBuffer pkt)+ copyToByteString buf size = + withBuffer buf $ \buf' ->+ packCStringLen (castPtr buf', size)++ fillBuffer = do+ buf <- allocBuffer buffSize+ (r, w) <- decodeAudio ctx buf pkt+ result <- copyToByteString buf w+ if r < (packetGetSize pkt) then do+ shiftPacket r+ rest <- fillBuffer+ return $ result `append` rest+ else return $ result+ ++maxAudioFrameSize :: Int+maxAudioFrameSize = #{const AVCODEC_MAX_AUDIO_FRAME_SIZE}++--+-- | decodeAudioPacket' - defaults the buffer size to 2048+--+decodeAudioPacket' :: CodecContext -> Packet -> IO ByteString+decodeAudioPacket' = decodeAudioPacket maxAudioFrameSize++--+-- |AVPicture+--++foreign import ccall "avpicture_fill" _avpicture_fill ::+ Ptr () -> Ptr () -> CInt -> CInt -> CInt -> IO CInt++class ExternalPointer pic => CommonPicture pic where+ pictureFill :: pic -> Buffer -> PixelFormat -> Int -> Int -> IO ()+ pictureFill pic buf pf w h =+ withThis pic $ \pic' -> + withThis buf $ \buf' ->+ _avpicture_fill (castPtr pic') + (castPtr buf')+ (cFromEnum pf)+ (cFromInt w) (cFromInt h) >> + return ()++ pictureGetSlice :: pic -> Ptr ()+ pictureGetSlice pic = + castPtr (_unsafeGetValue pic $ + return . (`plusPtr` #{offset AVPicture, data}))+ + pictureGetStride :: pic -> Ptr ()+ pictureGetStride pic = + castPtr (_unsafeGetValue pic $+ return . (`plusPtr` #{offset AVPicture, linesize}))++--+-- |pictureGetSize -- calculate the size of the picture in bytes+--+foreign import ccall "avpicture_get_size" _avpicture_get_size :: + #{type enum PixelFormat} -> CInt -> CInt -> IO CInt++pictureGetSize :: PixelFormat -> Int -> Int -> Int+pictureGetSize pf w h = cToInt $ unsafePerformIO + (_avpicture_get_size (cFromEnum pf) (cFromInt w) (cFromInt h))++--+-- |Frame - implementation of AVFrame+--++newtype Frame = Frame (ForeignPtr Frame)++instance ExternalPointer Frame where+ withThis (Frame f) io = withForeignPtr f (io . castPtr)++instance CommonPicture Frame++--+-- |allocFrame - allocate frame structure+--+foreign import ccall "avcodec_alloc_frame" _avcodec_alloc_frame :: IO (Ptr ())++allocFrame :: IO Frame+allocFrame = do+ p <- throwIf (== nullPtr)+ (\_ -> "allocFrame: failed to allocate frame")+ _avcodec_alloc_frame+ liftM (Frame . castForeignPtr) $ newAvForeignPtr p++--+-- | Packet -- binding to AVPacket+--++newtype Packet = Packet (ForeignPtr Packet)++instance ExternalPointer Packet where+ withThis (Packet pkt) io = withForeignPtr pkt (io . castPtr)++--+-- |allocPacket -- allocates packet structure, but don't allocates the+-- packet.data+--++foreign import ccall "av_init_packet" _av_init_packet :: Ptr () -> IO ()+foreign import ccall "b_free_packet" _b_free_packet :: Ptr () -> IO ()+++allocPacket :: IO Packet+allocPacket = do+ p <- mallocBytes #{size AVPacket}+ _av_init_packet p+ pkt <- newAvForeignPtr p+ deinit <- mkFinalizerPtr _b_free_packet + addForeignPtrFinalizer deinit pkt+ return (Packet $ castForeignPtr pkt)++--+-- |newPacket -- allocates packet with data+-- +foreign import ccall "av_new_packet" _av_new_packet :: Ptr () -> CInt -> IO CInt++newPacket :: Int -> IO Packet+newPacket s = do+ p <- mallocBytes #{size AVPacket}+ throwIf (/= 0)+ (printf "newPacket: error allocating new packet with size %d - %d" s . cToInt)+ (_av_new_packet p (cFromInt s))+ pkt <- newAvForeignPtr p+ deinit <- mkFinalizerPtr _b_free_packet+ addForeignPtrFinalizer deinit pkt+ return (Packet $ castForeignPtr pkt)++--+-- | cleanPacket - cleans the packet manually+--+cleanPacket :: Packet -> IO ()+cleanPacket pkt = withThis pkt _b_free_packet+++--+-- | dupPacket -- if packet doesn't own the buffer, than it +-- creates new buffer, and copies data there+--+foreign import ccall "av_dup_packet" _av_dup_packet :: Ptr ()-> IO CInt++dupPacket :: Packet -> IO ()+dupPacket pkt = + withThis pkt $ \pkt' -> + throwIf (< 0)+ (printf "dupPacket: failed to dup packet: %d" . cToInt)+ (_av_dup_packet pkt') >> return ()++packetGetStreamIndex :: Packet -> Int+packetGetStreamIndex pkt = _unsafeGetValue pkt $ \pkt' ->+ liftM cToInt (#{peek AVPacket, stream_index} pkt' :: IO CInt)++packetGetSize :: Packet -> Int+packetGetSize pkt = _unsafeGetValue pkt $ \pkt' ->+ liftM cToInt (#{peek AVPacket, size} pkt' :: IO CInt)++packetGetBuffer :: Packet -> Buffer+packetGetBuffer pkt = + _unsafeGetValue pkt $ \pkt' -> + (#{peek AVPacket, data} pkt' :: IO (Ptr ())) >>= + castBufferSize (packetGetSize pkt)++packetSetBuffer :: Packet -> Buffer -> IO ()+packetSetBuffer pkt buf = + withBuffer buf $ \buf' ->+ withThis pkt $ \pkt' -> do+ let bufSize = bufferSize buf+ #{poke AVPacket, size} pkt' ((cFromInt bufSize) :: CInt)+ #{poke AVPacket, data} pkt' (castPtr buf')
+ src/Media/FFMpeg/CodecEnums_.hsc view
@@ -0,0 +1,299 @@+---- -*- haskell -*- +{-# LANGUAGE ForeignFunctionInterface #-}++{- | Module 'Media.FFMpeg.CodecEnums_' implements + enumerations from libavcodec+ + (c) 2009 Vasyl Pasternak+ -}+++module Media.FFMpeg.CodecEnums_+ (+ CodecType (..)+ ,SampleFormat (..)+ ,CodecId (..)+ ) where++#include "libavcodec/avcodec.h"+#include "macros.hsc2hs.h"++--+-- | CodecType+--+#{begin_enum CodecType, CODEC_TYPE_UNKNOWN}+#{add_enum CODEC_TYPE_VIDEO}+#{add_enum CODEC_TYPE_AUDIO}+#{add_enum CODEC_TYPE_DATA}+#{add_enum CODEC_TYPE_SUBTITLE}+#{add_enum CODEC_TYPE_ATTACHMENT}+#{add_enum CODEC_TYPE_NB}+#{end_enum "Eq,Ord,Show"}++-- +-- | SampleFormat+--+#{begin_enum SampleFormat, SAMPLE_FMT_NONE}+#{add_enum SAMPLE_FMT_U8}+#{add_enum SAMPLE_FMT_S16}+#{add_enum SAMPLE_FMT_S32}+#{add_enum SAMPLE_FMT_FLT}+#{add_enum SAMPLE_FMT_DBL}+#{add_enum SAMPLE_FMT_NB}+#{end_enum "Eq,Ord,Show"}++--+-- | CodecId+--+#{begin_enum CodecId, CODEC_ID_NONE}+#{add_enum CODEC_ID_MPEG1VIDEO}+#{add_enum CODEC_ID_MPEG2VIDEO}+#{add_enum CODEC_ID_MPEG2VIDEO_XVMC}+#{add_enum CODEC_ID_H261}+#{add_enum CODEC_ID_H263}+#{add_enum CODEC_ID_RV10}+#{add_enum CODEC_ID_RV20}+#{add_enum CODEC_ID_MJPEG}+#{add_enum CODEC_ID_MJPEGB}+#{add_enum CODEC_ID_LJPEG}+#{add_enum CODEC_ID_SP5X}+#{add_enum CODEC_ID_JPEGLS}+#{add_enum CODEC_ID_MPEG4}+#{add_enum CODEC_ID_RAWVIDEO}+#{add_enum CODEC_ID_MSMPEG4V1}+#{add_enum CODEC_ID_MSMPEG4V2}+#{add_enum CODEC_ID_MSMPEG4V3}+#{add_enum CODEC_ID_WMV1}+#{add_enum CODEC_ID_WMV2}+#{add_enum CODEC_ID_H263P}+#{add_enum CODEC_ID_H263I}+#{add_enum CODEC_ID_FLV1}+#{add_enum CODEC_ID_SVQ1}+#{add_enum CODEC_ID_SVQ3}+#{add_enum CODEC_ID_DVVIDEO}+#{add_enum CODEC_ID_HUFFYUV}+#{add_enum CODEC_ID_CYUV}+#{add_enum CODEC_ID_H264}+#{add_enum CODEC_ID_INDEO3}+#{add_enum CODEC_ID_VP3}+#{add_enum CODEC_ID_THEORA}+#{add_enum CODEC_ID_ASV1}+#{add_enum CODEC_ID_ASV2}+#{add_enum CODEC_ID_FFV1}+#{add_enum CODEC_ID_4XM}+#{add_enum CODEC_ID_VCR1}+#{add_enum CODEC_ID_CLJR}+#{add_enum CODEC_ID_MDEC}+#{add_enum CODEC_ID_ROQ}+#{add_enum CODEC_ID_INTERPLAY_VIDEO}+#{add_enum CODEC_ID_XAN_WC3}+#{add_enum CODEC_ID_XAN_WC4}+#{add_enum CODEC_ID_RPZA}+#{add_enum CODEC_ID_CINEPAK}+#{add_enum CODEC_ID_WS_VQA}+#{add_enum CODEC_ID_MSRLE}+#{add_enum CODEC_ID_MSVIDEO1}+#{add_enum CODEC_ID_IDCIN}+#{add_enum CODEC_ID_8BPS}+#{add_enum CODEC_ID_SMC}+#{add_enum CODEC_ID_FLIC}+#{add_enum CODEC_ID_TRUEMOTION1}+#{add_enum CODEC_ID_VMDVIDEO}+#{add_enum CODEC_ID_MSZH}+#{add_enum CODEC_ID_ZLIB}+#{add_enum CODEC_ID_QTRLE}+#{add_enum CODEC_ID_SNOW}+#{add_enum CODEC_ID_TSCC}+#{add_enum CODEC_ID_ULTI}+#{add_enum CODEC_ID_QDRAW}+#{add_enum CODEC_ID_VIXL}+#{add_enum CODEC_ID_QPEG}+#{add_enum CODEC_ID_XVID}+#{add_enum CODEC_ID_PNG}+#{add_enum CODEC_ID_PPM}+#{add_enum CODEC_ID_PBM}+#{add_enum CODEC_ID_PGM}+#{add_enum CODEC_ID_PGMYUV}+#{add_enum CODEC_ID_PAM}+#{add_enum CODEC_ID_FFVHUFF}+#{add_enum CODEC_ID_RV30}+#{add_enum CODEC_ID_RV40}+#{add_enum CODEC_ID_VC1}+#{add_enum CODEC_ID_WMV3}+#{add_enum CODEC_ID_LOCO}+#{add_enum CODEC_ID_WNV1}+#{add_enum CODEC_ID_AASC}+#{add_enum CODEC_ID_INDEO2}+#{add_enum CODEC_ID_FRAPS}+#{add_enum CODEC_ID_TRUEMOTION2}+#{add_enum CODEC_ID_BMP}+#{add_enum CODEC_ID_CSCD}+#{add_enum CODEC_ID_MMVIDEO}+#{add_enum CODEC_ID_ZMBV}+#{add_enum CODEC_ID_AVS}+#{add_enum CODEC_ID_SMACKVIDEO}+#{add_enum CODEC_ID_NUV}+#{add_enum CODEC_ID_KMVC}+#{add_enum CODEC_ID_FLASHSV}+#{add_enum CODEC_ID_CAVS}+#{add_enum CODEC_ID_JPEG2000}+#{add_enum CODEC_ID_VMNC}+#{add_enum CODEC_ID_VP5}+#{add_enum CODEC_ID_VP6}+#{add_enum CODEC_ID_VP6F}+#{add_enum CODEC_ID_TARGA}+#{add_enum CODEC_ID_DSICINVIDEO}+#{add_enum CODEC_ID_TIERTEXSEQVIDEO}+#{add_enum CODEC_ID_TIFF}+#{add_enum CODEC_ID_GIF}+#{add_enum CODEC_ID_FFH264}+#{add_enum CODEC_ID_DXA}+#{add_enum CODEC_ID_DNXHD}+#{add_enum CODEC_ID_THP}+#{add_enum CODEC_ID_SGI}+#{add_enum CODEC_ID_C93}+#{add_enum CODEC_ID_BETHSOFTVID}+#{add_enum CODEC_ID_PTX}+#{add_enum CODEC_ID_TXD}+#{add_enum CODEC_ID_VP6A}+#{add_enum CODEC_ID_AMV}+#{add_enum CODEC_ID_VB}+#{add_enum CODEC_ID_PCX}+#{add_enum CODEC_ID_SUNRAST}+#{add_enum CODEC_ID_INDEO4}+#{add_enum CODEC_ID_INDEO5}+#{add_enum CODEC_ID_MIMIC}+#{add_enum CODEC_ID_RL2}+#{add_enum CODEC_ID_8SVX_EXP}+#{add_enum CODEC_ID_8SVX_FIB}+#{add_enum CODEC_ID_ESCAPE124}+#{add_enum CODEC_ID_DIRAC}+#{add_enum CODEC_ID_BFI}+#{add_enum CODEC_ID_CMV}+#{add_enum CODEC_ID_MOTIONPIXELS}+#{add_enum CODEC_ID_TGV}+#{add_enum CODEC_ID_TGQ}+#{add_enum CODEC_ID_TQI}+#{add_enum CODEC_ID_AURA}+#{add_enum CODEC_ID_AURA2}+#{add_enum CODEC_ID_PCM_S16LE}+#{add_enum CODEC_ID_PCM_S16BE}+#{add_enum CODEC_ID_PCM_U16LE}+#{add_enum CODEC_ID_PCM_U16BE}+#{add_enum CODEC_ID_PCM_S8}+#{add_enum CODEC_ID_PCM_U8}+#{add_enum CODEC_ID_PCM_MULAW}+#{add_enum CODEC_ID_PCM_ALAW}+#{add_enum CODEC_ID_PCM_S32LE}+#{add_enum CODEC_ID_PCM_S32BE}+#{add_enum CODEC_ID_PCM_U32LE}+#{add_enum CODEC_ID_PCM_U32BE}+#{add_enum CODEC_ID_PCM_S24LE}+#{add_enum CODEC_ID_PCM_S24BE}+#{add_enum CODEC_ID_PCM_U24LE}+#{add_enum CODEC_ID_PCM_U24BE}+#{add_enum CODEC_ID_PCM_S24DAUD}+#{add_enum CODEC_ID_PCM_ZORK}+#{add_enum CODEC_ID_PCM_S16LE_PLANAR}+#{add_enum CODEC_ID_PCM_DVD}+#{add_enum CODEC_ID_PCM_F32BE}+#{add_enum CODEC_ID_PCM_F32LE}+#{add_enum CODEC_ID_PCM_F64BE}+#{add_enum CODEC_ID_PCM_F64LE}+#{add_enum CODEC_ID_ADPCM_IMA_QT}+#{add_enum CODEC_ID_ADPCM_IMA_WAV}+#{add_enum CODEC_ID_ADPCM_IMA_DK3}+#{add_enum CODEC_ID_ADPCM_IMA_DK4}+#{add_enum CODEC_ID_ADPCM_IMA_WS}+#{add_enum CODEC_ID_ADPCM_IMA_SMJPEG}+#{add_enum CODEC_ID_ADPCM_MS}+#{add_enum CODEC_ID_ADPCM_4XM}+#{add_enum CODEC_ID_ADPCM_XA}+#{add_enum CODEC_ID_ADPCM_ADX}+#{add_enum CODEC_ID_ADPCM_EA}+#{add_enum CODEC_ID_ADPCM_G726}+#{add_enum CODEC_ID_ADPCM_CT}+#{add_enum CODEC_ID_ADPCM_SWF}+#{add_enum CODEC_ID_ADPCM_YAMAHA}+#{add_enum CODEC_ID_ADPCM_SBPRO_4}+#{add_enum CODEC_ID_ADPCM_SBPRO_3}+#{add_enum CODEC_ID_ADPCM_SBPRO_2}+#{add_enum CODEC_ID_ADPCM_THP}+#{add_enum CODEC_ID_ADPCM_IMA_AMV}+#{add_enum CODEC_ID_ADPCM_EA_R1}+#{add_enum CODEC_ID_ADPCM_EA_R3}+#{add_enum CODEC_ID_ADPCM_EA_R2}+#{add_enum CODEC_ID_ADPCM_IMA_EA_SEAD}+#{add_enum CODEC_ID_ADPCM_IMA_EA_EACS}+#{add_enum CODEC_ID_ADPCM_EA_XAS}+#{add_enum CODEC_ID_ADPCM_EA_MAXIS_XA}+#{add_enum CODEC_ID_ADPCM_IMA_ISS}+#{add_enum CODEC_ID_AMR_NB}+#{add_enum CODEC_ID_AMR_WB}+#{add_enum CODEC_ID_RA_144}+#{add_enum CODEC_ID_RA_288}+#{add_enum CODEC_ID_ROQ_DPCM}+#{add_enum CODEC_ID_INTERPLAY_DPCM}+#{add_enum CODEC_ID_XAN_DPCM}+#{add_enum CODEC_ID_SOL_DPCM}+#{add_enum CODEC_ID_MP2}+#{add_enum CODEC_ID_MP3}+#{add_enum CODEC_ID_AAC}+#{add_enum CODEC_ID_AC3}+#{add_enum CODEC_ID_DTS}+#{add_enum CODEC_ID_VORBIS}+#{add_enum CODEC_ID_DVAUDIO}+#{add_enum CODEC_ID_WMAV1}+#{add_enum CODEC_ID_WMAV2}+#{add_enum CODEC_ID_MACE3}+#{add_enum CODEC_ID_MACE6}+#{add_enum CODEC_ID_VMDAUDIO}+#{add_enum CODEC_ID_SONIC}+#{add_enum CODEC_ID_SONIC_LS}+#{add_enum CODEC_ID_FLAC}+#{add_enum CODEC_ID_MP3ADU}+#{add_enum CODEC_ID_MP3ON4}+#{add_enum CODEC_ID_SHORTEN}+#{add_enum CODEC_ID_ALAC}+#{add_enum CODEC_ID_WESTWOOD_SND1}+#{add_enum CODEC_ID_GSM}+#{add_enum CODEC_ID_QDM2}+#{add_enum CODEC_ID_COOK}+#{add_enum CODEC_ID_TRUESPEECH}+#{add_enum CODEC_ID_TTA}+#{add_enum CODEC_ID_SMACKAUDIO}+#{add_enum CODEC_ID_QCELP}+#{add_enum CODEC_ID_WAVPACK}+#{add_enum CODEC_ID_DSICINAUDIO}+#{add_enum CODEC_ID_IMC}+#{add_enum CODEC_ID_MUSEPACK7}+#{add_enum CODEC_ID_MLP}+#{add_enum CODEC_ID_GSM_MS}+#{add_enum CODEC_ID_ATRAC3}+#{add_enum CODEC_ID_VOXWARE}+#{add_enum CODEC_ID_APE}+#{add_enum CODEC_ID_NELLYMOSER}+#{add_enum CODEC_ID_MUSEPACK8}+#{add_enum CODEC_ID_SPEEX}+#{add_enum CODEC_ID_WMAVOICE}+#{add_enum CODEC_ID_WMAPRO}+#{add_enum CODEC_ID_WMALOSSLESS}+#{add_enum CODEC_ID_ATRAC3P}+#{add_enum CODEC_ID_EAC3}+#{add_enum CODEC_ID_SIPR}+#{add_enum CODEC_ID_MP1}+#{add_enum CODEC_ID_TWINVQ}+#{add_enum CODEC_ID_TRUEHD}+#{add_enum CODEC_ID_DVD_SUBTITLE}+#{add_enum CODEC_ID_DVB_SUBTITLE}+#{add_enum CODEC_ID_TEXT}+#{add_enum CODEC_ID_XSUB}+#{add_enum CODEC_ID_SSA}+#{add_enum CODEC_ID_MOV_TEXT}+#{add_enum CODEC_ID_TTF}+#{add_enum CODEC_ID_PROBE}+#{add_enum CODEC_ID_MPEG2TS}+#{end_enum "Eq,Ord,Show"}+++
+ src/Media/FFMpeg/Common.hsc view
@@ -0,0 +1,51 @@+-- -*- haskell -*-+{-# LANGUAGE ForeignFunctionInterface, ScopedTypeVariables #-}++{- |Module 'Media.FFMpeg.Common' common definitions and helpers++ (c) 2009 Vasyl Pasternak+ -}++module Media.FFMpeg.Common + (+ ExternalPointer (..)+ ,cToInt+ ,cFromInt+ ,cToEnum+ ,cFromEnum+ ,justPtr+ ,combineBitMasks+ )where++-- +-- |ExternalPointer class, used to define method withThis+-- similar to 'Foreign.Marshal.Utils.with' but without need Storable specifier+--++import Foreign.Ptr (Ptr, nullPtr)+import Data.Bits (Bits, (.|.))++class ExternalPointer a where+ withThis :: a -> (Ptr b -> IO c) -> IO c++--+-- Some conversion functions+--+cToInt :: (Integral a) => a -> Int+cToInt = fromIntegral++cFromInt :: (Num a) => Int -> a +cFromInt = fromIntegral++cToEnum :: (Integral a, Enum b) => a -> b+cToEnum = toEnum . fromIntegral++cFromEnum :: (Enum a, Num b) => a -> b+cFromEnum = fromIntegral . fromEnum++justPtr :: Ptr a -> Maybe (Ptr a)+justPtr p | p == nullPtr = Nothing+ | otherwise = Just p++combineBitMasks :: (Enum a, Bits b) => [a] -> b+combineBitMasks = foldl (.|.) 0 . map cFromEnum
src/Media/FFMpeg/Format.hsc view
@@ -1,5 +1,5 @@ -- -*- haskell -*--{-# LANGUAGE ForeignFunctionInterface, ScopedTypeVariables #-}+{-# LANGUAGE ForeignFunctionInterface #-} {- |Module 'Media.FFMpeg.Format' implements bindings to AVFormat library @@ -8,24 +8,158 @@ module Media.FFMpeg.Format (- registerAll+ libAVFormatVersion+ ,registerAll ,withFFMpeg- ,module Media.FFMpeg.Internals++ ,FormatContext+ ,findStreamInfo+ ,dumpFormat+ ,newContext+ ,openInputFile++ ,Stream+ ,getStreams+ ,getCodecContext+ ,readFrame ) where +#include "libavformat/avformat.h"+ import Foreign+import Foreign.C.Types import Foreign.C.String-import Media.FFMpeg.Internals-import Text.Printf+import Data.Version+import Control.Monad (liftM)+import Text.Printf (printf) -#include "libavformat/avformat.h"+import Media.FFMpeg.Common+import Media.FFMpeg.Util+import Media.FFMpeg.Codec --- | import defines-foreign import ccall "av_register_all" registerAll :: IO ()+libAVFormatVersion :: Version+libAVFormatVersion = Version {+ versionBranch = [+ #{const LIBAVFORMAT_VERSION_MAJOR},+ #{const LIBAVFORMAT_VERSION_MINOR},+ #{const LIBAVFORMAT_VERSION_MICRO}+ ],+ versionTags = []+ } +--+-- | registerAll, this should be the first instruction in before working wiht+-- ffmpeg library+--+foreign import ccall "av_register_all" registerAll :: IO ()++--+-- | control helper+-- withFFMpeg :: IO a -> IO a-withFFMpeg clos = registerAll >> clos+withFFMpeg io = registerAll >> io +-- |FormatContext - wrapper to AVFormatContext+newtype FormatContext = FormatContext (ForeignPtr FormatContext) +instance ExternalPointer FormatContext where+ withThis (FormatContext fmt) io = withForeignPtr fmt (io . castPtr)++--+-- | findStreamInfo+foreign import ccall "av_find_stream_info" _find_stream_info :: Ptr () -> IO CInt++findStreamInfo :: FormatContext -> IO ()+findStreamInfo fmt = + withThis fmt $ \fmt' -> + throwIf_ (< 0) + (printf "findStreamInfo: failed with error code %d\n" . cToInt) + (_find_stream_info fmt')++-- +-- | dumpFormat - outputs the format into console+--+foreign import ccall "dump_format" _dump_format :: + Ptr () -> CInt -> CString -> CInt -> IO ()++dumpFormat :: FormatContext -> String -> IO ()+dumpFormat fmt s =+ withThis fmt $ \fmt' ->+ withCString s $ \s' ->+ _dump_format fmt' 0 s' 0+++--+-- | newContext - allocates new FormatContext+--+foreign import ccall "avformat_alloc_context" _alloc_context :: IO (Ptr ())++newContext :: IO FormatContext+newContext = do + p <- throwIf (== nullPtr) + (\_ -> "allocContext: failed to allocate context") + _alloc_context+ liftM (FormatContext . castForeignPtr) $ newAvForeignPtr p++--+-- |openInputFile -- opens media file+--+foreign import ccall "av_open_input_file" _open_file :: + Ptr (Ptr ()) -> CString -> Ptr () -> CInt -> Ptr () -> IO CInt++foreign import ccall "av_close_input_file" _close_file ::+ Ptr a -> IO ()++openInputFile :: String -> IO FormatContext+openInputFile name = + withCString name $ \s ->+ alloca $ \pp -> do+ throwIf_ (/=0) + (printf "openInputFile: fail to open %s - errorcode %d\n" name . cToInt) $+ _open_file pp s nullPtr 0 nullPtr+ ptr <- peek pp+ liftM (FormatContext . castForeignPtr) $ newFinForeignPtr _close_file ptr+++--+-- |Stream - wrapper to AVStream+--+newtype Stream = Stream (Ptr Stream)++instance ExternalPointer Stream where+ withThis (Stream s) io = io (castPtr s)++--+-- |getStreams -- retrieve all streams from the FormatContext+--+getStreams :: FormatContext -> [Stream]+getStreams fmt = unsafePerformIO $+ withThis fmt $ \fmt' -> do+ count <- liftM fromIntegral $ + (#{peek AVFormatContext, nb_streams} fmt' :: IO CUInt)+ let streamsPtr = fmt' `plusPtr` #{offset AVFormatContext, streams}+ liftM (map Stream) $ peekArray count streamsPtr++--+-- |getCodecContext - reads codec context from the stream structure+--+getCodecContext :: Stream -> Maybe CodecContext+getCodecContext s = unsafePerformIO $ + withThis s $ \s' -> do+ p <- liftM justPtr $ (#{peek AVStream, codec} s' :: IO (Ptr ()))+ maybe (return Nothing) (liftM Just . toCodecContext) p+ ++--+-- |readFrame - reads frame from file, return False if error of EOF occured,+-- True otherwise+--+foreign import ccall "av_read_frame" _read_frame :: Ptr () -> Ptr () -> IO CInt++readFrame :: FormatContext -> Packet -> IO Bool+readFrame fmt pkt = + withThis fmt $ \fmt' ->+ withThis pkt $ \pkt' ->+ liftM (>= 0) $ _read_frame fmt' pkt'
− src/Media/FFMpeg/Internals.hsc
@@ -1,20 +0,0 @@--- -*- haskell -*---{- |The module 'Media.FFMpeg.Internals' implements helpers and- internal data representaion for the rest of 'hs-ffmpeg' library- - (c) 2009 Vasyl Pasternak- -}-module Media.FFMpeg.Internals - (- module Media.FFMpeg.Internals.Types- ,module Media.FFMpeg.Internals.Utils- ,module Media.FFMpeg.Internals.AVFormat- ,module Media.FFMpeg.Internals.AVCodec- ) where--import Media.FFMpeg.Internals.Types-import Media.FFMpeg.Internals.Utils-import Media.FFMpeg.Internals.AVFormat-import Media.FFMpeg.Internals.AVCodec hiding (toCodecContext)-
− src/Media/FFMpeg/Internals/AVCodec.hsc
@@ -1,541 +0,0 @@--- -*- haskell -*--{-# LANGUAGE ForeignFunctionInterface, ScopedTypeVariables #-}--{- | Module 'Media.FFMpeg.Internals.AVFormat' implements - avformat header (its structures and datatypes) along with - getters and setters to work with them- - (c) 2009 Vasyl Pasternak- -}--module Media.FFMpeg.Internals.AVCodec- (- -- Enumerations- CodecType (..)- ,CodecId (..)- - ,WithCodecType (..)- ,WithCodecId (..)- ,WithVideoProps (..)-- -- CodecContext - ,CodecContext- ,withCodecContext- ,toCodecContext- ,openCodec- ,decodeVideo- - -- Codec- ,Codec - ,withCodec- ,findDecoder- - -- Frame- ,Frame- ,withFrame- ,allocFrame-- -- Picture- ,CommonPicture (..)- ,pictureGetSize-- -- Packet- ,Packet- ,withPacket- ,allocPacket- ,cleanPacket- ,getStreamIndex- )where--import Foreign-import Foreign.C.String-import Control.Monad (liftM)-import Text.Printf-import Media.FFMpeg.Internals.Types-import Media.FFMpeg.Internals.Utils--#include "libavcodec/avcodec.h"-#include "macros.hsc2hs.h"----- |Different enumerations--- |CodecType-#{begin_enum CodecType, CODEC_TYPE_UNKNOWN}-#{add_enum CODEC_TYPE_VIDEO}-#{add_enum CODEC_TYPE_AUDIO}-#{add_enum CODEC_TYPE_DATA}-#{add_enum CODEC_TYPE_SUBTITLE}-#{add_enum CODEC_TYPE_ATTACHMENT}-#{add_enum CODEC_TYPE_NB}-#{end_enum "Eq,Ord,Show"}---- | CodecId-#{begin_enum CodecId, CODEC_ID_NONE}-#{add_enum CODEC_ID_MPEG1VIDEO}-#{add_enum CODEC_ID_MPEG2VIDEO}-#{add_enum CODEC_ID_MPEG2VIDEO_XVMC}-#{add_enum CODEC_ID_H261}-#{add_enum CODEC_ID_H263}-#{add_enum CODEC_ID_RV10}-#{add_enum CODEC_ID_RV20}-#{add_enum CODEC_ID_MJPEG}-#{add_enum CODEC_ID_MJPEGB}-#{add_enum CODEC_ID_LJPEG}-#{add_enum CODEC_ID_SP5X}-#{add_enum CODEC_ID_JPEGLS}-#{add_enum CODEC_ID_MPEG4}-#{add_enum CODEC_ID_RAWVIDEO}-#{add_enum CODEC_ID_MSMPEG4V1}-#{add_enum CODEC_ID_MSMPEG4V2}-#{add_enum CODEC_ID_MSMPEG4V3}-#{add_enum CODEC_ID_WMV1}-#{add_enum CODEC_ID_WMV2}-#{add_enum CODEC_ID_H263P}-#{add_enum CODEC_ID_H263I}-#{add_enum CODEC_ID_FLV1}-#{add_enum CODEC_ID_SVQ1}-#{add_enum CODEC_ID_SVQ3}-#{add_enum CODEC_ID_DVVIDEO}-#{add_enum CODEC_ID_HUFFYUV}-#{add_enum CODEC_ID_CYUV}-#{add_enum CODEC_ID_H264}-#{add_enum CODEC_ID_INDEO3}-#{add_enum CODEC_ID_VP3}-#{add_enum CODEC_ID_THEORA}-#{add_enum CODEC_ID_ASV1}-#{add_enum CODEC_ID_ASV2}-#{add_enum CODEC_ID_FFV1}-#{add_enum CODEC_ID_4XM}-#{add_enum CODEC_ID_VCR1}-#{add_enum CODEC_ID_CLJR}-#{add_enum CODEC_ID_MDEC}-#{add_enum CODEC_ID_ROQ}-#{add_enum CODEC_ID_INTERPLAY_VIDEO}-#{add_enum CODEC_ID_XAN_WC3}-#{add_enum CODEC_ID_XAN_WC4}-#{add_enum CODEC_ID_RPZA}-#{add_enum CODEC_ID_CINEPAK}-#{add_enum CODEC_ID_WS_VQA}-#{add_enum CODEC_ID_MSRLE}-#{add_enum CODEC_ID_MSVIDEO1}-#{add_enum CODEC_ID_IDCIN}-#{add_enum CODEC_ID_8BPS}-#{add_enum CODEC_ID_SMC}-#{add_enum CODEC_ID_FLIC}-#{add_enum CODEC_ID_TRUEMOTION1}-#{add_enum CODEC_ID_VMDVIDEO}-#{add_enum CODEC_ID_MSZH}-#{add_enum CODEC_ID_ZLIB}-#{add_enum CODEC_ID_QTRLE}-#{add_enum CODEC_ID_SNOW}-#{add_enum CODEC_ID_TSCC}-#{add_enum CODEC_ID_ULTI}-#{add_enum CODEC_ID_QDRAW}-#{add_enum CODEC_ID_VIXL}-#{add_enum CODEC_ID_QPEG}-#{add_enum CODEC_ID_XVID}-#{add_enum CODEC_ID_PNG}-#{add_enum CODEC_ID_PPM}-#{add_enum CODEC_ID_PBM}-#{add_enum CODEC_ID_PGM}-#{add_enum CODEC_ID_PGMYUV}-#{add_enum CODEC_ID_PAM}-#{add_enum CODEC_ID_FFVHUFF}-#{add_enum CODEC_ID_RV30}-#{add_enum CODEC_ID_RV40}-#{add_enum CODEC_ID_VC1}-#{add_enum CODEC_ID_WMV3}-#{add_enum CODEC_ID_LOCO}-#{add_enum CODEC_ID_WNV1}-#{add_enum CODEC_ID_AASC}-#{add_enum CODEC_ID_INDEO2}-#{add_enum CODEC_ID_FRAPS}-#{add_enum CODEC_ID_TRUEMOTION2}-#{add_enum CODEC_ID_BMP}-#{add_enum CODEC_ID_CSCD}-#{add_enum CODEC_ID_MMVIDEO}-#{add_enum CODEC_ID_ZMBV}-#{add_enum CODEC_ID_AVS}-#{add_enum CODEC_ID_SMACKVIDEO}-#{add_enum CODEC_ID_NUV}-#{add_enum CODEC_ID_KMVC}-#{add_enum CODEC_ID_FLASHSV}-#{add_enum CODEC_ID_CAVS}-#{add_enum CODEC_ID_JPEG2000}-#{add_enum CODEC_ID_VMNC}-#{add_enum CODEC_ID_VP5}-#{add_enum CODEC_ID_VP6}-#{add_enum CODEC_ID_VP6F}-#{add_enum CODEC_ID_TARGA}-#{add_enum CODEC_ID_DSICINVIDEO}-#{add_enum CODEC_ID_TIERTEXSEQVIDEO}-#{add_enum CODEC_ID_TIFF}-#{add_enum CODEC_ID_GIF}-#{add_enum CODEC_ID_FFH264}-#{add_enum CODEC_ID_DXA}-#{add_enum CODEC_ID_DNXHD}-#{add_enum CODEC_ID_THP}-#{add_enum CODEC_ID_SGI}-#{add_enum CODEC_ID_C93}-#{add_enum CODEC_ID_BETHSOFTVID}-#{add_enum CODEC_ID_PTX}-#{add_enum CODEC_ID_TXD}-#{add_enum CODEC_ID_VP6A}-#{add_enum CODEC_ID_AMV}-#{add_enum CODEC_ID_VB}-#{add_enum CODEC_ID_PCX}-#{add_enum CODEC_ID_SUNRAST}-#{add_enum CODEC_ID_INDEO4}-#{add_enum CODEC_ID_INDEO5}-#{add_enum CODEC_ID_MIMIC}-#{add_enum CODEC_ID_RL2}-#{add_enum CODEC_ID_8SVX_EXP}-#{add_enum CODEC_ID_8SVX_FIB}-#{add_enum CODEC_ID_ESCAPE124}-#{add_enum CODEC_ID_DIRAC}-#{add_enum CODEC_ID_BFI}-#{add_enum CODEC_ID_CMV}-#{add_enum CODEC_ID_MOTIONPIXELS}-#{add_enum CODEC_ID_TGV}-#{add_enum CODEC_ID_TGQ}-#{add_enum CODEC_ID_TQI}-#{add_enum CODEC_ID_AURA}-#{add_enum CODEC_ID_AURA2}-#{add_enum CODEC_ID_PCM_S16LE}-#{add_enum CODEC_ID_PCM_S16BE}-#{add_enum CODEC_ID_PCM_U16LE}-#{add_enum CODEC_ID_PCM_U16BE}-#{add_enum CODEC_ID_PCM_S8}-#{add_enum CODEC_ID_PCM_U8}-#{add_enum CODEC_ID_PCM_MULAW}-#{add_enum CODEC_ID_PCM_ALAW}-#{add_enum CODEC_ID_PCM_S32LE}-#{add_enum CODEC_ID_PCM_S32BE}-#{add_enum CODEC_ID_PCM_U32LE}-#{add_enum CODEC_ID_PCM_U32BE}-#{add_enum CODEC_ID_PCM_S24LE}-#{add_enum CODEC_ID_PCM_S24BE}-#{add_enum CODEC_ID_PCM_U24LE}-#{add_enum CODEC_ID_PCM_U24BE}-#{add_enum CODEC_ID_PCM_S24DAUD}-#{add_enum CODEC_ID_PCM_ZORK}-#{add_enum CODEC_ID_PCM_S16LE_PLANAR}-#{add_enum CODEC_ID_PCM_DVD}-#{add_enum CODEC_ID_PCM_F32BE}-#{add_enum CODEC_ID_PCM_F32LE}-#{add_enum CODEC_ID_PCM_F64BE}-#{add_enum CODEC_ID_PCM_F64LE}-#{add_enum CODEC_ID_ADPCM_IMA_QT}-#{add_enum CODEC_ID_ADPCM_IMA_WAV}-#{add_enum CODEC_ID_ADPCM_IMA_DK3}-#{add_enum CODEC_ID_ADPCM_IMA_DK4}-#{add_enum CODEC_ID_ADPCM_IMA_WS}-#{add_enum CODEC_ID_ADPCM_IMA_SMJPEG}-#{add_enum CODEC_ID_ADPCM_MS}-#{add_enum CODEC_ID_ADPCM_4XM}-#{add_enum CODEC_ID_ADPCM_XA}-#{add_enum CODEC_ID_ADPCM_ADX}-#{add_enum CODEC_ID_ADPCM_EA}-#{add_enum CODEC_ID_ADPCM_G726}-#{add_enum CODEC_ID_ADPCM_CT}-#{add_enum CODEC_ID_ADPCM_SWF}-#{add_enum CODEC_ID_ADPCM_YAMAHA}-#{add_enum CODEC_ID_ADPCM_SBPRO_4}-#{add_enum CODEC_ID_ADPCM_SBPRO_3}-#{add_enum CODEC_ID_ADPCM_SBPRO_2}-#{add_enum CODEC_ID_ADPCM_THP}-#{add_enum CODEC_ID_ADPCM_IMA_AMV}-#{add_enum CODEC_ID_ADPCM_EA_R1}-#{add_enum CODEC_ID_ADPCM_EA_R3}-#{add_enum CODEC_ID_ADPCM_EA_R2}-#{add_enum CODEC_ID_ADPCM_IMA_EA_SEAD}-#{add_enum CODEC_ID_ADPCM_IMA_EA_EACS}-#{add_enum CODEC_ID_ADPCM_EA_XAS}-#{add_enum CODEC_ID_ADPCM_EA_MAXIS_XA}-#{add_enum CODEC_ID_ADPCM_IMA_ISS}-#{add_enum CODEC_ID_AMR_NB}-#{add_enum CODEC_ID_AMR_WB}-#{add_enum CODEC_ID_RA_144}-#{add_enum CODEC_ID_RA_288}-#{add_enum CODEC_ID_ROQ_DPCM}-#{add_enum CODEC_ID_INTERPLAY_DPCM}-#{add_enum CODEC_ID_XAN_DPCM}-#{add_enum CODEC_ID_SOL_DPCM}-#{add_enum CODEC_ID_MP2}-#{add_enum CODEC_ID_MP3}-#{add_enum CODEC_ID_AAC}-#{add_enum CODEC_ID_AC3}-#{add_enum CODEC_ID_DTS}-#{add_enum CODEC_ID_VORBIS}-#{add_enum CODEC_ID_DVAUDIO}-#{add_enum CODEC_ID_WMAV1}-#{add_enum CODEC_ID_WMAV2}-#{add_enum CODEC_ID_MACE3}-#{add_enum CODEC_ID_MACE6}-#{add_enum CODEC_ID_VMDAUDIO}-#{add_enum CODEC_ID_SONIC}-#{add_enum CODEC_ID_SONIC_LS}-#{add_enum CODEC_ID_FLAC}-#{add_enum CODEC_ID_MP3ADU}-#{add_enum CODEC_ID_MP3ON4}-#{add_enum CODEC_ID_SHORTEN}-#{add_enum CODEC_ID_ALAC}-#{add_enum CODEC_ID_WESTWOOD_SND1}-#{add_enum CODEC_ID_GSM}-#{add_enum CODEC_ID_QDM2}-#{add_enum CODEC_ID_COOK}-#{add_enum CODEC_ID_TRUESPEECH}-#{add_enum CODEC_ID_TTA}-#{add_enum CODEC_ID_SMACKAUDIO}-#{add_enum CODEC_ID_QCELP}-#{add_enum CODEC_ID_WAVPACK}-#{add_enum CODEC_ID_DSICINAUDIO}-#{add_enum CODEC_ID_IMC}-#{add_enum CODEC_ID_MUSEPACK7}-#{add_enum CODEC_ID_MLP}-#{add_enum CODEC_ID_GSM_MS}-#{add_enum CODEC_ID_ATRAC3}-#{add_enum CODEC_ID_VOXWARE}-#{add_enum CODEC_ID_APE}-#{add_enum CODEC_ID_NELLYMOSER}-#{add_enum CODEC_ID_MUSEPACK8}-#{add_enum CODEC_ID_SPEEX}-#{add_enum CODEC_ID_WMAVOICE}-#{add_enum CODEC_ID_WMAPRO}-#{add_enum CODEC_ID_WMALOSSLESS}-#{add_enum CODEC_ID_ATRAC3P}-#{add_enum CODEC_ID_EAC3}-#{add_enum CODEC_ID_SIPR}-#{add_enum CODEC_ID_MP1}-#{add_enum CODEC_ID_TWINVQ}-#{add_enum CODEC_ID_TRUEHD}-#{add_enum CODEC_ID_DVD_SUBTITLE}-#{add_enum CODEC_ID_DVB_SUBTITLE}-#{add_enum CODEC_ID_TEXT}-#{add_enum CODEC_ID_XSUB}-#{add_enum CODEC_ID_SSA}-#{add_enum CODEC_ID_MOV_TEXT}-#{add_enum CODEC_ID_TTF}-#{add_enum CODEC_ID_PROBE}-#{add_enum CODEC_ID_MPEG2TS}-#{end_enum "Eq,Ord,Show"}---class WithCodecId a where- getCodecId :: a -> CodecId--class WithCodecType a where- getCodecType :: a -> CodecType--class WithVideoProps a where- getVideoWidth :: a -> Int- getVideoHeight :: a -> Int- getPixelFormat :: a -> PixelFormat---- |CodecContext - wrapper to AVCodecContext-newtype CodecContext = CodecContext (ForeignPtr CodecContext)--withCodecContext :: CodecContext -> (Ptr a -> IO b) -> IO b-withCodecContext (CodecContext ctx) clos = withForeignPtr ctx (clos . castPtr)--toCodecContext :: Ptr a -> IO CodecContext-toCodecContext p = liftM CodecContext $ (newForeignPtr_ . castPtr) p--instance WithCodecId CodecContext where- getCodecId ctx = - unsafePerformIO $- withCodecContext ctx $ \ctx' -> - do- val <- #{peek AVCodecContext, codec_id} ctx' :: IO #{type enum CodecID}- return $ (toEnum . fromIntegral) val--instance WithCodecType CodecContext where- getCodecType ctx = - unsafePerformIO $- withCodecContext ctx $ \ctx' -> - do- val <- #{peek AVCodecContext, codec_type} ctx' :: IO #{type enum CodecType}- return $ (toEnum . fromIntegral) val--instance WithVideoProps CodecContext where- getVideoWidth ctx = - unsafePerformIO $- withCodecContext ctx $ \ctx' ->- liftM fromIntegral $ (#{peek AVCodecContext, width} ctx' :: IO #{type int})-- getVideoHeight ctx =- unsafePerformIO $- withCodecContext ctx $ \ctx' -> - liftM fromIntegral $ (#{peek AVCodecContext, height} ctx' :: IO #{type int})-- getPixelFormat ctx = - unsafePerformIO $ - withCodecContext ctx $ \ctx' ->- do- val <- #{peek AVCodecContext, pix_fmt} ctx' :: IO #{type enum PixelFormat}- return $ (toEnum . fromIntegral) val---- |CodecContext function-foreign import ccall "avcodec_open" _open :: VoidP -> VoidP -> IO SInt-foreign import ccall "avcodec_close" _close :: VoidP -> IO ()--openCodec :: CodecContext -> Codec -> IO ()-openCodec ctx@(CodecContext ct) c = - withCodecContext ctx $ \ctx' ->- withCodec c $ \c' -> do- throwIf_ (<0)- (printf "openCodec: fails to open codec '%s' - errorcode %d\n" (show $ getCodecId c)) $ _open ctx' c'- finalizer <- mkFinalizerPtr _close- addForeignPtrFinalizer finalizer (castForeignPtr ct)----- |CodecContext getters/setters-- ---- |Codec - implementation of AVCodec-newtype Codec = Codec (Ptr Codec)--withCodec :: Codec -> (Ptr a -> IO b) -> IO b-withCodec (Codec c) clos = clos (castPtr c)----- |Codec getters/setters-instance WithCodecId Codec where- getCodecId ctx = - unsafePerformIO $- withCodec ctx $ \ctx' -> - do- val <- #{peek AVCodec, id} ctx' :: IO #{type enum CodecID}- return $ (toEnum . fromIntegral) val--instance WithCodecType Codec where- getCodecType ctx = - unsafePerformIO $- withCodec ctx $ \ctx' -> - do- val <- #{peek AVCodec, type} ctx' :: IO #{type enum CodecType}- return $ (toEnum . fromIntegral) val----- |Codec functions--foreign import ccall "avcodec_find_decoder" _find_decoder :: #{type enum CodecID} -> IO VoidP--findDecoder :: CodecId -> IO (Maybe Codec)-findDecoder cid = do- res <- _find_decoder (fromIntegral $ fromEnum cid)- if res == nullPtr then return Nothing else return $ Just $ Codec $ castPtr res---foreign import ccall "avcodec_decode_video2" _decode_video :: - VoidP -> VoidP -> (Ptr SInt) -> VoidP -> IO SInt---- | returns True if complete picture is decompressed-decodeVideo :: CodecContext -> Frame -> Packet -> IO Bool-decodeVideo ctx frm pkt = - withCodecContext ctx $ \ctx' ->- withFrame frm $ \frm' ->- withPacket pkt $ \pkt' ->- alloca $ \gotPic' -> do- throwIf (<0)- (printf "decodeVideo: failed to decode video packet: %d")- (_decode_video ctx' frm' gotPic' pkt')- peek gotPic' >>= return . (>0)----- |AVFrame implementation-newtype Frame = Frame (ForeignPtr Frame)--withFrame :: Frame -> (Ptr a -> IO b) -> IO b-withFrame (Frame f) clos = withForeignPtr f (clos . castPtr)--foreign import ccall "avcodec_alloc_frame" _alloc_frame :: IO VoidP--allocFrame :: IO Frame-allocFrame = do- p <- throwIf (== nullPtr)- (\_ -> "allocFrame: failed to allocate frame")- _alloc_frame- finalizer <- mkFinalizerPtr avFree- newForeignPtr finalizer p >>= return . Frame . castForeignPtr--instance CommonPicture Frame where- withCPicture = withFrame----- |AVPicture ---foreign import ccall "avpicture_fill" _picture_fill ::- VoidP -> VoidP -> #{type int} -> #{type int} -> #{type int} -> IO #{type int}--type CPicture = VoidP--class CommonPicture a where- withCPicture :: a -> (CPicture -> IO b) -> IO b-- pictureFill :: a -> Buffer -> PixelFormat -> Int -> Int -> IO ()- pictureFill pic buff pf w h = - withCPicture pic $ \pic' ->- withBuffer buff $ \buff' -> - _picture_fill pic' (castPtr buff') - (fromIntegral $ fromEnum pf)- (fromIntegral w)- (fromIntegral h) >> return ()- - getPictureSlice :: a -> PictureSlice- getPictureSlice pic =- unsafePerformIO $- withCPicture pic $ \pic' ->- return $ castPtr $ pic' `plusPtr` #{offset AVPicture, data}-- getPictureStride :: a -> PictureStride- getPictureStride pic = - unsafePerformIO $- withCPicture pic $ \pic' ->- return $ castPtr $ pic' `plusPtr` #{offset AVPicture, linesize}----- |Other functions- -foreign import ccall "avpicture_get_size" _picture_get_size :: - #{type enum PixelFormat} -> #{type int} -> #{type int} -> IO (#{type int})--pictureGetSize :: PixelFormat -> Int -> Int -> IO Int-pictureGetSize pf w h = do- liftM fromIntegral $ - (_picture_get_size ((fromIntegral . fromEnum) pf) (fromIntegral w) (fromIntegral h) :: IO (#{type int}))- ---- |AVPacket--newtype Packet = Packet (ForeignPtr Packet)--withPacket :: Packet -> (Ptr a -> IO b) -> IO b-withPacket (Packet p) clos = withForeignPtr p (clos . castPtr)--foreign import ccall "av_init_packet" _init_packet :: VoidP -> IO ()-foreign import ccall "b_free_packet" _free_packet :: VoidP -> IO ()--allocPacket :: IO Packet-allocPacket = do- p <- mallocBytes #{size AVPacket}- _init_packet p- fp <- newForeignPtr finalizerFree p- deinit <- mkFinalizerPtr _free_packet- addForeignPtrFinalizer deinit fp - return $ Packet $ castForeignPtr fp--cleanPacket :: Packet -> IO ()-cleanPacket pkt = withPacket pkt _free_packet----- | AVPacket getters/setters--getStreamIndex :: Packet -> Int-getStreamIndex pkt = - unsafePerformIO $- withPacket pkt $ \pkt' ->- liftM fromIntegral $ - (#{peek AVPacket, stream_index} pkt' :: IO #{type int})
− src/Media/FFMpeg/Internals/AVFormat.hsc
@@ -1,142 +0,0 @@--- -*- haskell -*--{-# LANGUAGE ForeignFunctionInterface, ScopedTypeVariables #-}--{- | Module 'Media.FFMpeg.Internals.AVFormat' implements - avformat header (its structures and datatypes) along with - getters and setters to work with them- - (c) 2009 Vasyl Pasternak- -}--module Media.FFMpeg.Internals.AVFormat - (- -- FormatContext - FormatContext- ,withFormatContext- ,newContext- ,openInputFile- ,getStreams- ,findStreamInfo- ,dumpFormat-- -- Stream- ,Stream- ,withStream- ,getCodecContext-- -- Other- ,readFrame- )where--import Foreign-import Foreign.C.String-import Control.Monad (liftM)-import Text.Printf-import Media.FFMpeg.Internals.Types-import Media.FFMpeg.Internals.Utils-import Media.FFMpeg.Internals.AVCodec--#include "libavformat/avformat.h"----- |FormatContext - wrapper to AVFormatContext-newtype FormatContext = FormatContext (ForeignPtr FormatContext)--withFormatContext :: FormatContext -> (Ptr a -> IO b) -> IO b-withFormatContext (FormatContext fmt) clos = withForeignPtr fmt (clos . castPtr)----- |Different functions on FormatContext--foreign import ccall "av_find_stream_info" _find_stream_info :: VoidP -> IO SInt--findStreamInfo :: FormatContext -> IO ()-findStreamInfo fmt = - withFormatContext fmt $ \fmt' -> - throwIf_ (< 0) (printf "findStreamInfo: failed with error code %d\n") - (_find_stream_info fmt')- --foreign import ccall "dump_format" _dump_format :: VoidP -> SInt -> CString -> SInt -> IO ()--dumpFormat :: FormatContext -> String -> IO ()-dumpFormat fmt s =- withFormatContext fmt $ \fmt' ->- withCString s $ \s' ->- _dump_format fmt' 0 s' 0------ |Stream -- wrapper to AVStream-newtype Stream = Stream (Ptr Stream)--withStream :: Stream -> (VoidP -> IO a) -> IO a-withStream (Stream s) clos = clos (castPtr s)----- |Foreign declarations--foreign import ccall "avformat_alloc_context" _alloc_context :: IO VoidP--foreign import ccall "av_open_input_file" _open_file :: - Ptr (VoidP) -> CString -> VoidP -> SInt -> VoidP -> IO SInt--foreign import ccall "av_close_input_file" _close_file ::- Ptr a -> IO ()----- |FormatContext functions---- |Empty context creation-newContext :: IO FormatContext-newContext = do - p <- throwIf (== nullPtr) - (\_ -> "allocContext: failed to allocate context") - _alloc_context- finalizer <- mkFinalizerPtr avFree- newForeignPtr finalizer p >>= return . FormatContext . castForeignPtr- ---- |Open input file-openInputFile :: String -> IO FormatContext-openInputFile name = - withCString name $ \s ->- alloca $ \ (pp :: (Ptr VoidP)) -> do- throwIf_ (/=0) - (printf "openInputFile: fail to open %s - errorcode %d\n" name) $- _open_file pp s nullPtr 0 nullPtr- ptr <- peek pp- finalizer <- mkFinalizerPtr _close_file- newForeignPtr finalizer ptr >>= return . FormatContext . castForeignPtr----- | FormatContext getters/setters---- |Get streams from FormatContext. Pure, because it is--- field of already allocated structure-getStreams :: FormatContext -> [Stream]-getStreams fmt = unsafePerformIO $- withFormatContext fmt $ \fmt' -> do- count <- liftM fromIntegral $ - (#{peek AVFormatContext, nb_streams} fmt' :: IO UInt)- let streamList = fmt' `plusPtr` #{offset AVFormatContext, streams} - peekArray count streamList >>= return . map Stream - ---- | Stream getters/setters--getCodecContext :: Stream -> Maybe CodecContext-getCodecContext s = unsafePerformIO $- withStream s $ \s' -> do- p <- #{peek AVStream, codec} s' :: IO VoidP- if p == nullPtr then return Nothing else liftM Just $ toCodecContext p--foreign import ccall "av_read_frame" _read_frame :: VoidP -> VoidP -> IO SInt---- |returns False if error or EOF occured, True otherwise-readFrame :: FormatContext -> Packet -> IO Bool-readFrame ctx pkt = - withFormatContext ctx $ \ctx' ->- withPacket pkt $ \pkt' -> do- ret <- _read_frame ctx' pkt'- return $ ret >= 0
− src/Media/FFMpeg/Internals/SWScale.hsc
@@ -1,87 +0,0 @@--- -*- haskell -*--{-# LANGUAGE ForeignFunctionInterface, ScopedTypeVariables #-}--{- | Module 'Media.FFMpeg.Internals.SWScale' implements - swscale header (its structures and datatypes) along with - getters and setters to work with them- - (c) 2009 Vasyl Pasternak- -}--module Media.FFMpeg.Internals.SWScale- (- -- Enumerations- ScaleAlgorithm (..)-- -- Context- ,Context- ,getContext- ,scale- ) where--import Foreign-import Foreign.C.String-import Control.Monad (liftM)-import Text.Printf-import Media.FFMpeg.Internals.Types-import Media.FFMpeg.Internals.Utils--#include "libswscale/swscale.h"-#include "macros.hsc2hs.h"----- |Enumerations-#{begin_enum ScaleAlgorithm, SWS_FAST_BILINEAR}-#{add_enum SWS_BICUBIC}-#{add_enum SWS_X}-#{add_enum SWS_POINT}-#{add_enum SWS_AREA}-#{add_enum SWS_BICUBLIN}-#{add_enum SWS_GAUSS}-#{add_enum SWS_SINC}-#{add_enum SWS_LANCZOS}-#{add_enum SWS_SPLINE}-#{end_enum "Eq,Ord,Show"}---- |SwsContext--newtype Context = Context (ForeignPtr Context)--withContext :: Context -> (Ptr a -> IO b) -> IO b-withContext (Context ctx) clos = withForeignPtr ctx (clos . castPtr)--foreign import ccall "sws_freeContext" _free_context :: VoidP -> IO ()--foreign import ccall "sws_getContext" _get_context :: - SInt -> SInt -> #{type enum PixelFormat} -> - SInt -> SInt -> #{type enum PixelFormat} ->- SInt -> VoidP -> VoidP -> VoidP -> IO VoidP--combineBitMasks :: (Enum a, Bits b) => [a] -> b-combineBitMasks = foldl (.|.) 0 . map (fromIntegral . fromEnum)--getContext :: (Int, Int, PixelFormat) ->- (Int, Int, PixelFormat) ->- [ScaleAlgorithm] -> IO Context-getContext (srcW, srcH, srcPf) (dstW, dstH, dstPf) flags = do- ret <- throwIf (== nullPtr) - (\_ -> "getContext: failed to create SWScale context") $- _get_context (fromIntegral srcW) (fromIntegral srcH) (fromIntegral $ fromEnum srcPf)- (fromIntegral dstW) (fromIntegral dstH) (fromIntegral $ fromEnum dstPf) - (combineBitMasks flags) nullPtr nullPtr nullPtr - finalizer <- mkFinalizerPtr _free_context- newForeignPtr finalizer ret >>= return . Context . castForeignPtr--foreign import ccall "sws_scale" _sws_scale ::- VoidP -> VoidP -> VoidP -> SInt -> SInt -> VoidP -> VoidP -> IO SInt--scale :: Context -> PictureSlice -> PictureStride -> Int -> Int -> - PictureSlice -> PictureStride -> IO ()-scale ctx srcSlice srcStride srcSliceY srcSliceH dstSlice dstStride = - withContext ctx $ \ctx' -> - _sws_scale ctx' srcSlice srcStride - (fromIntegral srcSliceY) - (fromIntegral srcSliceH) - dstSlice dstStride >> - return ()-
− src/Media/FFMpeg/Internals/Types.hsc
@@ -1,25 +0,0 @@--- -*- haskell -*--{-# LANGUAGE ForeignFunctionInterface #-}--{- |The 'Media.FFMpeg.Internals.Types' module defines types and - structures from the ffmpeg library- - (c) 2009 Vasyl Pasternak- -}-module Media.FFMpeg.Internals.Types- (- UInt- ,VoidP- ,SInt- ,PictureSlice- ,PictureStride- ) where--import Foreign--type UInt = #{type unsigned int}-type SInt = #{type int}-type VoidP = Ptr ()--type PictureSlice = Ptr ()-type PictureStride = Ptr ()
− src/Media/FFMpeg/Internals/Utils.hsc
@@ -1,126 +0,0 @@--- -*- haskell -*- -{-# LANGUAGE ForeignFunctionInterface #-}--{- | Module 'Media.FFMpeg.Internals.Utils' implements - utility functions from libAVUtil library- - (c) 2009 Vasyl Pasternak- -}--module Media.FFMpeg.Internals.Utils - (- PixelFormat (..)- ,avMalloc- ,avFree- ,mkFinalizerPtr-- -- Buffer datatype- ,Buffer- ,withBuffer- ,allocBuffer- ,makeBuffer- )where--import Foreign-import Media.FFMpeg.Internals.Types--#include "libavutil/avutil.h"-#include "macros.hsc2hs.h"---- |PixelFormat enumeration-#{begin_enum PixelFormat, PIX_FMT_NONE}-#{add_enum PIX_FMT_YUV420P}-#{add_enum PIX_FMT_YUYV422}-#{add_enum PIX_FMT_RGB24}-#{add_enum PIX_FMT_BGR24}-#{add_enum PIX_FMT_YUV422P}-#{add_enum PIX_FMT_YUV444P}-#{add_enum PIX_FMT_YUV410P}-#{add_enum PIX_FMT_YUV411P}-#{add_enum PIX_FMT_GRAY8}-#{add_enum PIX_FMT_MONOWHITE}-#{add_enum PIX_FMT_MONOBLACK}-#{add_enum PIX_FMT_PAL8}-#{add_enum PIX_FMT_YUVJ420P}-#{add_enum PIX_FMT_YUVJ422P}-#{add_enum PIX_FMT_YUVJ444P}-#{add_enum PIX_FMT_XVMC_MPEG2_MC}-#{add_enum PIX_FMT_XVMC_MPEG2_IDCT}-#{add_enum PIX_FMT_UYVY422}-#{add_enum PIX_FMT_UYYVYY411}-#{add_enum PIX_FMT_BGR8}-#{add_enum PIX_FMT_BGR4}-#{add_enum PIX_FMT_BGR4_BYTE}-#{add_enum PIX_FMT_RGB8}-#{add_enum PIX_FMT_RGB4}-#{add_enum PIX_FMT_RGB4_BYTE}-#{add_enum PIX_FMT_NV12}-#{add_enum PIX_FMT_NV21}-#{add_enum PIX_FMT_ARGB}-#{add_enum PIX_FMT_RGBA}-#{add_enum PIX_FMT_ABGR}-#{add_enum PIX_FMT_BGRA}-#{add_enum PIX_FMT_GRAY16BE}-#{add_enum PIX_FMT_GRAY16LE}-#{add_enum PIX_FMT_YUV440P}-#{add_enum PIX_FMT_YUVJ440P}-#{add_enum PIX_FMT_YUVA420P}-#{add_enum PIX_FMT_VDPAU_H264}-#{add_enum PIX_FMT_VDPAU_MPEG1}-#{add_enum PIX_FMT_VDPAU_MPEG2}-#{add_enum PIX_FMT_VDPAU_WMV3}-#{add_enum PIX_FMT_VDPAU_VC1}-#{add_enum PIX_FMT_RGB48BE}-#{add_enum PIX_FMT_RGB48LE}-#{add_enum PIX_FMT_RGB565BE}-#{add_enum PIX_FMT_RGB565LE}-#{add_enum PIX_FMT_RGB555BE}-#{add_enum PIX_FMT_RGB555LE}-#{add_enum PIX_FMT_BGR565BE}-#{add_enum PIX_FMT_BGR565LE}-#{add_enum PIX_FMT_BGR555BE}-#{add_enum PIX_FMT_BGR555LE}-#{add_enum PIX_FMT_VAAPI_MOCO}-#{add_enum PIX_FMT_VAAPI_IDCT}-#{add_enum PIX_FMT_VAAPI_VLD}-#{add_enum PIX_FMT_NB}-#{add_enum PIX_FMT_RGB32}-#{add_enum PIX_FMT_RGB32_1}-#{add_enum PIX_FMT_BGR32}-#{add_enum PIX_FMT_BGR32_1}-#{add_enum PIX_FMT_GRAY16}-#{add_enum PIX_FMT_RGB48}-#{add_enum PIX_FMT_RGB565}-#{add_enum PIX_FMT_RGB555}-#{add_enum PIX_FMT_BGR565}-#{add_enum PIX_FMT_BGR555}-#{end_enum "Eq, Ord, Show"}--foreign import ccall "av_malloc" _malloc :: UInt -> IO VoidP-foreign import ccall "av_free" avFree :: Ptr a -> IO ()--avMalloc :: Integral a => a -> IO (Maybe VoidP)-avMalloc a = do - ptr <- _malloc (fromIntegral a)- return $ if ptr == nullPtr then Nothing else Just ptr --foreign import ccall "wrapper" mkFinalizerPtr :: - (Ptr a -> IO ()) -> IO (FunPtr (Ptr a -> IO ()))----- |Buffer type. -newtype Buffer = Buffer (ForeignPtr Buffer)--withBuffer :: Buffer -> (Ptr a -> IO b) -> IO b-withBuffer (Buffer b) clos = withForeignPtr b (clos . castPtr)--allocBuffer :: Int -> IO Buffer-allocBuffer size = do- p <- throwIf (== nullPtr)- (\_ -> "allocBuffer: failed to allocate buffer")- (_malloc (fromIntegral size))- finalizer <- mkFinalizerPtr avFree- newForeignPtr finalizer p >>= return . Buffer . castForeignPtr--makeBuffer :: Ptr a -> IO Buffer-makeBuffer p = newForeignPtr_ p >>= return . Buffer . castForeignPtr
− src/Media/FFMpeg/Internals/_c_utils.c
@@ -1,6 +0,0 @@---#include <libavcodec/avcodec.h>--void b_free_packet (AVPacket* pkt){ av_free_packet (pkt);}-
+ src/Media/FFMpeg/SWScale.hsc view
@@ -0,0 +1,86 @@+-- -*- haskell -*-+{-# LANGUAGE ForeignFunctionInterface #-}++{- |Module 'Media.FFMpeg.SWScale' implements bindings to SWScale library++ (c) 2009 Vasyl Pasternak+ -}++module Media.FFMpeg.SWScale + (+ libSWScaleVersion+ ,module Media.FFMpeg.SWScaleEnums_++ ,Context+ ,scale+ ,getContext++ )where++#include "libswscale/swscale.h"++import Data.Version+import Foreign+import Foreign.C.Types+import Control.Monad (liftM)++import Media.FFMpeg.Common+import Media.FFMpeg.Util+import Media.FFMpeg.SWScaleEnums_++libSWScaleVersion :: Version+libSWScaleVersion = Version {+ versionBranch = [+ #{const LIBSWSCALE_VERSION_MAJOR},+ #{const LIBSWSCALE_VERSION_MINOR},+ #{const LIBSWSCALE_VERSION_MICRO}+ ],+ versionTags = []+ }++-- +-- |Context -- SwsContext implementation +--+newtype Context = Context (ForeignPtr Context)++instance ExternalPointer Context where+ withThis (Context ctx) io = withForeignPtr ctx (io . castPtr)+++--+-- |getContext - return SWScale context+--++foreign import ccall "sws_getContext" _sws_getContext :: + CInt -> CInt -> #{type enum PixelFormat} -> + CInt -> CInt -> #{type enum PixelFormat} ->+ CInt -> Ptr () -> Ptr () -> Ptr () -> IO (Ptr ())++foreign import ccall "sws_freeContext" _sws_freeContext :: Ptr () -> IO ()++getContext :: (Int, Int, PixelFormat) ->+ (Int, Int, PixelFormat) ->+ [ScaleAlgorithm] -> IO Context+getContext (srcW, srcH, srcPf) (dstW, dstH, dstPf) flags = do+ ret <- throwIf (==nullPtr)+ (\_ -> "getContext: failed to create SWScale context")+ (_sws_getContext (cFromInt srcW) (cFromInt srcH) (cFromEnum srcPf)+ (cFromInt dstW) (cFromInt dstH) (cFromEnum dstPf)+ (combineBitMasks flags) nullPtr nullPtr nullPtr)+ liftM (Context . castForeignPtr) $ newFinForeignPtr _sws_freeContext ret+ ++--+-- | scale - a scale function+--++foreign import ccall "sws_scale" _sws_scale ::+ Ptr () -> Ptr () -> Ptr () -> CInt -> CInt -> Ptr () -> Ptr () -> IO CInt++scale :: Context -> Ptr () -> Ptr () -> Int -> Int -> Ptr () -> Ptr () -> IO ()+scale ctx srcSlice srcStride srcSliceY srcSliceH dstSlice dstStride =+ withThis ctx $ \ctx' ->+ _sws_scale ctx' srcSlice srcStride + (cFromInt srcSliceY) (cFromInt srcSliceH)+ dstSlice dstStride >> return ()+
+ src/Media/FFMpeg/SWScaleEnums_.hsc view
@@ -0,0 +1,31 @@+-- -*- haskell -*- +{-# LANGUAGE ForeignFunctionInterface #-}++{- | Module 'Media.FFMpeg.SWScaleEnums_' implements + enumeration from libswscale+ + (c) 2009 Vasyl Pasternak+ -}+++module Media.FFMpeg.SWScaleEnums_+ (+ ScaleAlgorithm (..)+ ) where++#include "libswscale/swscale.h"+#include "macros.hsc2hs.h"++-- |ScaleAlgorithm Enumeration+#{begin_enum ScaleAlgorithm, SWS_FAST_BILINEAR}+#{add_enum SWS_BICUBIC}+#{add_enum SWS_X}+#{add_enum SWS_POINT}+#{add_enum SWS_AREA}+#{add_enum SWS_BICUBLIN}+#{add_enum SWS_GAUSS}+#{add_enum SWS_SINC}+#{add_enum SWS_LANCZOS}+#{add_enum SWS_SPLINE}+#{end_enum "Eq,Ord,Show"}+
− src/Media/FFMpeg/Scale.hs
@@ -1,14 +0,0 @@--- -*- haskell -*--{-# LANGUAGE ForeignFunctionInterface, ScopedTypeVariables #-}--{- |Module 'Media.FFMpeg.Scale' implements bindings to SWScale library-- (c) 2009 Vasyl Pasternak- -}--module Media.FFMpeg.Scale - (- module Media.FFMpeg.Internals.SWScale- ) where--import Media.FFMpeg.Internals.SWScale
− src/Media/FFMpeg/Types.hsc
@@ -1,12 +0,0 @@--- -*- haskell -*---{- |Module 'Media.FFMpeg.Types' defines common types of the ffmpeg library- -}--module Media.FFMpeg.Types - (- ) where--import Media.FFMpeg.Internals-import Foreign-
+ src/Media/FFMpeg/Util.hsc view
@@ -0,0 +1,126 @@+-- -*- haskell -*-+{-# LANGUAGE ForeignFunctionInterface, ScopedTypeVariables #-}++{- |Module 'Media.FFMpeg.Util' implements bindings to AVUtil library++ (c) 2009 Vasyl Pasternak+ -}++module Media.FFMpeg.Util + (+ module Media.FFMpeg.UtilEnums_++ ,avMalloc+ ,avFree++ ,mkFinalizerPtr+ ,avFinalizer+ ,newAvForeignPtr+ ,newFinForeignPtr++ ,Buffer+ ,bufferSize+ ,allocBuffer+ ,shiftBuffer+ ,castBuffer+ ,castBufferSize+ ,withBuffer+ ,unsafeBufferSetSize+ )where++import Foreign+import Foreign.C.Types+import Control.Monad (liftM)+import Text.Printf++import Media.FFMpeg.Common+import Media.FFMpeg.UtilEnums_++#include "libavutil/avutil.h"+++--+-- |avFree+-- +foreign import ccall "av_free" avFree :: Ptr a -> IO ()+++--+-- |avMalloc +-- +foreign import ccall "av_malloc" _malloc :: CUInt -> IO (Ptr())++avMalloc :: Integral a => a -> IO (Maybe (Ptr()))+avMalloc a = do + ptr <- _malloc (fromIntegral a)+ return $ if ptr == nullPtr then Nothing else Just ptr ++--+-- |mkFinalizerPtr+--+foreign import ccall "wrapper" mkFinalizerPtr :: + (Ptr a -> IO ()) -> IO (FunPtr (Ptr a -> IO ()))++--+-- |avFinalizer -- finalizer function pointer to avFree+--+avFinalizer :: IO (FunPtr (Ptr a -> IO ()))+avFinalizer = mkFinalizerPtr avFree++--+-- |newAvForeignPtr create new foreign ptr with avFinalizer+-- +newAvForeignPtr :: Ptr a -> IO (ForeignPtr a)+newAvForeignPtr p = avFinalizer >>= \f -> newForeignPtr f p++newFinForeignPtr :: (Ptr a -> IO ()) -> Ptr a -> IO (ForeignPtr a)+newFinForeignPtr f p = mkFinalizerPtr f >>= \f' -> newForeignPtr f' p++--+-- |Buffer type+--+data Buffer = Buffer Int (ForeignPtr Buffer) ++instance ExternalPointer Buffer where+ withThis (Buffer _ b) io = withForeignPtr b (io . castPtr)++bufferSize :: Buffer -> Int+bufferSize (Buffer s _) = s++shiftBuffer :: Int -> Buffer -> IO Buffer+shiftBuffer l buf + | l > bsize = error $+ printf "shiftBuffer: buffer is to narrow, size is %d, shift %d\n" + bsize l+ | otherwise = withThis buf $ castBufferSize (bsize - l) . (`plusPtr` l) + where bsize = bufferSize buf+ ++--+-- Allocate buffer with specified size+--+allocBuffer :: Int -> IO Buffer+allocBuffer size = do+ p <- throwIf + (== nullPtr)+ (\_ -> "allocBuffer: failed to allocate memory block")+ (_malloc (fromIntegral size))+ liftM (Buffer size . castForeignPtr) $ newAvForeignPtr p++-- |Cast pointer to buffer with size (unsafe op)+castBufferSize :: Int -> Ptr a -> IO Buffer+castBufferSize s = liftM (Buffer s . castForeignPtr) . newForeignPtr_++-- |Cast pointer to buffer (unsafe operation)+castBuffer :: Ptr a -> IO Buffer+castBuffer = castBufferSize (-1)++-- |operations with buffer+withBuffer :: ExternalPointer p => p -> (Ptr a -> IO b) -> IO b+withBuffer = withThis++-- | Very unsafe operation, allows to set size to the +-- existing buffer. Use very carefully+unsafeBufferSetSize :: Buffer -> Int -> Buffer+unsafeBufferSetSize (Buffer s b) ns = Buffer ns b+
+ src/Media/FFMpeg/UtilEnums_.hsc view
@@ -0,0 +1,86 @@+-- -*- haskell -*- +{-# LANGUAGE ForeignFunctionInterface #-}++{- | Module 'Media.FFMpeg.UtilEnums_' implements + enumerations from libavutil+ + (c) 2009 Vasyl Pasternak+ -}+++module Media.FFMpeg.UtilEnums_+ (+ PixelFormat (..)+ ) where++#include "libavutil/avutil.h"+#include "macros.hsc2hs.h"++-- |PixelFormat enumeration+#{begin_enum PixelFormat, PIX_FMT_NONE}+#{add_enum PIX_FMT_YUV420P}+#{add_enum PIX_FMT_YUYV422}+#{add_enum PIX_FMT_RGB24}+#{add_enum PIX_FMT_BGR24}+#{add_enum PIX_FMT_YUV422P}+#{add_enum PIX_FMT_YUV444P}+#{add_enum PIX_FMT_YUV410P}+#{add_enum PIX_FMT_YUV411P}+#{add_enum PIX_FMT_GRAY8}+#{add_enum PIX_FMT_MONOWHITE}+#{add_enum PIX_FMT_MONOBLACK}+#{add_enum PIX_FMT_PAL8}+#{add_enum PIX_FMT_YUVJ420P}+#{add_enum PIX_FMT_YUVJ422P}+#{add_enum PIX_FMT_YUVJ444P}+#{add_enum PIX_FMT_XVMC_MPEG2_MC}+#{add_enum PIX_FMT_XVMC_MPEG2_IDCT}+#{add_enum PIX_FMT_UYVY422}+#{add_enum PIX_FMT_UYYVYY411}+#{add_enum PIX_FMT_BGR8}+#{add_enum PIX_FMT_BGR4}+#{add_enum PIX_FMT_BGR4_BYTE}+#{add_enum PIX_FMT_RGB8}+#{add_enum PIX_FMT_RGB4}+#{add_enum PIX_FMT_RGB4_BYTE}+#{add_enum PIX_FMT_NV12}+#{add_enum PIX_FMT_NV21}+#{add_enum PIX_FMT_ARGB}+#{add_enum PIX_FMT_RGBA}+#{add_enum PIX_FMT_ABGR}+#{add_enum PIX_FMT_BGRA}+#{add_enum PIX_FMT_GRAY16BE}+#{add_enum PIX_FMT_GRAY16LE}+#{add_enum PIX_FMT_YUV440P}+#{add_enum PIX_FMT_YUVJ440P}+#{add_enum PIX_FMT_YUVA420P}+#{add_enum PIX_FMT_VDPAU_H264}+#{add_enum PIX_FMT_VDPAU_MPEG1}+#{add_enum PIX_FMT_VDPAU_MPEG2}+#{add_enum PIX_FMT_VDPAU_WMV3}+#{add_enum PIX_FMT_VDPAU_VC1}+#{add_enum PIX_FMT_RGB48BE}+#{add_enum PIX_FMT_RGB48LE}+#{add_enum PIX_FMT_RGB565BE}+#{add_enum PIX_FMT_RGB565LE}+#{add_enum PIX_FMT_RGB555BE}+#{add_enum PIX_FMT_RGB555LE}+#{add_enum PIX_FMT_BGR565BE}+#{add_enum PIX_FMT_BGR565LE}+#{add_enum PIX_FMT_BGR555BE}+#{add_enum PIX_FMT_BGR555LE}+#{add_enum PIX_FMT_VAAPI_MOCO}+#{add_enum PIX_FMT_VAAPI_IDCT}+#{add_enum PIX_FMT_VAAPI_VLD}+#{add_enum PIX_FMT_NB}+#{add_enum PIX_FMT_RGB32}+#{add_enum PIX_FMT_RGB32_1}+#{add_enum PIX_FMT_BGR32}+#{add_enum PIX_FMT_BGR32_1}+#{add_enum PIX_FMT_GRAY16}+#{add_enum PIX_FMT_RGB48}+#{add_enum PIX_FMT_RGB565}+#{add_enum PIX_FMT_RGB555}+#{add_enum PIX_FMT_BGR565}+#{add_enum PIX_FMT_BGR555}+#{end_enum "Eq, Ord, Show"}
− src/Media/FFMpeg/Version.hsc
@@ -1,46 +0,0 @@--- -*- haskell -*--{-# LANGUAGE ForeignFunctionInterface #-}--{- |'Media.FFMpeg.Version' - FFMpeg version information -}--module Media.FFMpeg.Version- (- libAVCodecVersion- ,libAVFormatVersion- ) where--#include "libavformat/avformat.h"-#include "libavcodec/avcodec.h"-#include "libswscale/swscale.h"--import Data.Version--libAVFormatVersion :: Version-libAVFormatVersion = Version {- versionBranch = [- #{const LIBAVFORMAT_VERSION_MAJOR},- #{const LIBAVFORMAT_VERSION_MINOR},- #{const LIBAVFORMAT_VERSION_MICRO}- ],- versionTags = []- }--libAVCodecVersion :: Version-libAVCodecVersion = Version {- versionBranch = [- #{const LIBAVCODEC_VERSION_MAJOR},- #{const LIBAVCODEC_VERSION_MINOR},- #{const LIBAVCODEC_VERSION_MICRO}- ],- versionTags = []- }--libSWScaleVersion :: Version-libSWScaleVersion = Version {- versionBranch = [- #{const LIBSWSCALE_VERSION_MAJOR},- #{const LIBSWSCALE_VERSION_MINOR},- #{const LIBSWSCALE_VERSION_MICRO}- ],- versionTags = []- }
+ src/Media/FFMpeg/_c_utils.c view
@@ -0,0 +1,6 @@++#include <libavcodec/avcodec.h>++void b_free_packet (AVPacket * pkt){+ av_free_packet (pkt);+}