decodeVideoFrames
    :: ( SetMember Lift (Lift IO) r
       , Member (Reader AVCodecContext) r
       , Member (Yield AVFrame) r
       , Member (Exc IOError) r
       )
    => Eff (Yield AVPacket :> r) ()
    -> Eff r ()
decodeVideoFrames pkt = ask >>= \ctx -> do
    f <- newAvFrame
    runC pkt >>= loop ctx f where
        loop :: ( SetMember Lift (Lift IO) r
                , Member (Yield AVFrame) r
                , Member (Exc IOError) r
                ) => AVCodecContext -> AVFrame -> Y r AVPacket () -> Eff r ()
        loop _ _ (Done ()) = return ()
        loop ctx f (Y p k)  = do
            (r, gp) <- lift $ alloca $ \gpp -> do
                r <- withAvPacket p $ \p' ->
                     withAvFrame f $ \f' ->
                     c_avcodec_decode_video2 ctx f' gpp p'

                peek gpp >>= \gp -> return (r, gp)

            if r < 0
                then throwExc $ userError $ "error decoding frame: " ++ show r
                else if gp == 0
                        then yield f >> k () >>= loop ctx f
                        else k () >>= loop ctx f

-------------------------------------------------------------------------------
-- Imports
-------------------------------------------------------------------------------
decodeVideoFrames
    :: ( SetMember Lift (Lift IO) r
       , Member (Reader AVCodecContext) r
       , Member (Yield AVFrame) r
       , Member (Exc IOError) r
       )
    => Eff (Yield AVPacket :> r) ()
    -> Eff r ()
decodeVideoFrames pkt = ask >>= \ctx -> do
    f <- newAvFrame
    runC pkt >>= loop ctx f where
        loop :: ( SetMember Lift (Lift IO) r
                , Member (Yield AVFrame) r
                , Member (Exc IOError) r
                ) => AVCodecContext -> AVFrame -> Y r AVPacket () -> Eff r ()
        loop _ _ (Done ()) = return ()
        loop ctx f (Y p k)  = do
            (r, gp) <- lift $ alloca $ \gpp -> do
                r <- withAvPacket p $ \p' ->
                     withAvFrame f $ \f' ->
                     c_avcodec_decode_video2 ctx f' gpp p'

                peek gpp >>= \gp -> return (r, gp)

            if r < 0
                then throwExc $ userError $ "error decoding frame: " ++ show r
                else if gp == 0
                        then yield f >> k () >>= loop ctx f
                        else k () >>= loop ctx f

-------------------------------------------------------------------------------
-- Imports
-------------------------------------------------------------------------------
decodeVideoFrames pkt = ask >>= \ctx -> do
    f <- newAvFrame
    runC pkt >>= loop ctx f where
        loop :: ( SetMember Lift (Lift IO) r
                , Member (Yield AVFrame) r
                , Member (Exc IOError) r
                ) => AVCodecContext -> AVFrame -> Y r AVPacket () -> Eff r ()
        loop _ _ (Done ()) = return ()
        loop ctx f (Y p k)  = do
            (r, gp) <- lift $ alloca $ \gpp -> do
                r <- withAvPacket p $ \p' ->
                     withAvFrame f $ \f' ->
                     c_avcodec_decode_video2 ctx f' gpp p'

                peek gpp >>= \gp -> return (r, gp)

            if r < 0
                then throwExc $ userError $ "error decoding frame: " ++ show r
                else if gp == 0
                        then yield f >> k () >>= loop ctx f
                        else k () >>= loop ctx f

-------------------------------------------------------------------------------
-- Imports
-------------------------------------------------------------------------------