chromium / webm / bitstream-guide / 75582f114dffcbaf3530e88d5ddba7832cba8f9d / . / text_src / 16.04__vp8-bitstream__split-prediction.txt

#### 16.4 Split Prediction {#h-16-04} | |

The remaining mode (`SPLITMV`) causes multiple vectors to be applied to the Y subblocks. It is immediately followed by a partition specification that determines how many vectors will be specified and how they will be assigned to the subblocks. The possible partitions, with indicated subdivisions and coding tree, are as follows. | |

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |

typedef enum | |

{ | |

mv_top_bottom, /* two pieces {0...7} and {8...15} */ | |

mv_left_right, /* {0,1,4,5,8,9,12,13} and | |

{2,3,6,7,10,11,14,15} */ | |

mv_quarters, /* {0,1,4,5}, {2,3,6,7}, {8,9,12,13}, | |

{10,11,14,15} */ | |

MV_16, /* every subblock gets its own vector | |

{0} ... {15} */ | |

mv_num_partitions | |

} | |

MVpartition; | |

const tree_index mvpartition_tree [2 * (mvnum_partition - 1)] = | |

{ | |

-MV_16, 2, /* MV_16 = "0" */ | |

-mv_quarters, 4, /* mv_quarters = "10" */ | |

-mv_top_bottom, -mv_left_right /* top_bottom = "110", | |

left_right = "111" */ | |

}; | |

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |

{:lang="c"} | |

The partition is decoded using a fixed, constant probability table: | |

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |

const Prob mvpartition_probs [mvnum_partition - 1] = | |

{ 110, 111, 150}; | |

part = (MVpartition) treed_read( d, mvpartition_tree, | |

mvpartition_probs); | |

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |

{:lang="c"} | |

After the partition come two (for `mv_top_bottom` or `mv_left_right`), four (for `mv_quarters`), or sixteen (for `MV_16`) subblock inter-prediction modes. These modes occur in the order indicated by the partition layouts (given as comments to the `MVpartition` enum) and are coded as follows. (As was done for the macroblock-level modes, we offset the mode enumeration so that a single variable may unambiguously hold either an intra- or inter-subblock mode.) | |

Prior to decoding each subblock, a decoding tree context is chosen as illustrated in the code snippet below. The context is based on the immediate left and above subblock neighbors, and whether they are equal, are zero, or a combination of those. | |

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |

typedef enum | |

{ | |

LEFT4x4 = num_intra_bmodes, /* use already-coded MV to | |

my left */ | |

ABOVE4x4, /* use already-coded MV above me */ | |

ZERO4x4, /* use zero MV */ | |

NEW4x4, /* explicit offset from "best" */ | |

num_sub_mv_ref | |

}; | |

sub_mv_ref; | |

const tree_index sub_mv_ref_tree [2 * (num_sub_mv_ref - 1)] = | |

{ | |

-LEFT4X4, 2, /* LEFT = "0" */ | |

-ABOVE4X4, 4, /* ABOVE = "10" */ | |

-ZERO4X4, -NEW4X4 /* ZERO = "110", NEW = "111" */ | |

}; | |

/* Choose correct decoding tree context | |

* Function parameters are left subblock neighbor MV and above | |

* subblock neighbor MV */ | |

int vp8_mvCont(MV *l, MV*a) | |

{ | |

int lez = (l->row == 0 && l->col == 0); /* left neighbour | |

is zero */ | |

int aez = (a->row == 0 && a->col == 0); /* above neighbour | |

is zero */ | |

int lea = (l->row == a->row && l->col == a->col); /* left | |

neighbour equals above neighbour */ | |

if(lea && lez) | |

return SUBMVREF_LEFT_ABOVE_ZED; /* =4 */ | |

if(lea) | |

return SUBMVREF_LEFT_ABOVE_SAME; /* =3 */ | |

if(aez) | |

return SUBMVREF_ABOVE_ZED; /* =2 */ | |

if(lez) | |

return SUBMVREF_LEFT_ZED; /* =1*/ | |

return SUBMVREF_NORMAL; /* =0 */ | |

} | |

/* Constant probabilities and decoding procedure. */ | |

const Prob sub_mv_ref_prob [5][num_sub_mv_ref - 1] = { | |

{ 147,136,18 }, | |

{ 106,145,1 }, | |

{ 179,121,1 }, | |

{ 223,1 ,34 }, | |

{ 208,1 ,1 } }; | |

sub_ref = (sub_mv_ref) treed_read( d, sub_mv_ref_tree, | |

sub_mv_ref_prob[context]); | |

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |

{:lang="c"} | |

The first two sub-prediction modes simply copy the already-coded motion vectors used by the blocks above and to-the-left of the subblock at the upper left corner of the current subset (i.e., collection of subblocks being predicted). These prediction blocks need not lie in the current macroblock and, if the current subset lies at the top or left edges of the frame, need not lie in the frame. In this latter case, their motion vectors are taken to be zero, as are subblock motion vectors within an intra-predicted macroblock. Also, to ensure the correctness of prediction within this macroblock, all subblocks lying in an already-decoded subset of the current macroblock must have their motion vectors set. | |

`ZERO4x4` uses a zero motion vector and predicts the current subset using the corresponding subset from the prediction frame. | |

NEW4x4 is exactly like NEWMV except applied only to the current subset. It is followed by a 2-dimensional motion vector offset (described in the next chapter) that is added to the best vector returned by the earlier call to find_near_mvs to form the motion vector in effect for the subset. | |

Parsing of both inter-prediction modes and motion vectors (described next) can be found in the reference decoder file `decodemv.c`. | |