<?xml version="1.0" encoding="US-ASCII"?>
<!DOCTYPE rfc SYSTEM "rfc2629.dtd">
<?rfc toc="yes"?>
<?rfc tocompact="yes"?>
<?rfc tocdepth="3"?>
<?rfc tocindent="yes"?>
<?rfc symrefs="yes"?>
<?rfc sortrefs="yes"?>
<?rfc comments="yes"?>
<?rfc inline="yes"?>
<?rfc compact="yes"?>
<?rfc subcompact="no"?>
<rfc category="std" docName="draft-fuldseth-netvc-thor-00"
     ipr="trust200902">
  <front>
    <title abbrev="Thor Video Codec">Thor Video Codec</title>

    <author fullname="Arild Fuldseth" initials="A." surname="Fuldseth">
      <organization>Cisco</organization>

      <address>
        <postal>
          <street></street>

          <city>Lysaker</city>

          <country>Norway</country>
        </postal>

        <phone></phone>

        <email>arilfuld@cisco.com</email>
      </address>
    </author>

    <author fullname="Gisle Bjontegaard" initials="G." surname="Bjontegaard">
      <organization>Cisco</organization>

      <address>
        <postal>
          <street></street>

          <city>Lysaker</city>

          <country>Norway</country>
        </postal>

        <phone></phone>

        <email>gbjonteg@cisco.com</email>
      </address>
    </author>

    <author fullname="Mo Zanaty" initials="M." surname="Zanaty">
      <organization>Cisco</organization>

      <address>
        <postal>
          <street></street>

          <city>RTP,NC</city>

          <country>USA</country>
        </postal>

        <phone></phone>

        <email>mzanaty@cisco.com</email>
      </address>
    </author>
    
    <date month="July" year="2015"/>

    <abstract>
      <t>This document provides a high-level description of the Thor video codec.
      Thor is designed to achieve high compression efficiency with
      moderate complexity, using the well-known hybrid video coding approach of
      motion-compensated prediction and transform coding.</t>
    </abstract>
  </front>

  <middle>
    <section title="Introduction">
      <t>This document provides a high-level description of the Thor video codec.
        Thor is designed to achieve high compression efficiency with
        moderate complexity, using the well-known hybrid video coding approach of
        motion-compensated prediction and transform coding.</t>
      
      <t>The Thor video codec is a block-based hybrid video codec similar in structure to widespread standards. The high level encoder and decoder structures are illustrated in <xref target="encoder_arch"></xref> and <xref target="decoder_arch"></xref> respectively.</t>
      
<figure align="center" anchor="encoder_arch" title="Encoder Structure">
<artwork align="center">
<![CDATA[
           +---+   +-----------+   +-----------+   +--------+
Input--+-->| + |-->| Transform |-->| Quantizer |-->| Entropy|
Video  |   +---+   +-----------+   +-----------+   | Coding |
       |     ^ -                         |         +--------+
       |     |                           v              |
       |     |                     +-----------+        v
       |     |                     |  Inverse  |     Output
       |     |                     | Transform |    Bitstream
       |     |                     +-----------+
       |     |                           |
       |     |                           v
       |     |                         +---+
       |     +------------------------>| + |
       |     |      +-------------+    +---+
       |     |   ___| Intra Frame |      |
       |     |  /   | Prediction  |<-----+
       |     | /    +-------------+      |
       |     |/                          v
       |      \     +-------------+  +---------+
       |       \    | Inter Frame |  |  Loop   |
       |        \___| Prediction  |  | Filters |
       |            +-------------+  +---------+
       |                   ^             |
       |                   |             v
       |            +------------+   +---------------+
       |            |   Motion   |   | Reconstructed |
       +----------->| Estimation |<--| Frame Memory  |
                    +------------+   +---------------+
]]>
</artwork>
</figure>

<figure align="center" anchor="decoder_arch" title="Decoder Structure">
<artwork align="center">
<![CDATA[
                 +----------+      +-----------+
  Input  ------->| Entropy  |----->|  Inverse  |
Bitstream        | Decoding |      | Transform |
                 +----------+      +-----------+
                                         |
                                         v
                                       +---+
             +------------------------>| + |
             |      +-------------+    +---+
             |   ___| Intra Frame |      |
             |  /   | Prediction  |<-----+
             | /    +-------------+      |
             |/                          v
              \     +-------------+  +---------+
               \    | Inter Frame |  |  Loop   |
                \___| Prediction  |  | Filters |
                    +-------------+  +---------+
                           ^             |-------------> Output
                           |             v               Video
                  +--------------+   +---------------+
                  |     Motion   |   | Reconstructed |
                  | Compensation |<--| Frame Memory  |
                  +--------------+   +---------------+
]]>
</artwork>
</figure>

      <t>The remainder of this document is organized as follows. First, some requirements language and terms are defined. Block structures are described in detail, followed by intra-frame prediction techniques, inter-frame prediction techniques, transforms, quantization, loop filters, entropy coding, and finally high level syntax.</t>
      
      <t>An open source reference implementation will be available soon at github.com/cisco/thor.</t>
    </section>

    <section title="Definitions">

      <section title="Requirements Language">
        <t>The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT",
        "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this
        document are to be interpreted as described in <xref
        target="RFC2119">RFC 2119</xref>.</t>
      </section>

      <section title="Terminology">
        <t>This document frequently uses the following terms.
          <list style="empty">
            <t>SB: Super Block - 64x64 block (luma pixels) which can be divided into CBs.</t>
            <t>CB: Coding Block - Subdivision of a SB, down to 8x8 (luma pixels).</t>
            <t>PB: Prediction Block - Subdivision of a CB, into 1, 2 or 4 equal blocks.</t>
            <t>TB: Transform Block - Subdivision of a CB, into 1 or 4 equal blocks.</t>
          </list>
        </t>

      </section>
    </section>

    <section title="Block Structure">
      
      <section title="Super Blocks and Coding Blocks">
        <t>
Each frame is divided into 64x64 Super Blocks (SB) which are processed in raster-scan order. Each SB can be divided into Coding Blocks (CB) using a quad-tree structure. The smallest allowed CB size is 8x8 luma pixels. The four CBs of a larger block are coded/signaled in the following order; upleft, downleft, upright, and downright.</t>
<t>The following modes are signaled at the CB level:
<list style="symbols">
<t>Intra</t>
<t>Inter0 (MV index, no residual information)</t>
<t>Inter1 (MV index, residual information)</t>
<t>Inter2 (explicit motion information, residual information)</t>
<t>Bi-Prediction (explicit motion information, residual information)</t>
</list>
</t>
      </section>
      
      <section title="Special Processing at Frame Boundaries">
        <t>
At frame boundaries some square blocks might not be complete. For example, for 1920x1080 resolutions, the bottom row would consist of rectangular blocks of size 64x56. Rectangular blocks at frame boundaries are handled as follows. For each rectangular block, send one bit to choose between:
<list style="symbols">
<t>A  rectangular inter0 block and</t>
<t>Further split.</t>
</list>
</t>
        
<t>For the bottom part of a 1920x1080 frame, this implies the following:
<list style="symbols">
<t>For each 64x56 block, transmit one bit to signal a 64x56 inter0 block or a split into two 32x32 blocks and two 32x24 blocks.</t>
<t>For each 32x24 block, transmit one bit to signal a 32x24 inter0 block or a split into two 16x16 blocks and two 16x8 blocks.</t>
<t>For each 16x8 block, transmit one bit to signal a 16x8 inter0 block or a split into two 8x8 blocks.</t>
</list>
</t>

<t>Two examples of handling 64x56 blocks at the bottom row of a 1920x1080 frame are shown in <xref target="sb_frame_boundary"></xref>  and <xref target="cb_frame_boundary"></xref>  respectively.</t>

<figure align="center" anchor="sb_frame_boundary" title="Super block at frame boundary">
<artwork align="center">
<![CDATA[
                                 64
                  +-------------------------------+
                  |                               |
                  |                               |
                  |                               |
                  |                               |
                  |                               |
                  |                               |
                  |                               |
              64  | 56           64x56            |
                  |              SKIP             |
                  |                               |
                  |                               |
                  |                               |
                  |                               |
- - - - - - - - - + - - - - - - - - - - - - - - - + - - -
Frame boundary    | 8                             |
                  +-------------------------------+
]]>
</artwork>
</figure>

<figure align="center" anchor="cb_frame_boundary" title="Coding block at frame boundary">
<artwork align="center">
<![CDATA[
                                 64
                  +---------------+---------------+
                  |               |               |
                  |               |               |
                  |               |               |
                  |               |               |
                  |               |               |
                  |               |               |
                  |               |               |
              64  +---------------+-------+-------+
                  |               |       |       |
                  |               |       |       |
                  |     32x24     |       |       |
                  |     SKIP      +---+---+-------+
                  |               |   |   | 16x8  |
- - - - - - - - - + - - - - - - - +---+---+ - - - + - - -
Frame boundary    | 8             |   |   | SKIP  |
                  +---------------+---+---+-------+
]]>
</artwork>
</figure>

      </section>
      
      <section title="Transform Blocks">
        <t>
A CB can be divided into four smaller transform blocks (TBs).
        </t>
      </section>
      
      <section title="Prediction Blocks">
        <t>
A CB can also be divided into smaller prediction blocks (PBs) for the purpose of motion-compensated prediction. Horizontal, vertical and quad split is used.
        </t>
      </section>
    </section>
    
    <section title="Intra Prediction">
      <t>
8 modes are used:
<list style="numbers">
<t>DC
</t>
<t>Vertical (V)
</t>
<t>Horizontal (H)
</t>
<t>Upupright (north-northeast)
</t>
<t>Upupleft (north-northwest)
</t>
<t>Upleft (northwest)
</t>
<t>Upleftleft (west-northwest)
</t>
<t>Downleftleft (west-southwest)
</t>
</list>
</t>

<t>The definition of DC, vertical, and horizontal modes are straightforward.</t>
<t>The upright and upleft directions are exactly 45 degrees.</t>
<t>The upupright, upupleft, and upleftleft directions are equal to arctan(1/2) from the horizontal or vertical direction, since they are defined by going one pixel horizontally and two pixels vertically (or vice versa).</t>
<t>For the 5 angular intra modes (i.e. angle different from 90 degrees), the pixels of the neighbor blocks are filtered before they are used for prediction:</t>
<t>y(n) = (x(n-1) + 2*x(n) + x(n+1) + 2)/4</t>
<t>For the angular intra modes that are not 45 degrees, the prediction sometimes requires sample values at a half-pixel position. These sample values are determined by an additional filter:</t>
<t>z(n + 1/2) = (y(n) + y(n+1))/2</t>

    </section>
      
    <section title="Inter Prediction">

      <section title="Multiple Reference Frames">
        <t>
Multiple reference frames are currently implemented as follows.
<list style="symbols">
<t>Use a sliding-window process to keep the N most recent reconstructed frames in memory. The value of N is signaled in the sequence header.
</t>
<t>In the frame header, signal which of these frames shall be active for the current frame.
</t>
<t>For each CB, signal which of the active frames to be used for MC.
</t>
</list>
</t>
        
<t>Combined with re-ordering, this allows for MPEG-1 style B frames.</t>
<t>A desirable extension is to allow long-term reference frames in addition to the short-term reference frames defined by the sliding-window process.
        </t>
      </section>
      
      <section title="Bi-Prediction">
        <t>
In case of bi-prediction, two reference indices and two motion vectors are signaled per CB. In the current version, PB-split is not allowed in bi-prediction mode. Sub-pixel interpolation is performed for each motion vector/reference index separately before doing an average between the two predicted blocks:</t>
<t>p(x,y) = (p0(x,y) + p1(x,y))/2
        </t>
      </section>
      
      <section title="Sub-Pixel Interpolation">
        
        <section title="Luma Poly-phase Filter">
          <t>
Inter prediction uses traditional block-based motion compensated prediction with quarter pixel resolution. A separable 6-tap poly-phase filter is the basis method for doing MC with sub-pixel accuracy. The luma filter coefficients are as follows:</t>
<t>1/4 phase:	[3,-15,111,37,-10,2]/128</t>
<t>2/4 phase:	[3,-17,78,78,-17,3]/128</t>
<t>3/4 phase:	[2,-10,37,111,-15,3]/128</t>
<t>With reference to <xref target="subpixels"></xref>, a fractional sample value, e.g. i0,0 which has a phase of 1/4 in the horizontal dimension and a phase of 1/2 in the vertical dimension is calculated as follows:</t>
<t>a0,j = 3*A-2,i - 15*A-1,i + 111*A0,i + 37*A1,i - 10*A2,i + 2*A3,i </t>
<t>where j = -2,...,3 </t>
<t>i0,0 = (3*a0,-2 - 17*a0,-1 + 78*a0,0 + 78*a0,1 - 17*a0,2 + 3*a0,3 + 8192)/16384 </t>
<t>However, some of the sub-pixel positions have different filters which can be non-separable and/or have different filter coefficients. The minimum sub-block size is 8x8.
          </t>

<figure align="center" anchor="subpixels" title="Sub-pixel positions">
<artwork align="center">
<![CDATA[
+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|A    |     |     |     |A    |a    |b    |c    |A    |
|-1,-1|     |     |     | 0,-1| 0,-1| 0,-1| 0,-1| 1,-1|
+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|     |     |     |     |     |     |     |     |     |
|     |     |     |     |     |     |     |     |     |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|     |     |     |     |     |     |     |     |     |
|     |     |     |     |     |     |     |     |     |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|     |     |     |     |     |     |     |     |     |
|     |     |     |     |     |     |     |     |     |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|A    |     |     |     |A    |a    |b    |c    |A    |
|-1,0 |     |     |     | 0,0 | 0,0 | 0,0 | 0,0 | 1,0 |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|d    |     |     |     |d    |e    |f    |g    |d    |
|-1,0 |     |     |     | 0,0 | 0,0 | 0,0 | 0,0 | 1,0 |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|h    |     |     |     |h    |i    |j    |k    |h    |
|-1,0 |     |     |     | 0,0 | 0,0 | 0,0 | 0,0 | 1,0 |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|l    |     |     |     |l    |m    |n    |o    |l    |
|-1,0 |     |     |     | 0,0 | 0,0 | 0,0 | 0,0 | 1,0 |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+
|A    |     |     |     |A    |a    |b    |c    |A    |
|-1,1 |     |     |     | 0,1 | 0,1 | 0,1 | 0,1 | 1,1 |
+-----+-----+-----+-----+-----+-----+-----+-----+-----+

]]>
</artwork>
</figure>

        </section>
        
        <section title="Luma Special Filter Position">
          <t>
For the fractional pixel position having exactly 2 quarter pixel offsets in each dimension, a non-separable filter is used to calculate the interpolated value. With reference to <xref target="subpixels"></xref>, the center position j0,0 is calculated as follows:</t>
<t> j0,0 = </t>
<t> [0*A-1,-1 + 1*A0,-1 + 1*A1,-1 + 0*A2,-1 + </t>
<t> 1*A-1,0 + 2*A0,0  + 2*A1,0 + 1*A2,0 + </t>
<t> 1*A-1,1 + 2*A0,1  + 2*A1,1 + 1*A2,1 + </t>
<t> 0*A-1,2 + 1*A0,2 + 1*A1,2 + 0*A2,2 + 8]/16 </t>
        </section>
        
        <section title="Chroma Poly-phase Filter">
          <t>
Chroma interpolation is performed with 1/8 pixel resolution using the following poly-phase filter.</t>
<t> 1/8 phase:	[-2, 58,  10,-2]/64 </t>
<t> 2/8 phase:	[-4, 54, 16, -2]/64 </t>
<t> 3/8 phase:	[-4, 44, 28, -4]/64 </t>
<t> 4/8 phase:	[-4, 36, 36, -4]/64 </t>
<t> 5/8 phase:	[-4, 28, 44, -4]/64 </t>
<t> 6/8 phase:	[-2, 16, 54, -4]/64 </t>
<t> 7/8 phase:	[-2, 10, 58, -2]/64 </t>
        </section>
      </section>
      
      <section title="Motion Vector Coding">
        <section title="Inter0 and Inter1 Modes">
          <t>
Inter0 and inter1 modes imply signaling of a motion vector index to choose a motion vector from a list of candidate motion vectors with associated reference frame index. A list of motion vector candidates are derived from at most two different neighbor blocks, each having a unique motion vector/reference frame index. Signaling of the motion vector index uses 0 or 1 bit, dependent on the number of unique motion vector candidates. If the chosen neighbor block is coded in bi-prediction mode, the inter0 or inter1 block inherits both motion vectors, both reference indices and the bi-prediction property of the neighbor block.
</t>
<t>
For block sizes less than 64x64, inter0 has only one motion vector candidate, and its value is always zero.
</t>
<t>
Which neighbor blocks to use for motion vector candidates depends on the availability of the neighbor blocks (i.e. whether the neighbor blocks have already been coded, belong to the same slice and are not outside the frame boundaries). Four different availabilities, U, UR, L, and LL, are defined as illustrated in <xref target="neighbors"></xref>. If the neighbor block is intra it is considered to be available but with a zero motion vector.
</t>


<figure align="center" anchor="neighbors" title="Availability of neighbor blocks">
<artwork align="center">
<![CDATA[
           |           |
           |     U     |    UR
-----------+-----------+-----------
           |           |
           |  current  |
     L     |   block   |
           |           |
           |           |
-----------+-----------+
           |
           |
     LL    |
           |
]]>
</artwork>
</figure>


<t>
Based on the four availabilities defined above, each of the motion vector candidates is derived from one of the nine possible neighbor blocks defined in <xref target="candidates"></xref>.
</t>


<figure align="center" anchor="candidates" title="Motion vector candidates">
<artwork align="center">
<![CDATA[
+----+----+      +----+    +----+----+
| UL | U0 |      | U1 |    | U2 | UR |
+----+----+------+----+----+----+----+
| L0 |                          |
+----+                          |
     |                          |
     |                          |
+----+        current           |
| L1 |         block            |
+----+                          |
     |                          |
+----+                          |
| L2 |                          |
+----+--------------------------+
| LL |
+----+
]]>
</artwork>
</figure>


<t>
The choice of motion vector candidates depends on the availability of neighbor blocks as shown in <xref target="mv_candidates"></xref>.
</t>
<texttable anchor="mv_candidates" title="Motion vector candidates for different availability of neighbor blocks">
<ttcol> U </ttcol>
<ttcol> UR </ttcol>
<ttcol> L </ttcol>
<ttcol> LL </ttcol>
<ttcol> Motion vector candidates </ttcol>
<c>
0
</c>
<c>
0
</c>
<c>
0
</c>
<c>
0
</c>
<c>
zero vector
</c>
<c>
1
</c>
<c>
0
</c>
<c>
0
</c>
<c>
0
</c>
<c>
U2, zero vector
</c>
<c>
0
</c>
<c>
1
</c>
<c>
0
</c>
<c>
0
</c>
<c>
NA
</c>
<c>
1
</c>
<c>
1
</c>
<c>
0
</c>
<c>
0
</c>
<c>
U2,zero vector
</c>
<c>
0
</c>
<c>
0
</c>
<c>
1
</c>
<c>
0
</c>
<c>
L2, zero vector
</c>
<c>
1
</c>
<c>
0
</c>
<c>
1
</c>
<c>
0
</c>
<c>
U2,L2
</c>
<c>
0
</c>
<c>
1
</c>
<c>
1
</c>
<c>
0
</c>
<c>
NA
</c>
<c>
1
</c>
<c>
1
</c>
<c>
1
</c>
<c>
0
</c>
<c>
U2,L2
</c>
<c>
0
</c>
<c>
0
</c>
<c>
0
</c>
<c>
1
</c>
<c>
NA
</c>
<c>
1
</c>
<c>
0
</c>
<c>
0
</c>
<c>
1
</c>
<c>
NA
</c>
<c>
0
</c>
<c>
1
</c>
<c>
0
</c>
<c>
1
</c>
<c>
NA
</c>
<c>
1
</c>
<c>
1
</c>
<c>
0
</c>
<c>
1
</c>
<c>
NA
</c>
<c>
0
</c>
<c>
0
</c>
<c>
1
</c>
<c>
1
</c>
<c>
L2, zero vector
</c>
<c>
1
</c>
<c>
0
</c>
<c>
1
</c>
<c>
1
</c>
<c>
U2,L2
</c>
<c>
0
</c>
<c>
1
</c>
<c>
1
</c>
<c>
1
</c>
<c>
NA
</c>
<c>
1
</c>
<c>
1
</c>
<c>
1
</c>
<c>
1
</c>
<c>
U2,L2
</c>
</texttable>
        </section>
        <section title="Inter2 and Bi-Prediction Modes">
          <t>
Motion vectors are coded using motion vector prediction. The motion vector predictor is defined as the median of the motion vectors from three neighbor blocks.  Definition of the motion vector predictor uses the same definition of availability and neighbors as in <xref target="neighbors"></xref> and <xref target="candidates"></xref> respectively. The three vectors used for median filtering depends on the availability of neighbor blocks as shown in <xref target="mv_median"></xref>. If the neighbor block is coded in bi-prediction mode, only the first motion vector (in transmission order), MV0, is used as input to the median operator.</t>

<texttable anchor="mv_median" title="Neighbor blocks used to define motion vector predictor through median filtering">
<ttcol> U </ttcol>
<ttcol> UR </ttcol>
<ttcol> L </ttcol>
<ttcol> LL </ttcol>
<ttcol> Motion vectors for median filtering </ttcol>
<c>
0
</c>
<c>
0
</c>
<c>
0
</c>
<c>
0
</c>
<c>
3 x zero vector
</c>
<c>
1
</c>
<c>
0
</c>
<c>
0
</c>
<c>
0
</c>
<c>
U0,U1,U2
</c>
<c>
0
</c>
<c>
1
</c>
<c>
0
</c>
<c>
0
</c>
<c>
NA
</c>
<c>
1
</c>
<c>
1
</c>
<c>
0
</c>
<c>
0
</c>
<c>
U0,U2,UR
</c>
<c>
0
</c>
<c>
0
</c>
<c>
1
</c>
<c>
0
</c>
<c>
L0,L1,L2
</c>
<c>
1
</c>
<c>
0
</c>
<c>
1
</c>
<c>
0
</c>
<c>
UL,U2,L2
</c>
<c>
0
</c>
<c>
1
</c>
<c>
1
</c>
<c>
0
</c>
<c>
NA
</c>
<c>
1
</c>
<c>
1
</c>
<c>
1
</c>
<c>
0
</c>
<c>
U0,UR,L2,L0
</c>
<c>
0
</c>
<c>
0
</c>
<c>
0
</c>
<c>
1
</c>
<c>
NA
</c>
<c>
1
</c>
<c>
0
</c>
<c>
0
</c>
<c>
1
</c>
<c>
NA
</c>
<c>
0
</c>
<c>
1
</c>
<c>
0
</c>
<c>
1
</c>
<c>
NA
</c>
<c>
1
</c>
<c>
1
</c>
<c>
0
</c>
<c>
1
</c>
<c>
NA
</c>
<c>
0
</c>
<c>
0
</c>
<c>
1
</c>
<c>
1
</c>
<c>
L0,L2,LL
</c>
<c>
1
</c>
<c>
0
</c>
<c>
1
</c>
<c>
1
</c>
<c>
U2,L0,LL
</c>
<c>
0
</c>
<c>
1
</c>
<c>
1
</c>
<c>
1
</c>
<c>
NA
</c>
<c>
1
</c>
<c>
1
</c>
<c>
1
</c>
<c>
1
</c>
<c>
U0,UR,L0
</c>
          </texttable>
        </section>
      </section>
    </section>
    
    <section title="Transforms">
      <t>
Transforms are applied at the TB or CB level, implying that transform sizes range from 4x4 to 64x64. The transforms form an embedded structure meaning the transform matrix elements of the smaller transforms can be extracted from the larger transforms.
      </t>
    </section>
    
    <section title="Quantization">
      <t>
For the 32x32 and 64x64 transform sizes, only the 16x16 low frequency coefficients are quantized and transmitted.</t>

<t>Quantizer step-size control is not implemented yet, but some sort of sub-frame control is desired.
      </t>
    </section>
    
    <section title="Loop Filtering">
      <section title="Deblocking">
        <section title="Luma deblocking">
          <t>
Luma deblocking is performed on an 8x8 grid as follows:
<list style="numbers">
<t>For each vertical edge between two 8x8 blocks, calculate the following for each of line 2 and line 5 respectively:
<vspace blankLines="1" />
d =  abs(a-b) + abs(c-d),
<vspace blankLines="1" />
where a and b, are on the left  hand side of the block edge and c and d are on the right hand side of the block edge:
<vspace blankLines="1" />
a b | c d
</t>
<t>For each line crossing the vertical edge, perform deblocking if and only if all of the following conditions are true:
<list style="symbols">
<t> d2+d5 &lt; beta(QP) </t>
<t> The edge is also a transform block edge </t>
<t> abs(mvx(left)) &gt; 2, or abs(mvx(right)) &gt; 2, or
    <vspace blankLines="1" />
    abs(mvy(left)) &gt; 2, or abs(mvy(right)) &gt; 2, or
    <vspace blankLines="1" />
    One of the transform blocks on each side of the edge has non-zero coefficients, or
    <vspace blankLines="1" />
    One of the transform blocks on each side of the edge is coded using intra mode.
</t>
</list>
</t>
<t> If deblocking is performed, calculate a delta value as follows:
  <vspace blankLines="1" />
  delta = clip((18*(c-b) - 6*(d-a) + 16)/32,tc,-tc),
  <vspace blankLines="1" />
  where tc is a QP-dependent value.
</t>
<t> Next, modify two pixels on each side of the block edge as follows:
  <vspace blankLines="1" />
  a&apos; = a + delta/2
  <vspace blankLines="1" />
  b&apos; = b + delta
  <vspace blankLines="1" />
  c&apos; = c + delta
  <vspace blankLines="1" />
  d&apos; = d + delta/2
</t>
<t> The same procedure is followed for horizontal block edges.</t>
</list>
  The relative positions of the samples, a, b, c, d and the motion vectors, MV, are illustrated in <xref target="deblocking_filter"></xref>.
          </t>
          
<figure align="center" anchor="deblocking_filter" title="Deblocking filter pixel positions">
<artwork align="center">
<![CDATA[
         |
         | block edge
         |
 +---+---+---+---+
 | a | b | c | d |
 +---+---+---+---+
         |
mv       | mv
  x,left |   x,right
         |
mv         mv
  y,left     y,right
]]>
</artwork>
</figure>


        </section>
          
        <section title="Chroma Deblocking">
          <t>
  Chroma deblocking is performed on a 4x4 grid as follows:
  <list style="numbers">
  <t> Delocking of the edge between two 4x4 blocks is performed if and only if:
    <list style="symbols">
      <t> The pixels on either side of the block edge belongs to an intra block. </t>
      <t> The block edge is also an edge between two transform blocks. </t>
    </list>
  </t>
  <t> If deblocking is performed, calculate a delta value as follows:
      <vspace blankLines="1" />
      delta = clip((4*(c-b) + (d-a) + 4)/8,tc,-tc),
      <vspace blankLines="1" />
      where tc is a QP-dependent value.
  </t>
  <t> Next, modify one pixel on each side of the block edge as follows:
      <vspace blankLines="1" />
      b&apos; = b + delta
      <vspace blankLines="1" />
      c&apos; = c + delta
  </t>
  </list>
          </t>
        </section>
      </section>
      
      <section title="Constrained Low Pass Filter (CLPF1)">
        <t>
  A low-pass filter is applied after the deblocking filter and operates on 64x64 block units as follows:
  <list style="symbols">
  <t> 64x64 blocks that are encoded as 64x64 inter0 with a zero MV are not subject to filtering. </t>
  <t> For other 64x64 blocks, one bit (CLPFflag) is sent to signal filtering on/off. </t>
  <t> When the CLPFflag is equal to 1, perform filtering as follows:
      <vspace blankLines="1" />
      Delta = max(-1,min(1,(A+B+C+D-4X+2)>>2))
      <vspace blankLines="1" />
      X&apos; = X + Delta
  </t>
  </list>
  The relative positions of the pixel values A, B, C, D, and X are shown in <xref target="clp_filter"></xref>.
        </t>

<figure align="center" anchor="clp_filter" title="Constrained low pass filter pixel positions">
<artwork align="center">
<![CDATA[
    +---+
    | A |
+---+---+---+
| B | X | C |
+---+---+---+
    | D |
    +---+
]]>
</artwork>
</figure>

        
      </section>
    </section>
    
    <section title="Entropy coding">
      
      <section title="Overview">
<t> The following information is signaled at the sequence level:
  <list style="symbols">
  <t> Sequence header </t>
  </list>
</t>
<t> The following information is signaled at the frame level:
  <list style="symbols">
  <t> Frame header </t>
  </list>
</t>
<t> The following information is signaled at the CB level:
  <list style="symbols">
  <t> Super-mode (mode, split, reference index for uni-prediction) </t>
  <t> Intra prediction mode </t>
  <t> PB-split (none, hor, ver, quad) </t>
  <t> TB-split (none or quad) </t>
  <t> Reference frame indices for bi-prediction </t>
  <t> Motion vector candidate index </t>
  <t> Transform coefficients if TB-split=0 </t>
  </list>
</t>
<t> The following information is signaled at the TB level:
  <list style="symbols">
  <t> CBP (8 combinations of CBPY, CBPU, and CBPV) </t>
  <t> Transform coefficients </t>
  </list>
</t>
<t> The following information is signaled at the PB level:
  <list style="symbols">
  <t> Motion vector differences </t>
  </list>
</t>
      </section>
      
      <section title="Low Level Syntax">
        
        <section title="CB Level">
<t>
<figure><artwork><![CDATA[
    super-mode		(inter0/split/inter1/inter2-ref0/intra/inter2-ref1/inter2-ref2/inter-ref3,..)

    if (mode == inter0 || mode == inter1)

      mv_idx 			(one of up to 2 motion vector candidates)

    else if (mode == INTRA)

      intra_mode		(one of up to 8 intra modes)
  
      tb_split			(NONE or QUAD, coded jointly with CBP for tb_split=NONE)

    else if (mode == INTER)

      pb_split 		(NONE,VER,HOR,QUAD)
  
      tb_split_and_cbp	(NONE or QUAD and CBP)

    else if (mode == BIPRED)

      mvd_x0, mvd_y0	(motion vector difference for first vector)
  
      mvd_x1, mvd_y1	(motion vector difference for second vector)
  
      ref_idx0, ref_idx1	(two reference indices)
]]></artwork></figure>
</t>
        </section>
        
        <section title="PB Level">
          <t>
<figure><artwork><![CDATA[
    if (mode == INTER2 || mode == BIPRED)
    
      mvd_x, mvd_y		(motion vector differences)
]]></artwork></figure>
          </t>
        </section>
        
        <section title="TB Level">
          <t>
<figure><artwork><![CDATA[
    if (mode != INTER0 and tb_split == 1)
    
      cbp			(8 possibilities for CBPY/CBPU/CBPV)
      
    if (mode != INTER0)
    
      transform coefficients
]]></artwork></figure>
          </t>
        </section>
        
        <section title="Super Mode">
          <t>
For each block of size NxN (64>=N>8), the following mutually exclusive events are jointly encoded using a single VLC code as follows (example using 4 reference frames):
<figure><artwork><![CDATA[
  INTER0      1
  SPLIT       01
  INTER1      001
  INTER2-REF0 0001
  INTRA       00001
  INTER2-REF1 000001
  INTER2-REF2 0000001
  INTER2-REF3 00000001
  BIPRED      00000000
]]></artwork></figure>
</t>
<t>
If less than 4 reference frames is used, a shorter VLC table is used.
</t>
<t>
For each block of size 8x8, the following mutually exclusive events are jointly encoded using a single VLC code as follows (example using 4 reference frames):
<figure><artwork><![CDATA[
  INTER0      1
  INTER1      01
  INTER2-REF0 001
  INTRA       0001
  INTER2-REF1 00001
  INTER2-REF2 000001
  INTER2-REF3 0000001
  BIPRED      0000000
]]></artwork></figure>
</t>
<t>
Additionally, depending on information from the blocks to the left and above (meta data and CBP), a different sorting of the events can be used, e.g.:
<figure><artwork><![CDATA[
  SPLIT       1
  INTER1      01
  INTER2-REF0 001
  INTER0      0001
  INTRA       00001
  INTER2-REF1 000001
  INTER2-REF2 0000001
  INTER2-REF3 00000001
  BIPRED      00000000
]]></artwork></figure>
          </t>
        </section>
        
        <section title="CBP">
<t>  Calculate code as follows:
<figure><artwork><![CDATA[
    if (tb-split == 0)
    
      N = 4*CBPV + 2*CBPU + CBPY
      
    else
    
      N = 8
]]></artwork></figure>
</t>
<t>  Map the value of N to code through a table lookup: </t>
<t>  code = table[N] </t>
<t>  where the purpose of the table lookup is the sort the different values of code according to decreasing probability (typically CBPY=1, CBPU=0, CBPV=0 having the highest probability). </t>
<t>  Use a different table depending on the values of CBPY in neighbor blocks (left and above).</t>
<t>  Encode the value of code using a systematic VLC code.</t>
        </section>
        
        <section title="Transform Coefficients">
          <t>
  Transform coefficient coding uses a traditional zig-zag scan pattern to convert a 2D array of quantized transform coefficients, coeff, to a 1D array of samples. VLC coding of quantized transform coefficients starts from the low frequency end of the 1D array using two different modes; level-mode and run-mode, starting in level-mode:
<list style="symbols">
<t> Level-mode
  <list style="symbols">
  <t> Encode each coefficient, coeff, separately </t>
  <t> Each coefficient is encoded by:
    <list style="symbols">
    <t> The absolute value, level=abs(coeff), using a VLC code and </t>
    <t> If level > 0, the sign bit (sign=0 or sign=1 for coeff>0 and coeff&lt;0 respectively). </t>
    </list>
  </t>
  <t> If coefficient N is zero, switch to run-mode, starting from coefficient N+1. </t>
  </list>
</t>
<t> Run-mode
  <list style="symbols">
  <t> For each non-zero coefficient, encode the combined event of:
    <list style="numbers">
    <t> Length of the zero-run, i.e. the number of zeros since the last non-zero coefficient. </t>
    <t> Whether or not level=abs(coeff) is greater than 1. </t>
    <t> End of block (EOB) indicating that there are no more non-zero coefficients. </t>
    </list>
  </t>
  
  <t> Additionally, if level = 1, code the sign bit. </t>
  <t> Additionally, if level > 1 define code = 2*(level-2)+sign, </t>
  <t> If the absolute value of coefficient N is larger than 1, switch to level-mode, starting from coefficient N+1. </t>
  </list>
</t>
</list>
</t>
<t> Example </t>
<t> <xref target="coeff_coding"></xref> illustrates an example where 16 quantized transform coefficients are encoded. </t>

<figure align="center" anchor="coeff_coding" title="Coefficients to encode">
<artwork align="center">
<![CDATA[
      4
                           3
2     |                       2
   1  |  1        1        |           1
|     |     0  0     0  0  |  |  0  0     0  0  0
|__|__|__|________|________|__|________|__________

]]>
</artwork>
</figure>

<t> <xref target="xfrm_coeff_coding"></xref> shows the mode, VLC number and symbols to be coded for each coefficient.
</t>
<texttable anchor="xfrm_coeff_coding" title="Transform coefficient encoding for the example above.">
<ttcol> Index </ttcol>
<ttcol> abs(coeff) </ttcol>
<ttcol> Mode </ttcol>
<ttcol> Encoded symbols </ttcol>
<c> 0
</c><c> 2
</c><c> level-mode
</c><c> level=2,sign
</c><c> 1
</c><c> 1
</c><c> level-mode
</c><c> level=1,sign
</c><c> 2
</c><c> 5
</c><c> level-mode
</c><c> level=5,sign
</c><c> 3
</c><c> 1
</c><c> level-mode
</c><c> level=1,sign
</c><c> 4
</c><c> 0
</c><c> level-mode
</c><c> level=0
</c><c> 5
</c><c> 0
</c><c> run-mode
</c><c> 
</c><c> 6
</c><c> 1
</c><c> run-mode
</c><c> (run=1,level=1)
</c><c> 7
</c><c> 0
</c><c> run-mode
</c><c> 
</c><c> 8
</c><c> 0
</c><c> run-mode
</c><c> 
</c><c> 9
</c><c> 3
</c><c> run-mode
</c><c> (run=1,level>1),   2*(3-2)+sign
</c><c> 10
</c><c> 2
</c><c> level-mode
</c><c> level=2, sign
</c><c> 11
</c><c> 0
</c><c> level-mode
</c><c> level=0
</c><c> 12
</c><c> 0
</c><c> run-mode
</c><c> 
</c><c> 13
</c><c> 1
</c><c> run-mode
</c><c> (run=1,level=1)
</c><c> 14
</c><c> 0
</c><c> run-mode
</c><c> EOB
</c><c> 15
</c><c> 0
</c><c> run-mode
</c><c>
</c>
</texttable>

        </section>
      </section>
    </section>
    
    <section title="High Level Syntax">
      <t>
    High level syntax is currently very simple and rudimentary as the primary focus so far has been on compression performance. It is expected to evolve as functionality is added.
      </t>
      <section title="Sequence Header">
        <t>
<list style="symbols">
<t> Width - 16 bit
</t>
<t> Height - 16 bit
</t>
<t> Enable/disable PB-split - 1 bit
</t>
<t> Enable/disable TB-split - 1 bit
</t>
<t> Number of active reference frames (may go into frame header) - 2 bits (max 4)
</t>
<t> Enable/disable deblocking - 1 bit
</t>
<t> Enable/disable constrained low-pass filter (CLPF1) - 1 bit
</t>
</list>
        </t>
      </section>
        
      <section title="Frame Header">
        <t>
<list style="symbols">
<t> Frame type - 1 bit
</t>
<t> QP - 8 bits
</t>
<t> Identification of active reference frames - num_ref*4 bits
</t>
<t> Number of intra modes - 4 bits
</t>
<t> Constrained low-pass filter (CLPF1) enable/disable - 1 bit
</t>
</list>
        </t>
      </section>
    </section>

    <section anchor="IANA" title="IANA Considerations">
      <t>This document has no IANA considerations yet. TBD</t>
    </section>

    <section anchor="Security" title="Security Considerations">
      <t>This document has no security considerations yet. TBD</t>
    </section>

    <section anchor="Acknowledgements" title="Acknowledgements">
      <t>The authors would like to thank Thomas Davies, Steinar Midtskogen
        and Mo Zanaty for reviewing
        this document and design, and providing constructive feedback. </t>
    </section>
  </middle>

  <back>
    <references title="Normative References">
      <?rfc include="reference.RFC.2119"?>
    </references>
  </back>
</rfc>
