| |
| |
| #### 16.2 Inter-Predicted Macroblocks {#h-16-02} |
| |
| |
| Otherwise (when the above bool is true), we are using inter- |
| prediction (which of course only happens for interframes), to which |
| we now restrict our attention. |
| |
| The next datum is then another bool, `B( prob_last)`, selecting the |
| reference frame. If 0, the reference frame is the previous frame |
| (the last frame); if 1, another bool (`prob_gf`) selects the reference |
| frame between the golden frame (0) and the altref frame (1). The |
| probabilities `prob_last` and `prob_gf` are set in field J of the frame |
| header. |
| |
| Together with setting the reference frame, the purpose of inter-mode |
| decoding is to set a motion vector for each of the sixteen Y |
| subblocks of the current macroblock. These settings then define the |
| calculation of the inter-prediction buffer (detailed in Section 18). |
| |
| While the net effect of inter-mode decoding is straightforward, the |
| implementation is somewhat complex; the (lossless) compression |
| achieved by this method justifies the complexity. |
| |
| After the reference frame selector comes the mode (or motion vector |
| reference) applied to the macroblock as a whole, coded using the |
| following enumeration and tree. Setting `mv_nearest = num_ymodes` is a |
| convenience that allows a single variable to unambiguously hold an |
| inter- or intra-prediction mode. |
| |
| |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| typedef enum |
| { |
| mv_nearest = num_ymodes, /* use "nearest" motion vector |
| for entire MB */ |
| mv_near, /* use "next nearest" "" */ |
| mv_zero, /* use zero "" */ |
| mv_new, /* use explicit offset from |
| implicit "" */ |
| mv_split, /* use multiple motion vectors */ |
| |
| num_mv_refs = mv_split + 1 - mv_nearest |
| } |
| mv_ref; |
| |
| const tree_index mv_ref_tree [2 * (num_mv_refs - 1)] = |
| { |
| -mv_zero, 2, /* zero = "0" */ |
| -mv_nearest, 4, /* nearest = "10" */ |
| -mv_near, 6, /* near = "110" */ |
| -mv_new, -mv_split /* new = "1110", split = "1111" */ |
| }; |
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| {:lang="c"} |
| |