%Copyright (C) 2007-2015  Brian Langenberger
%This work is licensed under the
%Creative Commons Attribution-Share Alike 3.0 United States License.
%To view a copy of this license, visit
%http://creativecommons.org/licenses/by-sa/3.0/us/ or send a letter to
%Creative Commons,
%171 Second Street, Suite 300,
%San Francisco, California, 94105, USA.

\chapter{Ogg}
\label{ogg}
Ogg is a general-purpose container for storing audio and/or video streams.
It is used by Ogg Vorbis, Ogg FLAC, Ogg Speex and others
to store a stream of packets.
It consists of a stream of Ogg pages where each page stores
1 or more segments.
Those segments are combined into packets based on their length.
All of its fields are little-endian.
\begin{figure}[h]
  \includegraphics{figures/ogg/packets.pdf}
  \caption{Ogg stream overview}
\end{figure}

\clearpage

\section{Ogg Decoding}
{\relsize{-1}
\ALGORITHM{a file stream}{0 or more Ogg packets}
\SetKwData{CRC}{CRC}
\SetKwData{MAGIC}{magic number}
\SetKwData{VERSION}{version}
\SetKwData{CONT}{continuation}
\SetKwData{BOS}{beginning of stream}
\SetKwData{EOS}{end of stream}
\SetKwData{GRANULEPOS}{granule position}
\SetKwData{SERIALNUM}{bitstream serial number}
\SetKwData{SEQUENCENUM}{page sequence number}
\SetKwData{SEGCOUNT}{page segment count}
\SetKwData{SEGLENGTH}{page segment length}
\SetKwData{SEGMENT}{page segment}
\SetKwData{PACKET}{Ogg packet}
$p \leftarrow 0$\;
$\text{\PACKET}_p \leftarrow$ empty string of data\;
\Repeat{$\EOS = 1$}{
  \hyperref[ogg:checksum]{begin CRC calculation with initial checksum of 0}\;
  $\MAGIC \leftarrow$ \READ 4 bytes\;
  \ASSERT $\MAGIC = \texttt{"OggS"}$\;
  $\VERSION \leftarrow$ \READ 8 unsigned bits\;
  \ASSERT $\VERSION = 0$\;
  $\CONT \leftarrow$ \READ 1 unsigned bit\;
  $\BOS \leftarrow$ \READ 1 unsigned bit\;
  $\EOS \leftarrow$ \READ 1 unsigned bit\;
  \SKIP 5 bits\;
  $\GRANULEPOS \leftarrow$ \READ 64 signed bits\;
  $\SERIALNUM \leftarrow$ \READ 32 unsigned bits\;
  $\SEQUENCENUM \leftarrow$ \READ 32 unsigned bits\;
  suspend CRC calculation\;
  $\CRC \leftarrow$ \READ 32 unsigned bits\;
  resume CRC calculation, feeding checksum 4 bytes with 0 values\;
  $\SEGCOUNT \leftarrow$ \READ 8 unsigned bits\;
  \BlankLine
  \For{$i \leftarrow 0$ \emph{\KwTo}\SEGCOUNT}{
    $\text{\SEGLENGTH}_i \leftarrow$ \READ 8 unsigned bits\;
  }
  \For{$i \leftarrow 0$ \emph{\KwTo}\SEGCOUNT}{
    $\text{\SEGMENT}_i \leftarrow $ \READ $(\text{\SEGLENGTH}_i)$ bytes\;
    append $\text{\SEGMENT}_i$ to $\text{\PACKET}_p$\;
    \If{$\text{\SEGLENGTH}_i < 255$}{
      \Return $\text{\PACKET}_p$\;
      $p \leftarrow p + 1$\;
      $\text{\PACKET}_p \leftarrow$ empty string of data\;
    }
  }
  \ASSERT $\CRC = \text{page's calculated checksum}$\;
}
\EALGORITHM
}
\begin{table}[h]
{\relsize{-1}
\begin{tabular}{rl}
\textsf{magic number} & always \texttt{OggS} \\
\textsf{version} & always 0 \\
\textsf{continuation} & 1 if page's Ogg packet continues from previous page, 0 otherwise \\
\textsf{beginning of stream} & 1 if page is first in stream, 0 otherwise \\
\textsf{end of stream} & 1 if page is last in stream, 0 otherwise \\
\textsf{granule position} & codec-specific position value in stream \\
\textsf{bitstream serial number} & stream's unique identifier, in case an Ogg file contains more than one \\
\textsf{page sequence number} & page number in stream, starting from 0 \\
\textsf{CRC} & checksum of all page data \\
\textsf{page segment count} & number of segments \\
\textsf{page segment length} & length of each segment \\
\textsf{page segment} & raw segment data \\
\end{tabular}
}
\end{table}
\clearpage

\begin{figure}[h]
  \includegraphics{figures/ogg/stream.pdf}
\end{figure}

\clearpage

\section{Checksum Calculation}
\label{ogg:checksum}
Given an Ogg page byte and a previous CRC checksum,
or 0 as an initial value:
\begin{equation*}
  \text{CRC}_i = (\text{CRC}_{i - 1} \times 2 ^ 8) \xor \texttt{CRC32}((\lfloor\text{CRC}_{i - 1} \div 2 ^ {24}\rfloor \bmod 256) \xor byte)
\end{equation*}
where $\text{CRC}_i$ is truncated to 32 bits.
\begin{table}[h]
{\relsize{-3}
  \ttfamily
  \begin{tabular}{|r||r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|r|}
    \hline
    & 0x?0 & 0x?1 & 0x?2 & 0x?3 & 0x?4 & 0x?5 & 0x?6 & 0x?7 \\
    \hline
    0x0? & 0x00000000 & 0x04C11DB7 & 0x09823B6E & 0x0D4326D9 &
    0x130476DC & 0x17C56B6B & 0x1A864DB2 & 0x1E475005 \\
    0x1? & 0x4C11DB70 & 0x48D0C6C7 & 0x4593E01E & 0x4152FDA9 &
    0x5F15ADAC & 0x5BD4B01B & 0x569796C2 & 0x52568B75 \\
    0x2? & 0x9823B6E0 & 0x9CE2AB57 & 0x91A18D8E & 0x95609039 &
    0x8B27C03C & 0x8FE6DD8B & 0x82A5FB52 & 0x8664E6E5 \\
    0x3? & 0xD4326D90 & 0xD0F37027 & 0xDDB056FE & 0xD9714B49 &
    0xC7361B4C & 0xC3F706FB & 0xCEB42022 & 0xCA753D95 \\
    0x4? & 0x34867077 & 0x30476DC0 & 0x3D044B19 & 0x39C556AE &
    0x278206AB & 0x23431B1C & 0x2E003DC5 & 0x2AC12072 \\
    0x5? & 0x7897AB07 & 0x7C56B6B0 & 0x71159069 & 0x75D48DDE &
    0x6B93DDDB & 0x6F52C06C & 0x6211E6B5 & 0x66D0FB02 \\
    0x6? & 0xACA5C697 & 0xA864DB20 & 0xA527FDF9 & 0xA1E6E04E &
    0xBFA1B04B & 0xBB60ADFC & 0xB6238B25 & 0xB2E29692 \\
    0x7? & 0xE0B41DE7 & 0xE4750050 & 0xE9362689 & 0xEDF73B3E &
    0xF3B06B3B & 0xF771768C & 0xFA325055 & 0xFEF34DE2 \\
    0x8? & 0x690CE0EE & 0x6DCDFD59 & 0x608EDB80 & 0x644FC637 &
    0x7A089632 & 0x7EC98B85 & 0x738AAD5C & 0x774BB0EB \\
    0x9? & 0x251D3B9E & 0x21DC2629 & 0x2C9F00F0 & 0x285E1D47 &
    0x36194D42 & 0x32D850F5 & 0x3F9B762C & 0x3B5A6B9B \\
    0xA? & 0xF12F560E & 0xF5EE4BB9 & 0xF8AD6D60 & 0xFC6C70D7 &
    0xE22B20D2 & 0xE6EA3D65 & 0xEBA91BBC & 0xEF68060B \\
    0xB? & 0xBD3E8D7E & 0xB9FF90C9 & 0xB4BCB610 & 0xB07DABA7 &
    0xAE3AFBA2 & 0xAAFBE615 & 0xA7B8C0CC & 0xA379DD7B \\
    0xC? & 0x5D8A9099 & 0x594B8D2E & 0x5408ABF7 & 0x50C9B640 &
    0x4E8EE645 & 0x4A4FFBF2 & 0x470CDD2B & 0x43CDC09C \\
    0xD? & 0x119B4BE9 & 0x155A565E & 0x18197087 & 0x1CD86D30 &
    0x029F3D35 & 0x065E2082 & 0x0B1D065B & 0x0FDC1BEC \\
    0xE? & 0xC5A92679 & 0xC1683BCE & 0xCC2B1D17 & 0xC8EA00A0 &
    0xD6AD50A5 & 0xD26C4D12 & 0xDF2F6BCB & 0xDBEE767C \\
    0xF? & 0x89B8FD09 & 0x8D79E0BE & 0x803AC667 & 0x84FBDBD0 &
    0x9ABC8BD5 & 0x9E7D9662 & 0x933EB0BB & 0x97FFAD0C \\
    \hline
    \hline
    & 0x?8 & 0x?9 & 0x?A & 0x?B & 0x?C & 0x?D & 0x?E & 0x?F \\
    \hline
    0x0? & 0x2608EDB8 & 0x22C9F00F & 0x2F8AD6D6 & 0x2B4BCB61 &
    0x350C9B64 & 0x31CD86D3 & 0x3C8EA00A & 0x384FBDBD \\
    0x1? & 0x6A1936C8 & 0x6ED82B7F & 0x639B0DA6 & 0x675A1011 &
    0x791D4014 & 0x7DDC5DA3 & 0x709F7B7A & 0x745E66CD \\
    0x2? & 0xBE2B5B58 & 0xBAEA46EF & 0xB7A96036 & 0xB3687D81 &
    0xAD2F2D84 & 0xA9EE3033 & 0xA4AD16EA & 0xA06C0B5D \\
    0x3? & 0xF23A8028 & 0xF6FB9D9F & 0xFBB8BB46 & 0xFF79A6F1 &
    0xE13EF6F4 & 0xE5FFEB43 & 0xE8BCCD9A & 0xEC7DD02D \\
    0x4? & 0x128E9DCF & 0x164F8078 & 0x1B0CA6A1 & 0x1FCDBB16 &
    0x018AEB13 & 0x054BF6A4 & 0x0808D07D & 0x0CC9CDCA \\
    0x5? & 0x5E9F46BF & 0x5A5E5B08 & 0x571D7DD1 & 0x53DC6066 &
    0x4D9B3063 & 0x495A2DD4 & 0x44190B0D & 0x40D816BA \\
    0x6? & 0x8AAD2B2F & 0x8E6C3698 & 0x832F1041 & 0x87EE0DF6 &
    0x99A95DF3 & 0x9D684044 & 0x902B669D & 0x94EA7B2A \\
    0x7? & 0xC6BCF05F & 0xC27DEDE8 & 0xCF3ECB31 & 0xCBFFD686 &
    0xD5B88683 & 0xD1799B34 & 0xDC3ABDED & 0xD8FBA05A \\
    0x8? & 0x4F040D56 & 0x4BC510E1 & 0x46863638 & 0x42472B8F &
    0x5C007B8A & 0x58C1663D & 0x558240E4 & 0x51435D53 \\
    0x9? & 0x0315D626 & 0x07D4CB91 & 0x0A97ED48 & 0x0E56F0FF &
    0x1011A0FA & 0x14D0BD4D & 0x19939B94 & 0x1D528623 \\
    0xA? & 0xD727BBB6 & 0xD3E6A601 & 0xDEA580D8 & 0xDA649D6F &
    0xC423CD6A & 0xC0E2D0DD & 0xCDA1F604 & 0xC960EBB3 \\
    0xB? & 0x9B3660C6 & 0x9FF77D71 & 0x92B45BA8 & 0x9675461F &
    0x8832161A & 0x8CF30BAD & 0x81B02D74 & 0x857130C3 \\
    0xC? & 0x7B827D21 & 0x7F436096 & 0x7200464F & 0x76C15BF8 &
    0x68860BFD & 0x6C47164A & 0x61043093 & 0x65C52D24 \\
    0xD? & 0x3793A651 & 0x3352BBE6 & 0x3E119D3F & 0x3AD08088 &
    0x2497D08D & 0x2056CD3A & 0x2D15EBE3 & 0x29D4F654 \\
    0xE? & 0xE3A1CBC1 & 0xE760D676 & 0xEA23F0AF & 0xEEE2ED18 &
    0xF0A5BD1D & 0xF464A0AA & 0xF9278673 & 0xFDE69BC4 \\
    0xF? & 0xAFB010B1 & 0xAB710D06 & 0xA6322BDF & 0xA2F33668 &
    0xBCB4666D & 0xB8757BDA & 0xB5365D03 & 0xB1F740B4 \\
    \hline
  \end{tabular}
}
\caption{\texttt{CRC32} lookup}
\end{table}
\par
\noindent
The CRC is calculated over all the bytes in an Ogg page,
not counting the 32-bit CRC field itself.
That field is treated as having a value of 0 during calculation.
