packages feed

ffmpeg-tutorials (empty) → 0.2.1

raw patch · 4 files changed

+310/−0 lines, 4 filesdep +SDLdep +basedep +haskell98setup-changed

Dependencies added: SDL, base, haskell98, hs-ffmpeg

Files

+ Setup.hs view
@@ -0,0 +1,5 @@+#!/usr/bin/env runhaskell++import Distribution.Simple++main = defaultMain
+ ffmpeg-tutorials.cabal view
@@ -0,0 +1,25 @@+name:           ffmpeg-tutorials+version:        0.2.1+cabal-version:  >= 1.6+license:        BSD3+author:         Vasyl Pasternak+synopsis:       Tutorials on ffmpeg usage to play video/audio+maintainer:     vasyl.pasternak@gmail.com+description:    A set of tutorials with raising complexity+copyright:      (c) 2009 Vasyl Pasternak+stability:      alpha+category:       Media++build-type:     Simple++executable tutorial01+           main-is:             tutorial01/Main.hs+           hs-source-dirs:      src+           build-depends:       base < 4, haskell98, hs-ffmpeg >= 0.2.1++executable tutorial02+           main-is:             tutorial02/Main.hs+           hs-source-dirs:      src+           build-depends:       base < 4, haskell98, SDL, hs-ffmpeg >= 0.2.1++
+ src/tutorial01/Main.hs view
@@ -0,0 +1,137 @@+{-+  Testing the ffmpeg video decoding.++  Rewritten from the C code, from the FFMpeg tutorial +  (http://www.dranger.com/ffmpeg/)+  +  (c) 2009 Vasyl Pasternak+ -}++module Main (main) where++-- FFMpeg imports +import qualified Media.FFMpeg as FF+import qualified Media.FFMpeg.Scale as S++-- Common imports+import Data.Version+import System.Environment (getArgs, getProgName)+import Text.Printf (printf)+import Data.Maybe (fromJust)+import Data.IORef (newIORef, readIORef, modifyIORef)+import Control.Monad (when)+import System.IO -- (WriteMode, withBinaryFile, hPutStr, hPutBuf)++main :: IO ()+main = do+  getArgs >>= \args ->+      case args of+        filename:[] -> decodeFile filename+        otherwise -> getProgName >>= \pn -> +                     (putStrLn . unlines) +                     ["Usage: \n"+                     ,printf "%s filename\n" pn+                     ,"Where <filename> is the path to the video file"]+                      ++-- The main rutine, do all work+decodeFile :: String -> IO ()+decodeFile filename = +    FF.withFFMpeg $ do +      -- Print FFMpeg version+      printf "FFMpeg library initialized\n" +      printf "\tlibAVFormat version: %s\n" (showVersion FF.libAVFormatVersion)+      printf "\tlibAVCodec version: %s\n" (showVersion FF.libAVCodecVersion)++      -- Open file+      ctx <- FF.openInputFile filename+      FF.findStreamInfo ctx+      -- FF.dumpFormat ctx filename+        +      printf "File: %s\n" filename++      -- Get all streams from file+      let streams = FF.getStreams ctx+      printf "Found %d streams\n" (length streams)++      -- Retrive video streams+      let videoStreams = filter (\(_,s) -> maybe False ((==FF.CodecTypeVideo) . FF.getCodecType) (FF.getCodecContext s)) $ zip [0..] streams++      if null videoStreams +       then do +         printf "No video streams found. Exiting...\n"+       else do+         let (streamIdx, videoStream) = head videoStreams+         printf "Extracting video information from stream %d\n" (streamIdx :: Int) +        +         -- Starting decoding video+         let codecContext = fromJust $ FF.getCodecContext videoStream+         let codecId = FF.getCodecId codecContext+         printf "Video codec is '%s'\n" (show codecId)++         (Just decoder) <- FF.findDecoder codecId+         FF.openCodec codecContext decoder++         let (width, height, pixfmt) = (FF.getVideoWidth codecContext, +                                        FF.getVideoHeight codecContext,+                                        FF.getPixelFormat codecContext)++         printf "Video dimensions are %dx%d\n" width height++         printf "Video pixel format is %s\n" (show pixfmt)+++         frame <- FF.allocFrame+         frameRGB <- FF.allocFrame+         +         pictureSize <- FF.pictureGetSize FF.PixFmtRgb24 width height+    +         buffer <- FF.allocBuffer pictureSize+         +         FF.pictureFill frameRGB buffer FF.PixFmtRgb24 width height++         packet <- FF.allocPacket++         -- Prepare resizer+         scaler <- S.getContext (width, height, pixfmt) +                    (width, height, FF.PixFmtRgb24) [S.SwsBicubic]++         -- use IORef to cound packets+         idxRef <- newIORef (0 :: Int)++         while (FF.readFrame ctx packet) $ +               do+                 when (streamIdx == FF.getStreamIndex packet) $+                    do+                      frameFinished <- FF.decodeVideo codecContext frame packet+                      when frameFinished $ +                           do+                             -- Rescale the picture++                             S.scale scaler +                              (FF.getPictureSlice frame) (FF.getPictureStride frame)+                              0 height+                              (FF.getPictureSlice frameRGB) (FF.getPictureStride frameRGB)++                             idx <- readIORef idxRef+                             modifyIORef idxRef (+1)+                             printf "\rDecoded frame %05d" (idx)+                             when ((idx `mod` 100) == 0) $ +                                  writePPM (printf "frame%05d.ppm" idx) width height+                                           buffer pictureSize+                 FF.cleanPacket packet++         printf "\n"+++-- While cycle implementation+while :: IO Bool -> IO () -> IO ()+while cond body = do+  c <- cond+  when c $ body >> while cond body++writePPM fname width height buff b = +    withBinaryFile fname WriteMode $ \h -> do+      hPutStr h (printf "P6\n%d %d\n255\n" width height)+      FF.withBuffer buff $ \buff' -> +          hPutBuf h buff' b
+ src/tutorial02/Main.hs view
@@ -0,0 +1,143 @@+{-+  Testing the ffmpeg video decoding.++  Rewritten from the C code, from the FFMpeg tutorial +  (http://www.dranger.com/ffmpeg/)+  +  (c) 2009 Vasyl Pasternak+ -}++module Main (main) where++-- FFMpeg+import qualified Media.FFMpeg as FF+import qualified Media.FFMpeg.Scale as S++-- Common+import Data.Version+import System.Environment (getArgs, getProgName)+import Text.Printf (printf)+import Data.Maybe (fromJust)+import Data.IORef (newIORef, readIORef, modifyIORef)+import Control.Monad (when)+import System.IO -- (WriteMode, withBinaryFile, hPutStr, hPutBuf)++-- SDL+import Graphics.UI.SDL as SDL++main :: IO ()+main = do+  getArgs >>= \args ->+      case args of+        filename:[] -> decodeFile filename+        otherwise -> getProgName >>= \pn -> +                     (putStrLn . unlines) +                     ["Usage: \n"+                     ,printf "%s filename\n" pn+                     ,"Where <filename> is the path to the video file"]+                      ++-- The main rutine, do all work+decodeFile :: String -> IO ()+decodeFile filename = do+    SDL.init [InitTimer, InitAudio, InitVideo]+    FF.withFFMpeg $ do +      -- Print FFMpeg version+      printf "FFMpeg library initialized\n" +      printf "\tlibAVFormat version: %s\n" (showVersion FF.libAVFormatVersion)+      printf "\tlibAVCodec version: %s\n" (showVersion FF.libAVCodecVersion)++      -- Open file+      ctx <- FF.openInputFile filename+      FF.findStreamInfo ctx+      -- FF.dumpFormat ctx filename+        +      printf "File: %s\n" filename++      -- Get all streams from file+      let streams = FF.getStreams ctx+      printf "Found %d streams\n" (length streams)++      -- Retrive video streams+      let videoStreams = filter (\(_,s) -> maybe False ((==FF.CodecTypeVideo) . FF.getCodecType) (FF.getCodecContext s)) $ zip [0..] streams++      if null videoStreams +       then do +         printf "No video streams found. Exiting...\n"+       else do+         let (streamIdx, videoStream) = head videoStreams+         printf "Extracting video information from stream %d\n" (streamIdx :: Int) +        +         -- Starting decoding video+         let codecContext = fromJust $ FF.getCodecContext videoStream+         let codecId = FF.getCodecId codecContext+         printf "Video codec is '%s'\n" (show codecId)++         (Just decoder) <- FF.findDecoder codecId+         FF.openCodec codecContext decoder++         let (width, height, pixfmt) = (FF.getVideoWidth codecContext, +                                        FF.getVideoHeight codecContext,+                                        FF.getPixelFormat codecContext)++         printf "Video dimensions are %dx%d\n" width height+         printf "Video pixel format is %s\n" (show pixfmt)++         -- init primary SDL surface+         screen <- SDL.setVideoMode width height 0 []++         -- init output surface+         rgbSurface <- SDL.createRGBSurface [] width height 24+                       0x0000FF 0x00FF00 0xFF0000 0x000000++         frame <- FF.allocFrame+         frameRGB <- FF.allocFrame+         +         surfacePixels <- SDL.surfaceGetPixels rgbSurface >>= FF.makeBuffer++         FF.pictureFill frameRGB surfacePixels FF.PixFmtRgb24 width height++         packet <- FF.allocPacket++         -- Prepare resizer+         scaler <- S.getContext (width, height, pixfmt) +                    (width, height, FF.PixFmtRgb24) [S.SwsBicubic]++         -- use IORef to cound packets+         idxRef <- newIORef (0 :: Int)++         while (FF.readFrame ctx packet) $ +               do+                 when (streamIdx == FF.getStreamIndex packet) $+                    do+                      frameFinished <- FF.decodeVideo codecContext frame packet+                      when frameFinished $ +                           do+                             -- Rescale the picture++                             SDL.lockSurface rgbSurface++                             S.scale scaler +                              (FF.getPictureSlice frame) (FF.getPictureStride frame)+                              0 height+                              (FF.getPictureSlice frameRGB) (FF.getPictureStride frameRGB)++                             -- show on screen +                             SDL.unlockSurface rgbSurface+                             SDL.blitSurface rgbSurface Nothing screen Nothing+                             SDL.flip screen++                             idx <- readIORef idxRef+                             modifyIORef idxRef (+1)+                             printf "\rDecoded frame %05d" (idx)+                 FF.cleanPacket packet++         printf "\n"+++-- While cycle implementation+while :: IO Bool -> IO () -> IO ()+while cond body = do+  c <- cond+  when c $ body >> while cond body+