-- -- Module : Headers -- Copyright : (c) Conrad Parker 2008 -- License : BSD-style -- Maintainer : conradp@cse.unsw.edu.au -- Stability : experimental -- Portability : portable module Codec.Container.Ogg.Headers ( processHeaders ) where import qualified Data.Map as Map import Codec.Container.Ogg.ContentType import Codec.Container.Ogg.Page import Codec.Container.Ogg.Track ------------------------------------------------------------ -- processHeaders -- processHeaders :: ([OggPage] -> [OggPage]) -> [OggPage] -> [OggPage] processHeaders f gs = (f controlSection) ++ dataSection where (controlSection, dataSection) = splitHeaders gs -- | Separate out the control and data sections splitHeaders :: [OggPage] -> ([OggPage], [OggPage]) splitHeaders gs = splitHeaders' Map.empty ([], [], gs) splitHeaders' :: -- Pages seen so far, demuxed and keyed by Track Map.Map OggTrack [OggPage] -- (headers, seenNotHeaders, notSeen) -> ([OggPage], [OggPage], [OggPage]) -- output -> ([OggPage], [OggPage]) splitHeaders' _ (hs, nhs, []) = (hs, nhs) splitHeaders' seen (hs, nhs, (g:gs)) -- Include Skeleton pages in the control section, and don't bother keeping -- track of them in the list of seen pages | isSkeleton = splitHeaders' seen (hs++[g], nhs, gs) -- If this is a BOS page, add it to the list of seen tracks | pageBOS g = splitHeaders' insertSeen (hs++[g], nhs, gs) -- If all headers have been processed, return the remaining pages unmodified | Map.null seen = (hs, nhs++(g:gs)) -- If this track has already been fully processed, mark this as not a header | notSeen = splitHeaders' seen (hs, nhs++[g], gs) -- If this is the last header for this track, remove it from the list | lastHeader = splitHeaders' deleteSeen (hs++[g], nhs, gs) -- Otherwise, g is a header | otherwise = splitHeaders' appendSeen (hs++[g], nhs, gs) where t = pageTrack g insertSeen = Map.insert t [g] seen appendSeen = Map.insert t tPages seen deleteSeen = Map.delete t seen notSeen = Map.notMember t seen isSkeleton = contentTypeIs skeleton t lastHeader = nPackets >= nHeaders nHeaders = trackHeaders t nPackets = sum $ map pageCompletedPackets tPages tPages = (Map.findWithDefault [] t seen) ++ [g]