Tuesday, December 12, 2017

VP9 ELI5 Part 7

Now we need to write the data for the first 32x32 block. Remember that the last chapter ended with us recursively calling decode_partition(). Now we need partition to be PARTITION_NONE because we don't want to split the 32x32 block any further.

Let's go to the beginning of decode_partition(), section 6.4.3 of the spec PDF.



Skip the first IF statement since we're not on any right or bottom boundaries.

num8x8 will be 4 since you could fit 4 8x8 blocks inside the width of a 32x32 block.
halfBlock8x8 is rather obvious: 2.
hasRows and hasCols are both TRUE.

Now let's take care of our partition field. Remember, we need it to be PARTITION_NONE.


Plugging our values into this method, we find that our first probability is 17. For PARTITION_NONE, it's quite easy. We just need to write a 0 with probability 17. Let's add that to our running tally of bits.

Running tally of bits
1, p = 10
1, p = 7
1, p = 6
0, p = 17

Continuing, subsize is going to be BLOCK_32X32, or numerically, 9.

The next line is an IF block. We want to check if subsize is smaller than 8x8 OR if partition is PARTITION_NONE. In our case, the second condition is met so we will execute the statement inside the block, decode_block(r, c, subsize).


MiRow = 0
MiCol = 0
MiSize = BLOCK_32X32
AvailU = FALSE
AvailL = FALSE

Now we need to do mode_info().


This is an intra frame so we'll execute intra_frame_mode_info().


We can skip intra_segment_id() since we chose not to enable segmentation. intra_segment will be 0.

read_skip() reads a value called skip. We want skip to be 0 because we don't want to skip over this block.


Skip is a Tree value, so we need to figure out the probabilities to use when writing it.


Since AvailU and AvailL are both FALSE, ctx will be 0. This means our probability will be skip_prob[0]. We want default_skip_prob[0] since we didn't change any probabilities. default_skip_prob[0] is 192.


The Note at the bottom is interesting because it means that this is not a tree, but instead a normal bit flag expressed as a bool value. That means all we have to do is write 0 with probability 192.

Running tally of bits
1, p = 10
1, p = 7
1, p = 6
0, p = 17
0, p = 192

Now it's time for read_tx_size(1).


allowSelect is 1, but TX_MODE_SELECT is FALSE so we'll execute the code in the ELSE block. tx_size will be the lesser of maxTxSize and tx_mode_to_biggest_tx_size[tx_mode]. tx_mode, as you may recall, has been set to ALLOW_32X32.

maxTxSize is TX_32X32.  tx_mode_to_biggest_tx_size[ALLOW_32X32] = TX_32X32. So, tx_size will be TX_32X32.

Now we have some more state variables:
     ref_frame[0] = INTRA_FRAME
     ref_frame[1] = NONE
     is_inter = 0

Now we reach an IF block that checks to see that we're working on an 8x8 block or larger. Since we are, we'll execute the statements in here and skip the ELSE block underneath.

We need to figure out default_intra_mode, which is a Tree value. Let's look at what intra modes are available.


Before we go on, you may be wondering what these intra modes do. Well, intra modes are smudge functions. You see, compressing a video isn't just about finding differences between frames. You also have to compress as much as you can within each frame. That's what "intra" compression is all about.

So in an intra frame (like the one we're encoding now), you don't just write image data. That would take a lot of space. Instead, you grab the top, left, or both top and left edges of the block and smudge them across, and then only save the difference between the actual image and the smudged block. Here is an example of all the possible smudge functions:


Let's start by getting the necessary probability.


Both abovemode and leftmode will be DC_PRED. That means our probability will be kf_y_mode_probs[DC_PRED][DC_PRED][0] which equals 137.

For simplicity, let's just write a 0 bit, which translates to DC_PRED.

Running tally of bits
1, p = 10
1, p = 7
1, p = 6
0, p = 17
0, p = 192
0, p = 137

Now we have to add some more state variables.
     y_mode = DC_PRED
     sub_modes[0 - 3] = DC_PRED

To finish up intra_frame_mode_info(), we need to write our default_uv_mode. We'll set it to DC_PRED so we can write as little as possible.


kf_uv_mode_probs[DC_PRED][0] = 144, so we need to write a 0 bit with probability 144.

Running tally of bits
1, p = 10
1, p = 7
1, p = 6
0, p = 17
0, p = 192
0, p = 137
0, p = 144

Another state variable:
     uv_mode = DC_PRED


Finally, we're done with mode_info() and we're back in decode_block().

We have another state variable,
     EobTotal = 0

The next step is residual(), which will be covered in the next chapter.

No comments:

Post a Comment