diff options
author | Thomas Voss <mail@thomasvoss.com> | 2024-11-27 20:54:24 +0100 |
---|---|---|
committer | Thomas Voss <mail@thomasvoss.com> | 2024-11-27 20:54:24 +0100 |
commit | 4bfd864f10b68b71482b35c818559068ef8d5797 (patch) | |
tree | e3989f47a7994642eb325063d46e8f08ffa681dc /doc/rfc/rfc6386.txt | |
parent | ea76e11061bda059ae9f9ad130a9895cc85607db (diff) |
doc: Add RFC documents
Diffstat (limited to 'doc/rfc/rfc6386.txt')
-rw-r--r-- | doc/rfc/rfc6386.txt | 17027 |
1 files changed, 17027 insertions, 0 deletions
diff --git a/doc/rfc/rfc6386.txt b/doc/rfc/rfc6386.txt new file mode 100644 index 0000000..bb4d70b --- /dev/null +++ b/doc/rfc/rfc6386.txt @@ -0,0 +1,17027 @@ + + + + + + +Independent Submission J. Bankoski +Request for Comments: 6386 J. Koleszar +Category: Informational L. Quillio +ISSN: 2070-1721 J. Salonen + P. Wilkins + Y. Xu + Google Inc. + November 2011 + + + VP8 Data Format and Decoding Guide + +Abstract + + This document describes the VP8 compressed video data format, + together with a discussion of the decoding procedure for the format. + +Status of This Memo + + This document is not an Internet Standards Track specification; it is + published for informational purposes. + + This is a contribution to the RFC Series, independently of any other + RFC stream. The RFC Editor has chosen to publish this document at + its discretion and makes no statement about its value for + implementation or deployment. Documents approved for publication by + the RFC Editor are not a candidate for any level of Internet + Standard; see Section 2 of RFC 5741. + + Information about the current status of this document, any errata, + and how to provide feedback on it may be obtained at + http://www.rfc-editor.org/info/rfc6386. + +Copyright Notice + + Copyright (c) 2011 IETF Trust and the persons identified as the + document authors. All rights reserved. + + This document is subject to BCP 78 and the IETF Trust's Legal + Provisions Relating to IETF Documents + (http://trustee.ietf.org/license-info) in effect on the date of + publication of this document. Please review these documents + carefully, as they describe your rights and restrictions with respect + to this document. + + + + + + + +Bankoski, et al. Informational [Page 1] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +Table of Contents + + 1. Introduction ....................................................4 + 2. Format Overview .................................................5 + 3. Compressed Frame Types ..........................................7 + 4. Overview of Compressed Data Format ..............................8 + 5. Overview of the Decoding Process ................................9 + 6. Description of Algorithms ......................................14 + 7. Boolean Entropy Decoder ........................................16 + 7.1. Underlying Theory of Coding ...............................17 + 7.2. Practical Algorithm Description ...........................18 + 7.3. Actual Implementation .....................................20 + 8. Compressed Data Components .....................................25 + 8.1. Tree Coding Implementation ................................27 + 8.2. Tree Coding Example .......................................28 + 9. Frame Header ...................................................30 + 9.1. Uncompressed Data Chunk ...................................30 + 9.2. Color Space and Pixel Type (Key Frames Only) ..............33 + 9.3. Segment-Based Adjustments .................................34 + 9.4. Loop Filter Type and Levels ...............................35 + 9.5. Token Partition and Partition Data Offsets ................36 + 9.6. Dequantization Indices ....................................37 + 9.7. Refresh Golden Frame and Altref Frame .....................38 + 9.8. Refresh Last Frame Buffer .................................39 + 9.9. DCT Coefficient Probability Update ........................39 + 9.10. Remaining Frame Header Data (Non-Key Frame) ..............40 + 9.11. Remaining Frame Header Data (Key Frame) ..................41 + 10. Segment-Based Feature Adjustments .............................41 + 11. Key Frame Macroblock Prediction Records .......................42 + 11.1. mb_skip_coeff ............................................42 + 11.2. Luma Modes ...............................................42 + 11.3. Subblock Mode Contexts ...................................45 + 11.4. Chroma Modes .............................................46 + 11.5. Subblock Mode Probability Table ..........................47 + 12. Intraframe Prediction .........................................50 + 12.1. mb_skip_coeff ............................................51 + 12.2. Chroma Prediction ........................................51 + 12.3. Luma Prediction ..........................................54 + 13. DCT Coefficient Decoding ......................................60 + 13.1. Macroblock without Non-Zero Coefficient Values ...........61 + 13.2. Coding of Individual Coefficient Values ..................61 + 13.3. Token Probabilities ......................................63 + 13.4. Token Probability Updates ................................68 + 13.5. Default Token Probability Table ..........................73 + + + + + + + +Bankoski, et al. Informational [Page 2] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + 14. DCT and WHT Inversion and Macroblock Reconstruction ...........76 + 14.1. Dequantization ...........................................76 + 14.2. Inverse Transforms .......................................78 + 14.3. Implementation of the WHT Inversion ......................78 + 14.4. Implementation of the DCT Inversion ......................81 + 14.5. Summation of Predictor and Residue .......................83 + 15. Loop Filter ...................................................84 + 15.1. Filter Geometry and Overall Procedure ....................85 + 15.2. Simple Filter ............................................87 + 15.3. Normal Filter ............................................91 + 15.4. Calculation of Control Parameters ........................95 + 16. Interframe Macroblock Prediction Records ......................97 + 16.1. Intra-Predicted Macroblocks ..............................97 + 16.2. Inter-Predicted Macroblocks ..............................98 + 16.3. Mode and Motion Vector Contexts ..........................99 + 16.4. Split Prediction ........................................105 + 17. Motion Vector Decoding .......................................108 + 17.1. Coding of Each Component ................................108 + 17.2. Probability Updates .....................................110 + 18. Interframe Prediction ........................................113 + 18.1. Bounds on, and Adjustment of, Motion Vectors ............113 + 18.2. Prediction Subblocks ....................................115 + 18.3. Sub-Pixel Interpolation .................................115 + 18.4. Filter Properties .......................................118 + 19. Annex A: Bitstream Syntax ....................................120 + 19.1. Uncompressed Data Chunk .................................121 + 19.2. Frame Header ............................................122 + 19.3. Macroblock Data .........................................130 + 20. Attachment One: Reference Decoder Source Code ................133 + 20.1. bit_ops.h ...............................................133 + 20.2. bool_decoder.h ..........................................133 + 20.3. dequant_data.h ..........................................137 + 20.4. dixie.c .................................................138 + 20.5. dixie.h .................................................151 + 20.6. dixie_loopfilter.c ......................................158 + 20.7. dixie_loopfilter.h ......................................170 + 20.8. idct_add.c ..............................................171 + 20.9. idct_add.h ..............................................174 + 20.10. mem.h ..................................................175 + 20.11. modemv.c ...............................................176 + 20.12. modemv.h ...............................................192 + 20.13. modemv_data.h ..........................................193 + 20.14. predict.c ..............................................198 + 20.15. predict.h ..............................................231 + 20.16. tokens.c ...............................................232 + 20.17. tokens.h ...............................................242 + 20.18. vp8_prob_data.h ........................................243 + 20.19. vpx_codec_internal.h ...................................252 + + + +Bankoski, et al. Informational [Page 3] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + 20.20. vpx_decoder.h ..........................................263 + 20.21. vpx_decoder_compat.h ...................................271 + 20.22. vpx_image.c ............................................285 + 20.23. vpx_image.h ............................................291 + 20.24. vpx_integer.h ..........................................298 + 20.25. AUTHORS File ...........................................299 + 20.26. LICENSE ................................................301 + 20.27. PATENTS ................................................302 + 21. Security Considerations ......................................302 + 22. References ...................................................303 + 22.1. Normative Reference .....................................303 + 22.2. Informative References ..................................303 + +1. Introduction + + This document describes the VP8 compressed video data format, + together with a discussion of the decoding procedure for the format. + It is intended to be used in conjunction with, and as a guide to, the + reference decoder source code provided in Attachment One + (Section 20). If there are any conflicts between this narrative and + the reference source code, the reference source code should be + considered correct. The bitstream is defined by the reference source + code and not this narrative. + + Like many modern video compression schemes, VP8 is based on + decomposition of frames into square subblocks of pixels, prediction + of such subblocks using previously constructed blocks, and adjustment + of such predictions (as well as synthesis of unpredicted blocks) + using a discrete cosine transform (hereafter abbreviated as DCT). In + one special case, however, VP8 uses a Walsh-Hadamard transform + (hereafter abbreviated as WHT) instead of a DCT. + + Roughly speaking, such systems reduce datarate by exploiting the + temporal and spatial coherence of most video signals. It is more + efficient to specify the location of a visually similar portion of a + prior frame than it is to specify pixel values. The frequency + segregation provided by the DCT and WHT facilitates the exploitation + of both spatial coherence in the original signal and the tolerance of + the human visual system to moderate losses of fidelity in the + reconstituted signal. + + VP8 augments these basic concepts with, among other things, + sophisticated usage of contextual probabilities. The result is a + significant reduction in datarate at a given quality. + + + + + + + +Bankoski, et al. Informational [Page 4] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + Unlike some similar schemes (the older MPEG formats, for example), + VP8 specifies exact values for reconstructed pixels. Specifically, + the specification for the DCT and WHT portions of the reconstruction + does not allow for any "drift" caused by truncation of fractions. + Rather, the algorithm is specified using fixed-precision integer + operations exclusively. This greatly facilitates the verification of + the correctness of a decoder implementation and also avoids + difficult-to-predict visual incongruities between such + implementations. + + It should be remarked that, in a complete video playback system, the + displayed frames may or may not be identical to the reconstructed + frames. Many systems apply a final level of filtering (commonly + referred to as postprocessing) to the reconstructed frames prior to + viewing. Such postprocessing has no effect on the decoding and + reconstruction of subsequent frames (which are predicted using the + completely specified reconstructed frames) and is beyond the scope of + this document. In practice, the nature and extent of this sort of + postprocessing is dependent on both the taste of the user and on the + computational facilities of the playback environment. + + 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 RFC 2119 [RFC2119]. + +2. Format Overview + + VP8 works exclusively with an 8-bit YUV 4:2:0 image format. In this + format, each 8-bit pixel in the two chroma planes (U and V) + corresponds positionally to a 2x2 block of 8-bit luma pixels in the + Y plane; coordinates of the upper left corner of the Y block are of + course exactly twice the coordinates of the corresponding chroma + pixels. When we refer to pixels or pixel distances without + specifying a plane, we are implicitly referring to the Y plane or to + the complete image, both of which have the same (full) resolution. + + As is usually the case, the pixels are simply a large array of bytes + stored in rows from top to bottom, each row being stored from left to + right. This "left to right" then "top to bottom" raster-scan order + is reflected in the layout of the compressed data as well. + + Provision has been made in the VP8 bitstream header for the support + of a secondary YUV color format, in the form of a reserved bit. + + Occasionally, at very low datarates, a compression system may decide + to reduce the resolution of the input signal to facilitate efficient + compression. The VP8 data format supports this via optional + upscaling of its internal reconstruction buffer prior to output (this + + + +Bankoski, et al. Informational [Page 5] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + is completely distinct from the optional postprocessing discussed + earlier, which has nothing to do with decoding per se). This + upsampling restores the video frames to their original resolution. + In other words, the compression/decompression system can be viewed as + a "black box", where the input and output are always at a given + resolution. The compressor might decide to "cheat" and process the + signal at a lower resolution. In that case, the decompressor needs + the ability to restore the signal to its original resolution. + + Internally, VP8 decomposes each output frame into an array of + macroblocks. A macroblock is a square array of pixels whose Y + dimensions are 16x16 and whose U and V dimensions are 8x8. + Macroblock-level data in a compressed frame occurs (and must be + processed) in a raster order similar to that of the pixels comprising + the frame. + + Macroblocks are further decomposed into 4x4 subblocks. Every + macroblock has 16 Y subblocks, 4 U subblocks, and 4 V subblocks. Any + subblock-level data (and processing of such data) again occurs in + raster order, this time in raster order within the containing + macroblock. + + As discussed in further detail below, data can be specified at the + levels of both macroblocks and their subblocks. + + Pixels are always treated, at a minimum, at the level of subblocks, + which may be thought of as the "atoms" of the VP8 algorithm. In + particular, the 2x2 chroma blocks corresponding to 4x4 Y subblocks + are never treated explicitly in the data format or in the algorithm + specification. + + The DCT and WHT always operate at a 4x4 resolution. The DCT is used + for the 16Y, 4U, and 4V subblocks. The WHT is used (with some but + not all prediction modes) to encode a 4x4 array comprising the + average intensities of the 16 Y subblocks of a macroblock. These + average intensities are, up to a constant normalization factor, + nothing more than the 0th DCT coefficients of the Y subblocks. This + "higher-level" WHT is a substitute for the explicit specification of + those coefficients, in exactly the same way as the DCT of a subblock + substitutes for the specification of the pixel values comprising the + subblock. We consider this 4x4 array as a second-order subblock + called Y2, and think of a macroblock as containing 24 "real" + subblocks and, sometimes, a 25th "virtual" subblock. This is dealt + with further in Section 13. + + The frame layout used by the reference decoder may be found in the + file vpx_image.h (Section 20.23). + + + + +Bankoski, et al. Informational [Page 6] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +3. Compressed Frame Types + + There are only two types of frames in VP8. + + Intraframes (also called key frames and, in MPEG terminology, + I-frames) are decoded without reference to any other frame in a + sequence; that is, the decompressor reconstructs such frames + beginning from its "default" state. Key frames provide random access + (or seeking) points in a video stream. + + Interframes (also called prediction frames and, in MPEG terminology, + P-frames) are encoded with reference to prior frames, specifically + all prior frames up to and including the most recent key frame. + Generally speaking, the correct decoding of an interframe depends on + the correct decoding of the most recent key frame and all ensuing + frames. Consequently, the decoding algorithm is not tolerant of + dropped frames: In an environment in which frames may be dropped or + corrupted, correct decoding will not be possible until a key frame is + correctly received. + + In contrast to MPEG, there is no use of bidirectional prediction. No + frame is predicted using frames temporally subsequent to it; there is + no analog to an MPEG B-frame. + + Secondly, VP8 augments these notions with that of alternate + prediction frames, called golden frames and altref frames + (alternative reference frames). Blocks in an interframe may be + predicted using blocks in the immediately previous frame as well as + the most recent golden frame or altref frame. Every key frame is + automatically golden and altref, and any interframe may optionally + replace the most recent golden or altref frame. + + Golden frames and altref frames may also be used to partially + overcome the intolerance to dropped frames discussed above: If a + compressor is configured to code golden frames only with reference to + the prior golden frame (and key frame), then the "substream" of key + and golden frames may be decoded regardless of loss of other + interframes. Roughly speaking, the implementation requires (on the + compressor side) that golden frames subsume and recode any context + updates effected by the intervening interframes. A typical + application of this approach is video conferencing, in which + retransmission of a prior golden frame and/or a delay in playback + until receipt of the next golden frame is preferable to a larger + retransmit and/or delay until the next key frame. + + + + + + + +Bankoski, et al. Informational [Page 7] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +4. Overview of Compressed Data Format + + The input to a VP8 decoder is a sequence of compressed frames whose + order matches their order in time. Issues such as the duration of + frames, the corresponding audio, and synchronization are generally + provided by the playback environment and are irrelevant to the + decoding process itself; however, to aid in fast seeking, a start + code is included in the header of each key frame. + + The decoder is simply presented with a sequence of compressed frames + and produces a sequence of decompressed (reconstructed) YUV frames + corresponding to the input sequence. As stated in the Introduction, + the exact pixel values in the reconstructed frame are part of VP8's + specification. This document specifies the layout of the compressed + frames and gives unambiguous algorithms for the correct production of + reconstructed frames. + + The first frame presented to the decompressor is of course a key + frame. This may be followed by any number of interframes; the + correct reconstruction of each frame depends on all prior frames up + to the key frame. The next key frame restarts this process: The + decompressor resets to its default initial condition upon reception + of a key frame, and the decoding of a key frame (and its ensuing + interframes) is completely independent of any prior decoding. + + At the highest level, every compressed frame has three or more + pieces. It begins with an uncompressed data chunk comprising + 10 bytes in the case of key frames and 3 bytes for interframes. This + is followed by two or more blocks of compressed data (called + partitions). These compressed data partitions begin and end on byte + boundaries. + + The first compressed partition has two subsections: + + 1. Header information that applies to the frame as a whole. + + 2. Per-macroblock information specifying how each macroblock is + predicted from the already-reconstructed data that is available + to the decompressor. + + As stated above, the macroblock-level information occurs in raster- + scan order. + + The rest of the partitions contain, for each block, the DCT/WHT + coefficients (quantized and logically compressed) of the residue + signal to be added to the predicted block values. It typically + accounts for roughly 70% of the overall datarate. VP8 supports + packing the compressed DCT/WHT coefficients' data from macroblock + + + +Bankoski, et al. Informational [Page 8] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + rows into separate partitions. If there is more than one partition + for these coefficients, the sizes of the partitions -- except the + last partition -- in bytes are also present in the bitstream right + after the above first partition. Each of the sizes is a 3-byte data + item written in little endian format. These sizes provide the + decoder direct access to all DCT/WHT coefficient partitions, which + enables parallel processing of the coefficients in a decoder. + + The separate partitioning of the prediction data and coefficient data + also allows flexibility in the implementation of a decompressor: An + implementation may decode and store the prediction information for + the whole frame and then decode, transform, and add the residue + signal to the entire frame, or it may simultaneously decode both + partitions, calculating prediction information and adding in the + residue signal for each block in order. The length field in the + frame tag, which allows decoding of the second partition to begin + before the first partition has been completely decoded, is necessary + for the second "block-at-a-time" decoder implementation. + + All partitions are decoded using separate instances of the boolean + entropy decoder described in Section 7. Although some of the data + represented within the partitions is conceptually "flat" (a bit is + just a bit with no probabilistic expectation one way or the other), + because of the way such coders work, there is never a direct + correspondence between a "conceptual bit" and an actual physical bit + in the compressed data partitions. Only in the 3- or 10-byte + uncompressed chunk described above is there such a physical + correspondence. + + A related matter is that seeking within a partition is not supported. + The data must be decompressed and processed (or at least stored) in + the order in which it occurs in the partition. + + While this document specifies the ordering of the partition data + correctly, the details and semantics of this data are discussed in a + more logical fashion to facilitate comprehension. For example, the + frame header contains updates to many probability tables used in + decoding per-macroblock data. The per-macroblock data is often + described before the layouts of the probabilities and their updates, + even though this is the opposite of their order in the bitstream. + +5. Overview of the Decoding Process + + A VP8 decoder needs to maintain four YUV frame buffers whose + resolutions are at least equal to that of the encoded image. These + buffers hold the current frame being reconstructed, the immediately + previous reconstructed frame, the most recent golden frame, and the + most recent altref frame. + + + +Bankoski, et al. Informational [Page 9] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + Most implementations will wish to "pad" these buffers with + "invisible" pixels that extend a moderate number of pixels beyond all + four edges of the visible image. This simplifies interframe + prediction by allowing all (or most) prediction blocks -- which are + not guaranteed to lie within the visible area of a prior frame -- to + address usable image data. + + Regardless of the amount of padding chosen, the invisible rows above + (or below) the image are filled with copies of the top (or bottom) + row of the image; the invisible columns to the left (or right) of the + image are filled with copies of the leftmost (or rightmost) visible + row; and the four invisible corners are filled with copies of the + corresponding visible corner pixels. The use of these prediction + buffers (and suggested sizes for the halo) will be elaborated on in + the discussion of motion vectors, interframe prediction, and + sub-pixel interpolation later in this document. + + As will be seen in the description of the frame header, the image + dimensions are specified (and can change) with every key frame. + These buffers (and any other data structures whose size depends on + the size of the image) should be allocated (or re-allocated) + immediately after the dimensions are decoded. + + Leaving most of the details for later elaboration, the following is + an outline of the decoding process. + + First, the frame header (the beginning of the first data partition) + is decoded. Altering or augmenting the maintained state of the + decoder, this provides the context in which the per-macroblock data + can be interpreted. + + The macroblock data occurs (and must be processed) in raster-scan + order. This data comes in two or more parts. The first (prediction + or mode) part comes in the remainder of the first data partition. + The other parts comprise the data partition(s) for the DCT/WHT + coefficients of the residue signal. For each macroblock, the + prediction data must be processed before the residue. + + Each macroblock is predicted using one (and only one) of four + possible frames. All macroblocks in a key frame, and all intra-coded + macroblocks in an interframe, are predicted using the already-decoded + macroblocks in the current frame. Macroblocks in an interframe may + also be predicted using the previous frame, the golden frame, or the + altref frame. Such macroblocks are said to be inter-coded. + + + + + + + +Bankoski, et al. Informational [Page 10] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + The purpose of prediction is to use already-constructed image data to + approximate the portion of the original image being reconstructed. + The effect of any of the prediction modes is then to write a + macroblock-sized prediction buffer containing this approximation. + + Regardless of the prediction method, the residue DCT signal is + decoded, dequantized, reverse-transformed, and added to the + prediction buffer to produce the (almost final) reconstruction value + of the macroblock, which is stored in the correct position of the + current frame buffer. + + The residue signal consists of 24 (sixteen Y, four U, and four V) 4x4 + quantized and losslessly compressed DCT transforms approximating the + difference between the original macroblock in the uncompressed source + and the prediction buffer. For most prediction modes, the 0th + coefficients of the sixteen Y subblocks are expressed via a 25th WHT + of the second-order virtual Y2 subblock discussed above. + + Intra-prediction exploits the spatial coherence of frames. The 16x16 + luma (Y) and 8x8 chroma (UV) components are predicted independently + of each other using one of four simple means of pixel propagation, + starting from the already-reconstructed (16-pixel-long luma, 8-pixel- + long chroma) row above, and column to the left of, the current + macroblock. The four methods are: + + 1. Copying the row from above throughout the prediction buffer. + + 2. Copying the column from the left throughout the prediction + buffer. + + 3. Copying the average value of the row and column throughout the + prediction buffer. + + 4. Extrapolation from the row and column using the (fixed) second + difference (horizontal and vertical) from the upper left corner. + + Additionally, the sixteen Y subblocks may be predicted independently + of each other using one of ten different modes, four of which are 4x4 + analogs of those described above, augmented with six "diagonal" + prediction methods. There are two types of predictions, one intra + and one prediction (among all the modes), for which the residue + signal does not use the Y2 block to encode the DC portion of the + sixteen 4x4 Y subblock DCTs. This "independent Y subblock" mode has + no effect on the 8x8 chroma prediction. + + + + + + + +Bankoski, et al. Informational [Page 11] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + Inter-prediction exploits the temporal coherence between nearby + frames. Except for the choice of the prediction frame itself, there + is no difference between inter-prediction based on the previous frame + and that based on the golden frame or altref frame. + + Inter-prediction is conceptually very simple. While, for reasons of + efficiency, there are several methods of encoding the relationship + between the current macroblock and corresponding sections of the + prediction frame, ultimately each of the sixteen Y subblocks is + related to a 4x4 subblock of the prediction frame, whose position in + that frame differs from the current subblock position by a (usually + small) displacement. These two-dimensional displacements are called + motion vectors. + + The motion vectors used by VP8 have quarter-pixel precision. + Prediction of a subblock using a motion vector that happens to have + integer (whole number) components is very easy: The 4x4 block of + pixels from the displaced block in the previous, golden, or altref + frame is simply copied into the correct position of the current + macroblock's prediction buffer. + + Fractional displacements are conceptually and implementationally more + complex. They require the inference (or synthesis) of sample values + that, strictly speaking, do not exist. This is one of the most basic + problems in signal processing, and readers conversant with that + subject will see that the approach taken by VP8 provides a good + balance of robustness, accuracy, and efficiency. + + Leaving the details for the implementation discussion below, the + pixel interpolation is calculated by applying a kernel filter (using + reasonable-precision integer math) three pixels on either side, both + horizontally and vertically, of the pixel to be synthesized. The + resulting 4x4 block of synthetic pixels is then copied into position + exactly as in the case of integer displacements. + + Each of the eight chroma subblocks is handled similarly. Their + motion vectors are never specified explicitly; instead, the motion + vector for each chroma subblock is calculated by averaging the + vectors of the four Y subblocks that occupy the same area of the + frame. Since chroma pixels have twice the diameter (and four times + the area) of luma pixels, the calculated chroma motion vectors have + 1/8-pixel resolution, but the procedure for copying or generating + pixels for each subblock is essentially identical to that done in the + luma plane. + + + + + + + +Bankoski, et al. Informational [Page 12] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + After all the macroblocks have been generated (predicted and + corrected with the DCT/WHT residue), a filtering step (the loop + filter) is applied to the entire frame. The purpose of the loop + filter is to reduce blocking artifacts at the boundaries between + macroblocks and between subblocks of the macroblocks. The term "loop + filter" is used because this filter is part of the "coding loop"; + that is, it affects the reconstructed frame buffers that are used to + predict ensuing frames. This is distinguished from the + postprocessing filters discussed earlier, which affect only the + viewed video and do not "feed into" subsequent frames. + + Next, if signaled in the data, the current frame may replace the + golden frame prediction buffer and/or the altref frame buffer. + + The halos of the frame buffers are next filled as specified above. + Finally, at least as far as decoding is concerned, the (references + to) the "current" and "last" frame buffers should be exchanged in + preparation for the next frame. + + Various processes may be required (or desired) before viewing the + generated frame. As discussed in the frame dimension information + below, truncation and/or upscaling of the frame may be required. + Some playback systems may require a different frame format (RGB, + YUY2, etc.). Finally, as mentioned in the Introduction, further + postprocessing or filtering of the image prior to viewing may be + desired. Since the primary purpose of this document is a decoding + specification, the postprocessing is not specified in this document. + + While the basic ideas of prediction and correction used by VP8 are + straightforward, many of the details are quite complex. The + management of probabilities is particularly elaborate. Not only do + the various modes of intra-prediction and motion vector specification + have associated probabilities, but they, together with the coding of + DCT coefficients and motion vectors, often base these probabilities + on a variety of contextual information (calculated from what has been + decoded so far), as well as on explicit modification via the frame + header. + + The "top-level" of decoding and frame reconstruction is implemented + in the reference decoder file dixie.c (Section 20.4). + + This concludes our summary of decoding and reconstruction; we + continue by discussing the individual aspects in more depth. + + A reasonable "divide and conquer" approach to implementation of a + decoder is to begin by decoding streams composed exclusively of key + frames. After that works reliably, interframe handling can be added + more easily than if complete functionality were attempted + + + +Bankoski, et al. Informational [Page 13] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + immediately. In accordance with this, we first discuss components + needed to decode key frames (most of which are also used in the + decoding of interframes) and conclude with topics exclusive to + interframes. + +6. Description of Algorithms + + As the intent of this document, together with the reference decoder + source code, is to specify a platform-independent procedure for the + decoding and reconstruction of a VP8 video stream, many (small) + algorithms must be described exactly. + + Due to its near-universality, terseness, ability to easily describe + calculation at specific precisions, and the fact that On2's reference + VP8 decoder is written in C, these algorithm fragments are written + using the C programming language, augmented with a few simple + definitions below. + + The standard (and best) reference for C is [Kernighan]. + + Many code fragments will be presented in this document. Some will be + nearly identical to corresponding sections of the reference decoder; + others will differ. Roughly speaking, there are three reasons for + such differences: + + 1. For reasons of efficiency, the reference decoder version may be + less obvious. + + 2. The reference decoder often uses large data structures to + maintain context that need not be described or used here. + + 3. The authors of this document felt that a different expression of + the same algorithm might facilitate exposition. + + Regardless of the chosen presentation, the calculation effected by + any of the algorithms described here is identical to that effected by + the corresponding portion of the reference decoder. + + All VP8 decoding algorithms use integer math. To facilitate + specification of arithmetic precision, we define the following types. + + ---- Begin code block -------------------------------------- + + typedef signed char int8; /* signed int exactly 8 bits wide */ + typedef unsigned char uint8; /* unsigned "" */ + + typedef short int16; /* signed int exactly 16 bits wide */ + typedef unsigned int16 uint16; /* unsigned "" */ + + + +Bankoski, et al. Informational [Page 14] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /* int32 is a signed integer type at least 32 bits wide */ + + typedef long int32; /* guaranteed to work on all systems */ + typedef int int32; /* will be more efficient on some systems */ + + typedef unsigned int32 uint32; + + /* unsigned integer type, at least 16 bits wide, whose exact size + is most convenient to whatever processor we are using */ + + typedef unsigned int uint; + + /* While pixels themselves are 8-bit unsigned integers, + pixel arithmetic often occurs at 16- or 32-bit precision and + the results need to be "saturated" or clamped to an 8-bit + range. */ + + typedef uint8 Pixel; + + Pixel clamp255(int32 v) { return v < 0? 0 : (v < 255? v : 255);} + + /* As is elaborated in the discussion of the bool_decoder below, + VP8 represents probabilities as unsigned 8-bit numbers. */ + + typedef uint8 Prob; + + ---- End code block ---------------------------------------- + + We occasionally need to discuss mathematical functions involving + honest-to-goodness "infinite precision" real numbers. The DCT is + first described via the cosine function cos; the ratio of the lengths + of the circumference and diameter of a circle is denoted pi; at one + point, we take a (base 1/2) logarithm, denoted log; and pow(x, y) + denotes x raised to the power y. If x = 2 and y is a small + non-negative integer, pow(2, y) may be expressed in C as 1 << y. + + Finally, we sometimes need to divide signed integers by powers of + two; that is, we occasionally right-shift signed numbers. The + behavior of such shifts (i.e., the propagation of the sign bit) is, + perhaps surprisingly, not defined by the C language itself and is + left up to individual compilers. Because of the utility of this + frequently needed operation, it is at least arguable that it should + be defined by the language (to naturally propagate the sign bit) and, + at a minimum, should be correctly implemented by any reasonable + compiler. In the interest of strict portability, we attempt to call + attention to these shifts when they arise. + + + + + +Bankoski, et al. Informational [Page 15] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +7. Boolean Entropy Decoder + + As discussed in the overview above, essentially the entire VP8 data + stream is encoded using a boolean entropy coder. + + An understanding of the bool_decoder is critical to the + implementation of a VP8 decompressor, so we discuss the bool_decoder + in detail. It is easier to comprehend the bool_decoder in + conjunction with the bool_encoder used by the compressor to write the + compressed data partitions. + + The bool_encoder encodes (and the bool_decoder decodes) one bool + (zero-or-one boolean value) at a time. Its purpose is to losslessly + compress a sequence of bools for which the probability of their being + zero or one can be well-estimated (via constant or previously coded + information) at the time they are written, using identical + corresponding probabilities at the time they are read. + + As the reader is probably aware, if a bool is much more likely to be + zero than one (for instance), it can, on average, be faithfully + encoded using much less than one bit per value. The bool_encoder + exploits this. + + In the 1940s, [Shannon] proved that there is a lower bound for the + average datarate of a faithful encoding of a sequence of bools (whose + probability distributions are known and are independent of each + other) and also that there are encoding algorithms that approximate + this lower bound as closely as one wishes. + + If we encode a sequence of bools whose probability of being zero is p + (and whose probability of being 1 is 1-p), the lowest possible + datarate per value is + + plog(p) + (1-p)log(1-p); + + taking the logarithms to the base 1/2 expresses the datarate in bits/ + value. + + We give two simple examples. At one extreme, if p = 1/2, then log(p) + = log(1-p) = 1, and the lowest possible datarate per bool is 1/2 + + 1/2 = 1; that is, we cannot do any better than simply literally + writing out bits. At another extreme, if p is very small, say p = + 1/1024, then log(p)=10, log(1-p) is roughly .0014, and the lowest + possible datarate is approximately 10/1024 + .0014, roughly 1/100 of + a bit per bool. + + + + + + +Bankoski, et al. Informational [Page 16] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + Because most of the bools in the VP8 datastream have zero- + probabilities nowhere near 1/2, the compression provided by the + bool_encoder is critical to the performance of VP8. + + The boolean coder used by VP8 is a variant of an arithmetic coder. + An excellent discussion of arithmetic coding (and other lossless + compression techniques) can be found in [Bell]. + +7.1. Underlying Theory of Coding + + The basic idea used by the boolean coder is to consider the entire + data stream (either of the partitions in our case) as the binary + expansion of a single number x with 0 <= x < 1. The bits (or bytes) + in x are of course written from high to low order, and if b[j] (B[j]) + is the j^(th) bit (byte) in the partition, the value x is simply the + sum (starting with j = 1) of pow(2, -j) * b[j] or pow(256, -j) * + B[j]. + + Before the first bool is coded, all values of x are possible. + + The coding of each bool restricts the possible values of x in + proportion to the probability of what is coded. If p1 is the + probability of the first bool being zero and a zero is coded, the + range of possible values of x is restricted to 0 <= x < p1. If a one + is coded, the range becomes p1 <= x < 1. + + The coding continues by repeating the same idea. At every stage, + there is an interval a <= x < b of possible values of x. If p is the + probability of a zero being coded at this stage and a zero is coded, + the interval becomes a <= x < a + (p(b-a)). If a one is coded, the + possible values of x are restricted to a + (p(b-a)) <= x < b. + + Assuming that only finitely many values are to be coded, after the + encoder has received the last bool, it can write as its output any + value x that lies in the final interval. VP8 simply writes the left + endpoint of the final interval. Consequently, the output it would + make if encoding were to stop at any time either increases or stays + the same as each bool is encoded. + + Decoding parallels encoding. The decoder is presented with the + number x, which has only the initial restriction 0 <= x < 1. To + decode the first bool, the decoder is given the first probability p1. + If x < p1, a zero is decoded; if x >= p1, a one is decoded. In + either case, the new restriction on x -- that is, the interval of + possible values of x -- is remembered. + + + + + + +Bankoski, et al. Informational [Page 17] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + Decoding continues in exactly the same way: If a <= x < b is the + current interval and we are to decode a bool with zero-probability p, + we return a zero if a <= x < a + (p(b-a)) and a one if a + (p(b-a)) + <= x < b. In either case, the new restriction is remembered in + preparation for decoding the next bool. + + The process outlined above uses real numbers of infinite precision to + express the probabilities and ranges. It is true that, if one could + actualize this process and coded a large number of bools whose + supplied probabilities matched their value distributions, the + datarate achieved would approach the theoretical minimum as the + number of bools encoded increased. + + Unfortunately, computers operate at finite precision, and an + approximation to the theoretically perfect process described above is + necessary. Such approximation increases the datarate but, at quite + moderate precision and for a wide variety of data sets, this increase + is negligible. + + The only conceptual limitations are, first, that coder probabilities + must be expressed at finite precision and, second, that the decoder + be able to detect each individual modification to the value interval + via examination of a fixed amount of input. As a practical matter, + many of the implementation details stem from the fact that the coder + can function using only a small "window" to incrementally read or + write the arbitrarily precise number x. + +7.2. Practical Algorithm Description + + VP8's boolean coder works with 8-bit probabilities p. The range of + such p is 0 <= p <= 255; the actual probability represented by p is + p/256. Also, the coder is designed so that decoding of a bool + requires no more than an 8-bit comparison, and so that the state of + both the encoder and decoder can be easily represented using a small + number of unsigned 16-bit integers. + + The details are most easily understood if we first describe the + algorithm using bit-at-a-time input and output. Aside from the + ability to maintain a position in this bitstream and write/read bits, + the encoder also needs the ability to add 1 to the bits already + output; after writing n bits, adding 1 to the existing output is the + same thing as adding pow(2, -n) to x. + + + + + + + + + +Bankoski, et al. Informational [Page 18] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + Together with the bit position, the encoder must maintain two + unsigned 8-bit numbers, which we call "bottom" and "range". Writing + w for the n bits already written and S = pow(2, - n - 8) for the + scale of the current bit position one byte out, we have the following + constraint on all future values v of w (including the final value + v = x): + + w + ( S * bottom ) <= v < w + ( S * ( bottom + range ) ) + + Thus, appending bottom to the already-written bits w gives the left + endpoint of the interval of possible values, appending bottom + range + gives the right endpoint, and range itself (scaled to the current + output position) is the length of the interval. + + So that our probabilistic encodings are reasonably accurate, we do + not let range vary by more than a factor of two: It stays within the + bounds 128 <= range <= 255. + + The process for encoding a boolean value val whose probability of + being zero is prob / 256 -- and whose probability of being one is + ( 256 - prob ) / 256 -- with 1 <= prob <= 255 is as follows. + + Using an unsigned 16-bit multiply followed by an unsigned right + shift, we calculate an unsigned 8-bit split value: + + split = 1 + (((range - 1) * probability)]] >> 8) + + split is approximately ( prob / 256 ) * range and lies within the + bounds 1 <= split <= range - 1. These bounds ensure the correctness + of the decoding procedure described below. + + If the incoming boolean val to be encoded is false, we leave the left + interval endpoint bottom alone and reduce range, replacing it by + split. If the incoming val is true, we move up the left endpoint to + bottom + split, propagating any carry to the already-written value w + (this is where we need the ability to add 1 to w), and reduce range + to range - split. + + Regardless of the value encoded, range has been reduced and now has + the bounds 1 <= range <= 254. If range < 128, the encoder doubles it + and shifts the high-order bit out of bottom to the output as it also + doubles bottom, repeating this process one bit at a time until 128 <= + range <= 255. Once this is completed, the encoder is ready to accept + another bool, maintaining the constraints described above. + + After encoding the last bool, the partition may be completed by + appending bottom to the bitstream. + + + + +Bankoski, et al. Informational [Page 19] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + The decoder mimics the state of the encoder. It maintains, together + with an input bit position, two unsigned 8-bit numbers, a range + identical to that maintained by the encoder and a value. Decoding + one bool at a time, the decoder (in effect) tracks the same left + interval endpoint as does the encoder and subtracts it from the + remaining input. Appending the unread portion of the bitstream to + the 8-bit value gives the difference between the actual value encoded + and the known left endpoint. + + The decoder is initialized by setting range = 255 and reading the + first 16 input bits into value. The decoder maintains range and + calculates split in exactly the same way as does the encoder. + + To decode a bool, it compares value to split; if value < split, the + bool is zero, and range is replaced with split. If value >= split, + the bool is one, range is replaced with range - split, and value is + replaced with value - split. + + Again, range is doubled one bit at a time until it is at least 128. + The value is doubled in parallel, shifting a new input bit into the + bottom each time. + + Writing Value for value together with the unread input bits and Range + for range extended indefinitely on the right by zeros, the condition + Value < Range is maintained at all times by the decoder. In + particular, the bits shifted out of value as it is doubled are always + zero. + +7.3. Actual Implementation + + The C code below gives complete implementations of the encoder and + decoder described above. While they are logically identical to the + "bit-at-a-time" versions, they internally buffer a couple of extra + bytes of the bitstream. This allows I/O to be done (more + practically) a byte at a time and drastically reduces the number of + carries the encoder has to propagate into the already-written data. + + Another (logically equivalent) implementation may be found in the + reference decoder file bool_decoder.h (Section 20.2). + + + + + + + + + + + + +Bankoski, et al. Informational [Page 20] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + ---- Begin code block -------------------------------------- + + /* Encoder first */ + + typedef struct { + uint8 *output; /* ptr to next byte to be written */ + uint32 range; /* 128 <= range <= 255 */ + uint32 bottom; /* minimum value of remaining output */ + int bit_count; /* # of shifts before an output byte + is available */ + } bool_encoder; + + /* Must set initial state of encoder before writing any bools. */ + + void init_bool_encoder(bool_encoder *e, uint8 *start_partition) + { + e->output = start_partition; + e->range = 255; + e->bottom = 0; + e->bit_count = 24; + } + + /* Encoding very rarely produces a carry that must be propagated + to the already-written output. The arithmetic guarantees that + the propagation will never go beyond the beginning of the + output. Put another way, the encoded value x is always less + than one. */ + + void add_one_to_output(uint8 *q) + { + while (*--q == 255) + *q = 0; + ++*q; + } + + /* Main function writes a bool_value whose probability of being + zero is (expected to be) prob/256. */ + + void write_bool(bool_encoder *e, Prob prob, int bool_value) + { + /* split is approximately (range * prob) / 256 and, + crucially, is strictly bigger than zero and strictly + smaller than range */ + + uint32 split = 1 + (((e->range - 1) * prob) >> 8); + + + + + + +Bankoski, et al. Informational [Page 21] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + if (bool_value) { + e->bottom += split; /* move up bottom of interval */ + e->range -= split; /* with corresponding decrease in range */ + } else + e->range = split; /* decrease range, leaving bottom alone */ + + while (e->range < 128) + { + e->range <<= 1; + + if (e->bottom & (1 << 31)) /* detect carry */ + add_one_to_output(e->output); + + e->bottom <<= 1; /* before shifting bottom */ + + if (!--e->bit_count) { /* write out high byte of bottom ... */ + + *e->output++ = (uint8) (e->bottom >> 24); + + e->bottom &= (1 << 24) - 1; /* ... keeping low 3 bytes */ + + e->bit_count = 8; /* 8 shifts until next output */ + } + } + } + + /* Call this function (exactly once) after encoding the last + bool value for the partition being written */ + + void flush_bool_encoder(bool_encoder *e) + { + int c = e->bit_count; + uint32 v = e->bottom; + + if (v & (1 << (32 - c))) /* propagate (unlikely) carry */ + add_one_to_output(e->output); + v <<= c & 7; /* before shifting remaining output */ + c >>= 3; /* to top of internal buffer */ + while (--c >= 0) + v <<= 8; + c = 4; + while (--c >= 0) { /* write remaining data, possibly padded */ + *e->output++ = (uint8) (v >> 24); + v <<= 8; + } + } + + + + + +Bankoski, et al. Informational [Page 22] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /* Decoder state exactly parallels that of the encoder. + "value", together with the remaining input, equals the + complete encoded number x less the left endpoint of the + current coding interval. */ + + typedef struct { + uint8 *input; /* pointer to next compressed data byte */ + uint32 range; /* always identical to encoder's range */ + uint32 value; /* contains at least 8 significant bits */ + int bit_count; /* # of bits shifted out of + value, at most 7 */ + } bool_decoder; + + /* Call this function before reading any bools from the + partition. */ + + void init_bool_decoder(bool_decoder *d, uint8 *start_partition) + { + { + int i = 0; + d->value = 0; /* value = first 2 input bytes */ + while (++i <= 2) + + d->value = (d->value << 8) | *start_partition++; + } + + d->input = start_partition; /* ptr to next byte to be read */ + d->range = 255; /* initial range is full */ + d->bit_count = 0; /* have not yet shifted out any bits */ + } + + /* Main function reads a bool encoded at probability prob/256, + which of course must agree with the probability used when the + bool was written. */ + + int read_bool(bool_decoder *d, Prob prob) + { + /* range and split are identical to the corresponding values + used by the encoder when this bool was written */ + + uint32 split = 1 + (((d->range - 1) * prob) >> 8); + uint32 SPLIT = split << 8; + int retval; /* will be 0 or 1 */ + + + + + + + + +Bankoski, et al. Informational [Page 23] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + if (d->value >= SPLIT) { /* encoded a one */ + retval = 1; + d->range -= split; /* reduce range */ + d->value -= SPLIT; /* subtract off left endpoint of interval */ + } else { /* encoded a zero */ + retval = 0; + d->range = split; /* reduce range, no change in left endpoint */ + } + + while (d->range < 128) { /* shift out irrelevant value bits */ + d->value <<= 1; + d->range <<= 1; + if (++d->bit_count == 8) { /* shift in new bits 8 at a time */ + d->bit_count = 0; + d->value |= *d->input++; + } + } + return retval; + } + + /* Convenience function reads a "literal", that is, a "num_bits"- + wide unsigned value whose bits come high- to low-order, with + each bit encoded at probability 128 (i.e., 1/2). */ + + uint32 read_literal(bool_decoder *d, int num_bits) + { + uint32 v = 0; + + while (num_bits--) + v = (v << 1) + read_bool(d, 128); + return v; + } + + /* Variant reads a signed number */ + + int32 read_signed_literal(bool_decoder *d, int num_bits) + { + int32 v = 0; + if (!num_bits) + return 0; + if (read_bool(d, 128)) + v = -1; + while (--num_bits) + v = (v << 1) + read_bool(d, 128); + return v; + } + + ---- End code block ---------------------------------------- + + + +Bankoski, et al. Informational [Page 24] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +8. Compressed Data Components + + At the lowest level, VP8's compressed data is simply a sequence of + probabilistically encoded bools. Most of this data is composed of + (slightly) larger semantic units fashioned from bools, which we + describe here. + + We sometimes use these descriptions in C expressions within data + format specifications. In this context, they refer to the return + value of a call to an appropriate bool_decoder d, reading (as always) + from its current reference point. + + +--------------+-------+--------------------------------------------+ + | Call | Alt. | Return | + +--------------+-------+--------------------------------------------+ + | Bool(p) | B(p) | Bool with probability p/256 of being 0. | + | | | Return value of read_bool(d, p). | + | | | | + | Flag | F | A one-bit flag (same thing as a B(128) or | + | | | an L(1)). Abbreviated F. Return value of | + | | | read_bool(d, 128). | + | | | | + | Lit(n) | L(n) | Unsigned n-bit number encoded as n flags | + | | | (a "literal"). Abbreviated L(n). The | + | | | bits are read from high to low order. | + | | | Return value of read_literal(d, n). | + | | | | + | SignedLit(n) | | Signed n-bit number encoded similarly to | + | | | an L(n). Return value of | + | | | read_signed_literal(d, n). These are | + | | | rare. | + | | | | + | P(8) | | An 8-bit probability. No different from | + | | | an L(8), but we sometimes use this | + | | | notation to emphasize that a probability | + | | | is being coded. | + | | | | + | P(7) | | A 7-bit specification of an 8-bit | + | | | probability. Coded as an L(7) number x; | + | | | the resulting 8-bit probability is x ? x | + | | | << 1 : 1. | + | | | | + | F? X | | A flag that, if true, is followed by a | + | | | piece of data X. | + | | | | + + + + + + +Bankoski, et al. Informational [Page 25] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + | F? X:Y | | A flag that, if true, is followed by X | + | | | and, if false, is followed by Y. Also | + | | | used to express a value where Y is an | + | | | implicit default (not encoded in the data | + | | | stream), as in F? P(8):255, which | + | | | expresses an optional probability: If the | + | | | flag is true, the probability is specified | + | | | as an 8-bit literal, while if the flag is | + | | | false, the probability defaults to 255. | + | | | | + | B(p)? X | B(p)? | Variants of the above using a boolean | + | | X:Y | indicator whose probability is not | + | | | necessarily 128. | + | | | | + | T | | Tree-encoded value from small alphabet. | + +--------------+-------+--------------------------------------------+ + + The last type requires elaboration. We often wish to encode + something whose value is restricted to a small number of + possibilities (the alphabet). + + This is done by representing the alphabet as the leaves of a small + binary tree. The (non-leaf) nodes of the tree have associated + probabilities p and correspond to calls to read_bool(d, p). We think + of a zero as choosing the left branch below the node and a one as + choosing the right branch. + + Thus, every value (leaf) whose tree depth is x is decoded after + exactly x calls to read_bool. + + A tree representing an encoding of an alphabet of n possible values + always contains n-1 non-leaf nodes, regardless of its shape (this is + easily seen by induction on n). + + There are many ways that a given alphabet can be so represented. The + choice of tree has little impact on datarate but does affect decoder + performance. The trees used by VP8 are chosen to (on average) + minimize the number of calls to read_bool. This amounts to shaping + the tree so that values that are more probable have smaller tree + depth than do values that are less probable. + + Readers familiar with Huffman coding will notice that, given an + alphabet together with probabilities for each value, the associated + Huffman tree minimizes the expected number of calls to read_bool. + + + + + + + +Bankoski, et al. Informational [Page 26] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + Such readers will also realize that the coding method described here + never results in higher datarates than does the Huffman method and, + indeed, often results in much lower datarates. Huffman coding is, in + fact, nothing more than a special case of this method in which each + node probability is fixed at 128 (i.e., 1/2). + +8.1. Tree Coding Implementation + + We give a suggested implementation of a tree data structure followed + by a couple of actual examples of its usage by VP8. + + It is most convenient to represent the values using small positive + integers, typically an enum counting up from zero. The largest + alphabet (used to code DCT coefficients, described in Section 13) + that is tree-coded by VP8 has only 12 values. The tree for this + alphabet adds 11 interior nodes and so has a total of 23 positions. + Thus, an 8-bit number easily accommodates both a tree position and a + return value. + + A tree may then be compactly represented as an array of (pairs of) + 8-bit integers. Each (even) array index corresponds to an interior + node of the tree; the 0th index of course corresponds to the root of + the tree. The array entries come in pairs corresponding to the left + (0) and right (1) branches of the subtree below the interior node. + We use the convention that a positive (even) branch entry is the + index of a deeper interior node, while a nonpositive entry v + corresponds to a leaf whose value is -v. + + The node probabilities associated to a tree-coded value are stored in + an array whose indices are half the indices of the corresponding tree + positions. The length of the probability array is one less than the + size of the alphabet. + + Here is C code implementing the foregoing. The advantages of our + data structure should be noted. Aside from the smallness of the + structure itself, the tree-directed reading algorithm is essentially + a single line of code. + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 27] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + ---- Begin code block -------------------------------------- + + /* A tree specification is simply an array of 8-bit integers. */ + + typedef int8 tree_index; + typedef const tree_index Tree[]; + + /* Read and return a tree-coded value at the current decoder + position. */ + + int treed_read( + bool_decoder * const d, /* bool_decoder always returns a 0 or 1 */ + Tree t, /* tree specification */ + const Prob p[] /* corresponding interior node probabilities */ + ) { + register tree_index i = 0; /* begin at root */ + + /* Descend tree until leaf is reached */ + + while ((i = t[ i + read_bool(d, p[i>>1])]) > 0) {} + + return -i; /* return value is negation of nonpositive index */ + } + + ---- End code block ---------------------------------------- + + Tree-based decoding is implemented in the reference decoder file + bool_decoder.h (Section 20.2). + +8.2. Tree Coding Example + + As a multi-part example, without getting too far into the semantics + of macroblock decoding (which is of course taken up below), we look + at the "mode" coding for intra-predicted macroblocks. + + It so happens that, because of a difference in statistics, the Y (or + luma) mode encoding uses two different trees: one for key frames and + another for interframes. This is the only instance in VP8 of the + same dataset being coded by different trees under different + circumstances. The UV (or chroma) modes are a proper subset of the Y + modes and, as such, have their own decoding tree. + + + + + + + + + + +Bankoski, et al. Informational [Page 28] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + ---- Begin code block -------------------------------------- + + typedef enum + { + DC_PRED, /* predict DC using row above and column to the left */ + V_PRED, /* predict rows using row above */ + H_PRED, /* predict columns using column to the left */ + TM_PRED, /* propagate second differences a la "True Motion" */ + + B_PRED, /* each Y subblock is independently predicted */ + + num_uv_modes = B_PRED, /* first four modes apply to chroma */ + num_ymodes /* all modes apply to luma */ + } + intra_mbmode; + + /* The aforementioned trees together with the implied codings as + comments. + Actual (i.e., positive) indices are always even. + Value (i.e., nonpositive) indices are arbitrary. */ + + const tree_index ymode_tree [2 * (num_ymodes - 1)] = + { + -DC_PRED, 2, /* root: DC_PRED = "0", "1" subtree */ + 4, 6, /* "1" subtree has 2 descendant subtrees */ + -V_PRED, -H_PRED, /* "10" subtree: V_PRED = "100", + H_PRED = "101" */ + -TM_PRED, -B_PRED /* "11" subtree: TM_PRED = "110", + B_PRED = "111" */ + }; + + const tree_index kf_ymode_tree [2 * (num_ymodes - 1)] = + { + -B_PRED, 2, /* root: B_PRED = "0", "1" subtree */ + 4, 6, /* "1" subtree has 2 descendant subtrees */ + -DC_PRED, -V_PRED, /* "10" subtree: DC_PRED = "100", + V_PRED = "101" */ + -H_PRED, -TM_PRED /* "11" subtree: H_PRED = "110", + TM_PRED = "111" */ + }; + + + + + + + + + + + +Bankoski, et al. Informational [Page 29] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + const tree_index uv_mode_tree [2 * (num_uv_modes - 1)] = + { + -DC_PRED, 2, /* root: DC_PRED = "0", "1" subtree */ + -V_PRED, 4, /* "1" subtree: V_PRED = "10", + "11" subtree */ + -H_PRED, -TM_PRED /* "11" subtree: H_PRED = "110", + TM_PRED = "111" */ + }; + + /* Given a bool_decoder d, a Y mode might be decoded as follows. */ + + const Prob pretend_its_huffman [num_ymodes - 1] = + { 128, 128, 128, 128}; + + Ymode = (intra_mbmode) treed_read(d, ymode_tree, + pretend_its_huffman); + + ---- End code block ---------------------------------------- + + Since it greatly facilitates re-use of reference code, and since + there is no real reason to do otherwise, it is strongly suggested + that any decoder implementation use exactly the same enumeration + values and probability table layouts as those described in this + document (and in the reference code) for all tree-coded data in VP8. + +9. Frame Header + + The uncompressed data chunk at the start of each frame and at the + first part of the first data partition contains information + pertaining to the frame as a whole. We list the fields in the order + of occurrence. Most of the header decoding occurs in the reference + decoder file dixie.c (Section 20.4). + +9.1. Uncompressed Data Chunk + + The uncompressed data chunk comprises a common (for key frames and + interframes) 3-byte frame tag that contains four fields, as follows: + + 1. A 1-bit frame type (0 for key frames, 1 for interframes). + + 2. A 3-bit version number (0 - 3 are defined as four different + profiles with different decoding complexity; other values may be + defined for future variants of the VP8 data format). + + + + + + + + +Bankoski, et al. Informational [Page 30] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + 3. A 1-bit show_frame flag (0 when current frame is not for display, + 1 when current frame is for display). + + 4. A 19-bit field containing the size of the first data partition in + bytes. + + The version number setting enables or disables certain features in + the bitstream, as follows: + + +---------+-------------------------+-------------+ + | Version | Reconstruction Filter | Loop Filter | + +---------+-------------------------+-------------+ + | 0 | Bicubic | Normal | + | | | | + | 1 | Bilinear | Simple | + | | | | + | 2 | Bilinear | None | + | | | | + | 3 | None | None | + | | | | + | Other | Reserved for future use | | + +---------+-------------------------+-------------+ + + The reference software also adjusts the loop filter based on version + number, as per the table above. Version number 1 implies a "simple" + loop filter, and version numbers 2 and 3 imply no loop filter. + However, the "simple" filter setting in this context has no effect + whatsoever on the decoding process, and the "no loop filter" setting + only forces the reference encoder to set filter level equal to 0. + Neither affect the decoding process. In decoding, the only loop + filter settings that matter are those in the frame header. + + For key frames, the frame tag is followed by a further 7 bytes of + uncompressed data, as follows: + + ---- Begin code block -------------------------------------- + + Start code byte 0 0x9d + Start code byte 1 0x01 + Start code byte 2 0x2a + + 16 bits : (2 bits Horizontal Scale << 14) | Width (14 bits) + 16 bits : (2 bits Vertical Scale << 14) | Height (14 bits) + + ---- End code block ---------------------------------------- + + + + + + +Bankoski, et al. Informational [Page 31] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + The following source code segment illustrates validation of the start + code and reading the width, height, and scale factors for a key + frame. + + ---- Begin code block -------------------------------------- + + unsigned char *c = pbi->source+3; + + // vet via sync code + if (c[0]!=0x9d||c[1]!=0x01||c[2]!=0x2a) + return -1; + + ---- End code block ---------------------------------------- + + Where pbi->source points to the beginning of the frame. + + The following code reads the image dimension from the bitstream: + + ---- Begin code block -------------------------------------- + + pc->Width = swap2(*(unsigned short*)(c+3))&0x3fff; + pc->horiz_scale = swap2(*(unsigned short*)(c+3))>>14; + pc->Height = swap2(*(unsigned short*)(c+5))&0x3fff; + pc->vert_scale = swap2(*(unsigned short*)(c+5))>>14; + + ---- End code block ---------------------------------------- + + Where the swap2 macro takes care of the endian on a different + platform: + + ---- Begin code block -------------------------------------- + + #if defined(__ppc__) || defined(__ppc64__) + # define swap2(d) \ + ((d&0x000000ff)<<8) | \ + ((d&0x0000ff00)>>8) + #else + # define swap2(d) d + #endif + + ---- End code block ---------------------------------------- + + While each frame is encoded as a raster scan of 16x16 macroblocks, + the frame dimensions are not necessarily evenly divisible by 16. In + this case, write ew = 16 - (width & 15) and eh = 16 - (height & 15) + for the excess width and height, respectively. Although they are + + + + + +Bankoski, et al. Informational [Page 32] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + encoded, the last ew columns and eh rows are not actually part of the + image and should be discarded before final output. However, these + "excess pixels" should be maintained in the internal reconstruction + buffer used to predict ensuing frames. + + The scaling specifications for each dimension are encoded as follows. + + +-------+--------------------------------------+ + | Value | Scaling | + +-------+--------------------------------------+ + | 0 | No upscaling (the most common case). | + | | | + | 1 | Upscale by 5/4. | + | | | + | 2 | Upscale by 5/3. | + | | | + | 3 | Upscale by 2. | + +-------+--------------------------------------+ + + Upscaling does not affect the reconstruction buffer, which should be + maintained at the encoded resolution. Any reasonable method of + upsampling (including any that may be supported by video hardware in + the playback environment) may be used. Since scaling has no effect + on decoding, we do not discuss it any further. + + As discussed in Section 5, allocation (or re-allocation) of data + structures (such as the reconstruction buffer) whose size depends on + dimension will be triggered here. + +9.2. Color Space and Pixel Type (Key Frames Only) + + +-------+------------------------------------------+ + | Field | Value | + +-------+------------------------------------------+ + | L(1) | 1-bit color space type specification | + | | | + | L(1) | 1-bit pixel value clamping specification | + +-------+------------------------------------------+ + + The color space type bit is encoded as follows: + + o 0 - YUV color space similar to the YCrCb color space defined in + [ITU-R_BT.601] + + o 1 - Reserved for future use + + + + + + +Bankoski, et al. Informational [Page 33] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + The pixel value clamping type bit is encoded as follows: + + o 0 - Decoders are required to clamp the reconstructed pixel values + to between 0 and 255 (inclusive). + + o 1 - Reconstructed pixel values are guaranteed to be between 0 and + 255; no clamping is necessary. + + Information in this subsection does not appear in interframes. + +9.3. Segment-Based Adjustments + + This subsection contains probability and value information for + implementing segment adaptive adjustments to default decoder + behavior. The data in this subsection is used in the decoding of the + ensuing per-segment information and applies to the entire frame. + When segment adaptive adjustments are enabled, each macroblock will + be assigned a segment ID. Macroblocks with the same segment ID + belong to the same segment and have the same adaptive adjustments + over default baseline values for the frame. The adjustments can be + quantizer level or loop filter strength. + + The context for decoding this feature at the macroblock level is + provided by a subsection in the frame header, which contains: + + 1. A segmentation_enabled flag that enables the feature for this + frame if set to 1, and disables it if set to 0. The following + fields occur if the feature is enabled. + + 2. L(1) indicates if the segment map is updated for the current + frame (update_mb_segmentation_map). + + 3. L(1) indicates if the segment feature data items are updated for + the current frame (update_segment_feature_data). + + 4. If Item 3 above (update_segment_feature_data) is 1, the following + fields occur: + + a. L(1), the mode of segment feature data + (segment_feature_mode), can be absolute-value mode (0) or + delta value mode (1). + + + + + + + + + + +Bankoski, et al. Informational [Page 34] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + b. Segment feature data items are decoded segment by segment for + each segment feature. For every data item, a one-bit flag + indicates whether the item is 0, or a non-zero value to be + decoded. If the value is non-zero, then the value is decoded + as a magnitude L(n), followed by a one-bit sign (L(1) -- 0 + for positive and 1 for negative). The length n can be looked + up from a pre-defined length table for all feature data. + + 5. If the L(1) flag as noted in Item 2 above is set to 1, the + probabilities of the decoding tree for the segment map are + decoded from the bitstream. Each probability is decoded with a + one-bit flag indicating whether the probability is the default + value of 255 (flag is set to 0), or an 8-bit value, L(8), from + the bitstream. + + The layout and semantics supporting this feature at the macroblock + level are described in Section 10. + +9.4. Loop Filter Type and Levels + + VP8 supports two types of loop filters having different computational + complexity. The following bits occur in the header to support the + selection of the baseline type, strength, and sharpness behavior of + the loop filter used for the current frame. + + +-------+-------------------+ + | Index | Description | + +-------+-------------------+ + | L(1) | filter_type | + | | | + | L(6) | loop_filter_level | + | | | + | L(3) | sharpness_level | + +-------+-------------------+ + + The meaning of these numbers will be further explained in Section 15. + + VP8 has a feature in the bitstream that enables adjustment of the + loop filter level based on a macroblock's prediction mode and + reference frame. The per-macroblock adjustment is done through delta + values against the default loop filter level for the current frame. + This subsection contains flag and value information for implementing + per-macroblock loop filter level adjustment to default decoder + behavior. The data in this section is used in the decoding of the + ensuing per-macroblock information and applies to the entire frame. + + + + + + +Bankoski, et al. Informational [Page 35] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + L(1) is a one-bit flag indicating if the macroblock loop filter + adjustment is on for the current frame. 0 means that such a feature + is not supported in the current frame, and 1 means this feature is + enabled for the current frame. + + Whether the adjustment is based on a reference frame or encoding + mode, the adjustment of the loop filter level is done via a delta + value against a baseline loop filter value. The delta values are + updated for the current frame if an L(1) bit, + mode_ref_lf_delta_update, takes the value 1. There are two groups of + delta values: One group of delta values is for reference frame-based + adjustments, and the other group is for mode-based adjustments. The + number of delta values in the two groups is MAX_REF_LF_DELTAS and + MAX_MODE_LF_DELTAS, respectively. For every value within the two + groups, there is a one-bit L(1) to indicate if the particular value + is updated. When one is updated (1), it is transmitted as a six-bit- + magnitude L(6) followed by a one-bit sign flag (L(1) -- 0 for + positive and 1 for negative). + +9.5. Token Partition and Partition Data Offsets + + VP8 allows DCT coefficients to be packed into multiple partitions, + besides the first partition with header and per-macroblock prediction + information, so the decoder can perform parallel decoding in an + efficient manner. A two-bit L(2) is used to indicate the number of + coefficient data partitions within a compressed frame. The two bits + are defined in the following table: + + +-------+-------+----------------------+ + | Bit 1 | Bit 0 | Number of Partitions | + +-------+-------+----------------------+ + | 0 | 0 | 1 | + | | | | + | 0 | 1 | 2 | + | | | | + | 1 | 0 | 4 | + | | | | + | 1 | 1 | 8 | + +-------+-------+----------------------+ + + Offsets are embedded in the bitstream to provide the decoder direct + access to token partitions. If the number of data partitions is + greater than 1, the size of each partition (except the last) is + written in 3 bytes (24 bits). The size of the last partition is the + remainder of the data not used by any of the previous partitions. + + + + + + +Bankoski, et al. Informational [Page 36] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + The partitioned data are consecutive in the bitstream, so the size + can also be used to calculate the offset of each partition. The + following pseudocode illustrates how the size/offset is defined by + the three bytes in the bitstream. + + ---- Begin code block -------------------------------------- + + Offset/size = (uint32)(byte0) + ((uint32)(byte1)<<8) + + ((uint32)(byte2)<<16); + + ---- End code block ---------------------------------------- + +9.6. Dequantization Indices + + All residue signals are specified via a quantized 4x4 DCT applied to + the Y, U, V, or Y2 subblocks of a macroblock. As detailed in + Section 14, before inverting the transform, each decoded coefficient + is multiplied by one of six dequantization factors, the choice of + which depends on the plane (Y, chroma = U or V, Y2) and coefficient + position (DC = coefficient 0, AC = coefficients 1-15). The six + values are specified using 7-bit indices into six corresponding fixed + tables (the tables are given in Section 14). + + The first 7-bit index gives the dequantization table index for + Y-plane AC coefficients, called yac_qi. It is always coded and acts + as a baseline for the other 5 quantization indices, each of which is + represented by a delta from this baseline index. Pseudocode for + reading the indices follows: + + ---- Begin code block -------------------------------------- + + yac_qi = L(7); /* Y ac index always specified */ + ydc_delta = F? delta(): 0; /* Y dc delta specified if + flag is true */ + + y2dc_delta = F? delta(): 0; /* Y2 dc delta specified if + flag is true */ + y2ac_delta = F? delta(): 0; /* Y2 ac delta specified if + flag is true */ + + uvdc_delta = F? delta(): 0; /* chroma dc delta specified + if flag is true */ + uvac_delta = F? delta(): 0; /* chroma ac delta specified + if flag is true */ + + ---- End code block ---------------------------------------- + + + + + +Bankoski, et al. Informational [Page 37] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + Where delta() is the process to read 5 bits from the bitstream to + determine a signed delta value: + + +-------+--------------------------------------------------+ + | Index | Description | + +-------+--------------------------------------------------+ + | L(4) | Magnitude of delta | + | | | + | L(1) | Sign of delta, 0 for positive and 1 for negative | + +-------+--------------------------------------------------+ + +9.7. Refresh Golden Frame and Altref Frame + + For key frames, both the golden frame and the altref frame are + refreshed/ replaced by the current reconstructed frame, by default. + For non-key frames, VP8 uses two bits to indicate whether the two + frame buffers are refreshed, using the reconstructed current frame: + + +-------+----------------------------------------------------------+ + | Index | Description | + +-------+----------------------------------------------------------+ + | L(1) | Whether golden frame is refreshed (0 for no, 1 for yes). | + | | | + | L(1) | Whether altref frame is refreshed (0 for no, 1 for yes). | + +-------+----------------------------------------------------------+ + + When the flag for the golden frame is 0, VP8 uses 2 more bits in the + bitstream to indicate whether the buffer (and which buffer) is copied + to the golden frame, or if no buffer is copied: + + +-------+------------------------------------------+ + | Index | Description | + +-------+------------------------------------------+ + | L(2) | Buffer copy flag for golden frame buffer | + +-------+------------------------------------------+ + + Where: + + o 0 means no buffer is copied to the golden frame + + o 1 means last_frame is copied to the golden frame + + o 2 means alt_ref_frame is copied to the golden frame + + Similarly, when the flag for altref is 0, VP8 uses 2 bits in the + bitstream to indicate which buffer is copied to alt_ref_frame. + + + + + +Bankoski, et al. Informational [Page 38] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + +-------+------------------------------------------+ + | Index | Description | + +-------+------------------------------------------+ + | L(2) | Buffer copy flag for altref frame buffer | + +-------+------------------------------------------+ + + Where: + + o 0 means no buffer is copied to the altref frame + + o 1 means last_frame is copied to the altref frame + + o 2 means golden_frame is copied to the altref frame + + Two bits are transmitted for ref_frame_sign_bias for golden_frame and + alt_ref_frame, respectively. + + +-------+---------------------------------+ + | Index | Description | + +-------+---------------------------------+ + | L(1) | Sign bias flag for golden frame | + | | | + | L(1) | Sign bias flag for altref frame | + +-------+---------------------------------+ + + These values are used to control the sign of the motion vectors when + a golden frame or an altref frame is used as the reference frame for + a macroblock. + +9.8. Refresh Last Frame Buffer + + VP8 uses one bit, L(1), to indicate if the last frame reference + buffer is refreshed using the constructed current frame. On a key + frame, this bit is overridden, and the last frame buffer is always + refreshed. + +9.9. DCT Coefficient Probability Update + + This field contains updates to the probability tables used to decode + DCT coefficients. For each of the probabilities in the tables, there + is an L(1) flag indicating if the probability is updated for the + current frame, and if the L(1) flag is set to 1, there follows an + additional 8-bit value representing the new probability value. These + tables are maintained across interframes but are of course replaced + with their defaults at the beginning of every key frame. + + The layout and semantics of this field will be taken up in + Section 13. + + + +Bankoski, et al. Informational [Page 39] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +9.10. Remaining Frame Header Data (Non-Key Frame) + + +-------+-----------------------------------------------------------+ + | Index | Description | + +-------+-----------------------------------------------------------+ + | L(1) | mb_no_skip_coeff. This flag indicates at the frame level | + | | if skipping of macroblocks with no non-zero coefficients | + | | is enabled. If it is set to 0, then prob_skip_false is | + | | not read and mb_skip_coeff is forced to 0 for all | + | | macroblocks (see Sections 11.1 and 12.1). | + | | | + | L(8) | prob_skip_false = probability used for decoding a | + | | macroblock-level flag, which indicates if a macroblock | + | | has any non-zero coefficients. Only read if | + | | mb_no_skip_coeff is 1. | + | | | + | L(8) | prob_intra = probability that a macroblock is "intra" | + | | predicted (that is, predicted from the already-encoded | + | | portions of the current frame), as opposed to "inter" | + | | predicted (that is, predicted from the contents of a | + | | prior frame). | + | | | + | L(8) | prob_last = probability that an inter-predicted | + | | macroblock is predicted from the immediately previous | + | | frame, as opposed to the most recent golden frame or | + | | altref frame. | + | | | + | L(8) | prob_gf = probability that an inter-predicted macroblock | + | | is predicted from the most recent golden frame, as | + | | opposed to the altref frame. | + | | | + | F | If true, followed by four L(8)s updating the | + | | probabilities for the different types of intra-prediction | + | | for the Y plane. These probabilities correspond to the | + | | four interior nodes of the decoding tree for intra-Y | + | | modes in an interframe, that is, the even positions in | + | | the ymode_tree array given above. | + | | | + | F | If true, followed by three L(8)s updating the | + | | probabilities for the different types of intra-prediction | + | | for the chroma planes. These probabilities correspond to | + | | the even positions in the uv_mode_tree array given above. | + | | | + | X | Motion vector probability update. Details are given in | + | | Section 17.2, "Probability Updates". | + +-------+-----------------------------------------------------------+ + + + + + +Bankoski, et al. Informational [Page 40] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + Decoding of this portion of the frame header is handled in the + reference decoder file dixie.c (Section 20.4). + +9.11. Remaining Frame Header Data (Key Frame) + + +-------+-----------------------------------------------------------+ + | Index | Description | + +-------+-----------------------------------------------------------+ + | L(1) | mb_no_skip_coeff. This flag indicates at the frame level | + | | if skipping of macroblocks with no non-zero coefficients | + | | is enabled. If it is set to 0, then prob_skip_false is | + | | not read and mb_skip_coeff is forced to 0 for all | + | | macroblocks (see Sections 11.1 and 12.1). | + | | | + | L(8) | prob_skip_false = Probability used for decoding a | + | | macroblock-level flag, which indicates if a macroblock | + | | has any non-zero coefficients. Only read if | + | | mb_no_skip_coeff is 1. | + +-------+-----------------------------------------------------------+ + + Decoding of this portion of the frame header is handled in the + reference decoder file modemv.c (Section 20.11). + + This completes the layout of the frame header. The remainder of the + first data partition consists of macroblock-level prediction data. + + After the frame header is processed, all probabilities needed to + decode the prediction and residue data are known and will not change + until the next frame. + +10. Segment-Based Feature Adjustments + + Every macroblock may optionally override some of the default + behaviors of the decoder. Specifically, VP8 uses segment-based + adjustments to support changing quantizer level and loop filter level + for a macroblock. When the segment-based adjustment feature is + enabled for a frame, each macroblock within the frame is coded with a + segment_id. This effectively segments all the macroblocks in the + current frame into a number of different segments. Macroblocks + within the same segment behave exactly the same for quantizer and + loop filter level adjustments. + + If both the segmentation_enabled and update_mb_segmentation_map flags + in subsection B of the frame header take a value of 1, the prediction + data for each (intra- or inter-coded) macroblock begins with a + specification of segment_id for the current macroblock. It is + decoded using this simple tree ... + + + + +Bankoski, et al. Informational [Page 41] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + ---- Begin code block -------------------------------------- + + const tree_index mb_segment_tree [2 * (4-1)] = + { + 2, 4, /* root: "0", "1" subtrees */ + -0, -1, /* "00" = 0th value, "01" = 1st value */ + -2, -3 /* "10" = 2nd value, "11" = 3rd value */ + } + + ---- End code block ---------------------------------------- + + ... combined with a 3-entry probability table, + mb_segment_tree_probs[3]. The macroblock's segment_id is used later + in the decoding process to look into the segment_feature_data table + and determine how the quantizer and loop filter levels are adjusted. + + The decoding of segment_id, together with the parsing of + intra-prediction modes (which is taken up next), is implemented in + the reference decoder file modemv.c. + +11. Key Frame Macroblock Prediction Records + + After specifying the features described above, the macroblock + prediction record next specifies the prediction mode used for the + macroblock. + +11.1. mb_skip_coeff + + The single bool flag is decoded using prob_skip_false if and only if + mb_no_skip_coeff is set to 1 (see Sections 9.10 and 9.11). If + mb_no_skip_coeff is set to 0, then this value defaults to 0. + +11.2. Luma Modes + + First comes the luma specification of type intra_mbmode, coded using + the kf_ymode_tree, as described in Section 8 and repeated here for + convenience: + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 42] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + ---- Begin code block -------------------------------------- + + typedef enum + { + DC_PRED, /* predict DC using row above and column to the left */ + V_PRED, /* predict rows using row above */ + H_PRED, /* predict columns using column to the left */ + TM_PRED, /* propagate second differences a la "True Motion" */ + + B_PRED, /* each Y subblock is independently predicted */ + + num_uv_modes = B_PRED, /* first four modes apply to chroma */ + num_ymodes /* all modes apply to luma */ + } + intra_mbmode; + + const tree_index kf_ymode_tree [2 * (num_ymodes - 1)] = + { + -B_PRED, 2, /* root: B_PRED = "0", "1" subtree */ + 4, 6, /* "1" subtree has 2 descendant subtrees */ + -DC_PRED, -V_PRED, /* "10" subtree: DC_PRED = "100", + V_PRED = "101" */ + -H_PRED, -TM_PRED /* "11" subtree: H_PRED = "110", + TM_PRED = "111" */ + }; + + ---- End code block ---------------------------------------- + + For key frames, the Y mode is decoded using a fixed probability array + as follows: + + ---- Begin code block -------------------------------------- + + const Prob kf_ymode_prob [num_ymodes - 1] = { 145, 156, 163, 128}; + Ymode = (intra_mbmode) treed_read(d, kf_ymode_tree, kf_ymode_prob); + + ---- End code block ---------------------------------------- + + d is of course the bool_decoder being used to read the first data + partition. + + If the Ymode is B_PRED, it is followed by a (tree-coded) mode for + each of the 16 Y subblocks. The 10 subblock modes and their coding + tree are as follows: + + + + + + + +Bankoski, et al. Informational [Page 43] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + ---- Begin code block -------------------------------------- + + typedef enum + { + B_DC_PRED, /* predict DC using row above and column + to the left */ + B_TM_PRED, /* propagate second differences a la + "True Motion" */ + + B_VE_PRED, /* predict rows using row above */ + B_HE_PRED, /* predict columns using column to the left */ + + B_LD_PRED, /* southwest (left and down) 45 degree diagonal + prediction */ + B_RD_PRED, /* southeast (right and down) "" */ + + B_VR_PRED, /* SSE (vertical right) diagonal prediction */ + B_VL_PRED, /* SSW (vertical left) "" */ + B_HD_PRED, /* ESE (horizontal down) "" */ + B_HU_PRED, /* ENE (horizontal up) "" */ + + num_intra_bmodes + } + intra_bmode; + + /* Coding tree for the above, with implied codings as comments */ + + const tree_index bmode_tree [2 * (num_intra_bmodes - 1)] = + { + -B_DC_PRED, 2, /* B_DC_PRED = "0" */ + -B_TM_PRED, 4, /* B_TM_PRED = "10" */ + -B_VE_PRED, 6, /* B_VE_PRED = "110" */ + 8, 12, + -B_HE_PRED, 10, /* B_HE_PRED = "11100" */ + -B_RD_PRED, -B_VR_PRED, /* B_RD_PRED = "111010", + B_VR_PRED = "111011" */ + -B_LD_PRED, 14, /* B_LD_PRED = "111110" */ + -B_VL_PRED, 16, /* B_VL_PRED = "1111110" */ + -B_HD_PRED, -B_HU_PRED /* HD = "11111110", + HU = "11111111" */ + }; + + ---- End code block ---------------------------------------- + + The first four modes are smaller versions of the similarly named + 16x16 modes above, albeit with slightly different numbering. The + last six "diagonal" modes are unique to luma subblocks. + + + + +Bankoski, et al. Informational [Page 44] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +11.3. Subblock Mode Contexts + + The coding of subblock modes in key frames uses the modes already + coded for the subblocks to the left of and above the subblock to + select a probability array for decoding the current subblock mode. + This is our first instance of contextual prediction, and there are + several caveats associated with it: + + 1. The adjacency relationships between subblocks are based on the + normal default raster placement of the subblocks. + + 2. The adjacent subblocks need not lie in the current macroblock. + The subblocks to the left of the left-edge subblocks 0, 4, 8, and + 12 are the right-edge subblocks 3, 7, 11, and 15, respectively, + of the (already coded) macroblock immediately to the left. + Similarly, the subblocks above the top-edge subblocks 0, 1, 2, + and 3 are the bottom-edge subblocks 12, 13, 14, and 15 of the + already-coded macroblock immediately above us. + + 3. For macroblocks on the top row or left edge of the image, some of + the predictors will be non-existent. Such predictors are taken + to have had the value B_DC_PRED, which, perhaps conveniently, + takes the value 0 in the enumeration above. A simple management + scheme for these contexts might maintain a row of above + predictors and four left predictors. Before decoding the frame, + the entire row is initialized to B_DC_PRED; before decoding each + row of macroblocks, the four left predictors are also set to + B_DC_PRED. After decoding a macroblock, the bottom four subblock + modes are copied into the row predictor (at the current position, + which then advances to be above the next macroblock), and the + right four subblock modes are copied into the left predictor. + + 4. Many macroblocks will of course be coded using a 16x16 luma + prediction mode. For the purpose of predicting ensuing subblock + modes (only), such macroblocks derive a subblock mode, constant + throughout the macroblock, from the 16x16 luma mode as follows: + DC_PRED uses B_DC_PRED, V_PRED uses B_VE_PRED, H_PRED uses + B_HE_PRED, and TM_PRED uses B_TM_PRED. + + 5. Although we discuss interframe modes in Section 16, we remark + here that, while interframes do use all the intra-coding modes + described here and below, the subblock modes in an interframe are + coded using a single constant probability array that does not + depend on any context. + + The dependence of subblock mode probability on the nearby subblock + mode context is most easily handled using a three-dimensional + constant array: + + + +Bankoski, et al. Informational [Page 45] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + ---- Begin code block -------------------------------------- + + const Prob kf_bmode_prob [num_intra_bmodes] [num_intra_bmodes] + [num_intra_bmodes-1]; + + ---- End code block ---------------------------------------- + + The outer two dimensions of this array are indexed by the already- + coded subblock modes above and to the left of the current block, + respectively. The inner dimension is a typical tree probability list + whose indices correspond to the even indices of the bmode_tree above. + The mode for the j^(th) luma subblock is then + + ---- Begin code block -------------------------------------- + + Bmode = (intra_bmode) treed_read(d, bmode_tree, kf_bmode_prob + [A] [L]); + + ---- End code block ---------------------------------------- + + Where the 4x4 Y subblock index j varies from 0 to 15 in raster order, + and A and L are the modes used above and to the left of the j^(th) + subblock. + + The contents of the kf_bmode_prob array are given at the end of this + section. + +11.4. Chroma Modes + + After the Y mode (and optional subblock mode) specification comes the + chroma mode. The chroma modes are a subset of the Y modes and are + coded using the uv_mode_tree, as described in Section 8 and repeated + here for convenience: + + ---- Begin code block -------------------------------------- + + const tree_index uv_mode_tree [2 * (num_uv_modes - 1)] = + { + -DC_PRED, 2, /* root: DC_PRED = "0", "1" subtree */ + -V_PRED, 4, /* "1" subtree: V_PRED = "10", + "11" subtree */ + -H_PRED, -TM_PRED /* "11" subtree: H_PRED = "110", + TM_PRED = "111" */ + }; + + ---- End code block ---------------------------------------- + + + + + +Bankoski, et al. Informational [Page 46] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + As for the Y modes (in a key frame), the chroma modes are coded using + a fixed, contextless probability table: + + ---- Begin code block -------------------------------------- + + const Prob kf_uv_mode_prob [num_uv_modes - 1] = { 142, 114, 183}; + uv_mode = (intra_mbmode) treed_read(d, uv_mode_tree, + kf_uv_mode_prob); + + ---- End code block ---------------------------------------- + + This completes the description of macroblock prediction coding for + key frames. As will be discussed in Section 16, the coding of intra + modes within interframes is similar, but not identical, to that + described here (and in the reference code) for prediction modes and, + indeed, for all tree-coded data in VP8. + +11.5. Subblock Mode Probability Table + + Finally, here is the fixed probability table used to decode subblock + modes in key frames. + + ---- Begin code block -------------------------------------- + + const Prob kf_bmode_prob [num_intra_bmodes] [num_intra_bmodes] + [num_intra_bmodes-1] = + { + { + { 231, 120, 48, 89, 115, 113, 120, 152, 112}, + { 152, 179, 64, 126, 170, 118, 46, 70, 95}, + { 175, 69, 143, 80, 85, 82, 72, 155, 103}, + { 56, 58, 10, 171, 218, 189, 17, 13, 152}, + { 144, 71, 10, 38, 171, 213, 144, 34, 26}, + { 114, 26, 17, 163, 44, 195, 21, 10, 173}, + { 121, 24, 80, 195, 26, 62, 44, 64, 85}, + { 170, 46, 55, 19, 136, 160, 33, 206, 71}, + { 63, 20, 8, 114, 114, 208, 12, 9, 226}, + { 81, 40, 11, 96, 182, 84, 29, 16, 36} + }, + + + + + + + + + + + + +Bankoski, et al. Informational [Page 47] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + { + { 134, 183, 89, 137, 98, 101, 106, 165, 148}, + { 72, 187, 100, 130, 157, 111, 32, 75, 80}, + { 66, 102, 167, 99, 74, 62, 40, 234, 128}, + { 41, 53, 9, 178, 241, 141, 26, 8, 107}, + { 104, 79, 12, 27, 217, 255, 87, 17, 7}, + { 74, 43, 26, 146, 73, 166, 49, 23, 157}, + { 65, 38, 105, 160, 51, 52, 31, 115, 128}, + { 87, 68, 71, 44, 114, 51, 15, 186, 23}, + { 47, 41, 14, 110, 182, 183, 21, 17, 194}, + { 66, 45, 25, 102, 197, 189, 23, 18, 22} + }, + { + { 88, 88, 147, 150, 42, 46, 45, 196, 205}, + { 43, 97, 183, 117, 85, 38, 35, 179, 61}, + { 39, 53, 200, 87, 26, 21, 43, 232, 171}, + { 56, 34, 51, 104, 114, 102, 29, 93, 77}, + { 107, 54, 32, 26, 51, 1, 81, 43, 31}, + { 39, 28, 85, 171, 58, 165, 90, 98, 64}, + { 34, 22, 116, 206, 23, 34, 43, 166, 73}, + { 68, 25, 106, 22, 64, 171, 36, 225, 114}, + { 34, 19, 21, 102, 132, 188, 16, 76, 124}, + { 62, 18, 78, 95, 85, 57, 50, 48, 51} + }, + { + { 193, 101, 35, 159, 215, 111, 89, 46, 111}, + { 60, 148, 31, 172, 219, 228, 21, 18, 111}, + { 112, 113, 77, 85, 179, 255, 38, 120, 114}, + { 40, 42, 1, 196, 245, 209, 10, 25, 109}, + { 100, 80, 8, 43, 154, 1, 51, 26, 71}, + { 88, 43, 29, 140, 166, 213, 37, 43, 154}, + { 61, 63, 30, 155, 67, 45, 68, 1, 209}, + { 142, 78, 78, 16, 255, 128, 34, 197, 171}, + { 41, 40, 5, 102, 211, 183, 4, 1, 221}, + { 51, 50, 17, 168, 209, 192, 23, 25, 82} + }, + { + { 125, 98, 42, 88, 104, 85, 117, 175, 82}, + { 95, 84, 53, 89, 128, 100, 113, 101, 45}, + { 75, 79, 123, 47, 51, 128, 81, 171, 1}, + { 57, 17, 5, 71, 102, 57, 53, 41, 49}, + { 115, 21, 2, 10, 102, 255, 166, 23, 6}, + { 38, 33, 13, 121, 57, 73, 26, 1, 85}, + { 41, 10, 67, 138, 77, 110, 90, 47, 114}, + { 101, 29, 16, 10, 85, 128, 101, 196, 26}, + { 57, 18, 10, 102, 102, 213, 34, 20, 43}, + { 117, 20, 15, 36, 163, 128, 68, 1, 26} + }, + + + +Bankoski, et al. Informational [Page 48] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + { + { 138, 31, 36, 171, 27, 166, 38, 44, 229}, + { 67, 87, 58, 169, 82, 115, 26, 59, 179}, + { 63, 59, 90, 180, 59, 166, 93, 73, 154}, + { 40, 40, 21, 116, 143, 209, 34, 39, 175}, + { 57, 46, 22, 24, 128, 1, 54, 17, 37}, + { 47, 15, 16, 183, 34, 223, 49, 45, 183}, + { 46, 17, 33, 183, 6, 98, 15, 32, 183}, + { 65, 32, 73, 115, 28, 128, 23, 128, 205}, + { 40, 3, 9, 115, 51, 192, 18, 6, 223}, + { 87, 37, 9, 115, 59, 77, 64, 21, 47} + }, + { + { 104, 55, 44, 218, 9, 54, 53, 130, 226}, + { 64, 90, 70, 205, 40, 41, 23, 26, 57}, + { 54, 57, 112, 184, 5, 41, 38, 166, 213}, + { 30, 34, 26, 133, 152, 116, 10, 32, 134}, + { 75, 32, 12, 51, 192, 255, 160, 43, 51}, + { 39, 19, 53, 221, 26, 114, 32, 73, 255}, + { 31, 9, 65, 234, 2, 15, 1, 118, 73}, + { 88, 31, 35, 67, 102, 85, 55, 186, 85}, + { 56, 21, 23, 111, 59, 205, 45, 37, 192}, + { 55, 38, 70, 124, 73, 102, 1, 34, 98} + }, + { + { 102, 61, 71, 37, 34, 53, 31, 243, 192}, + { 69, 60, 71, 38, 73, 119, 28, 222, 37}, + { 68, 45, 128, 34, 1, 47, 11, 245, 171}, + { 62, 17, 19, 70, 146, 85, 55, 62, 70}, + { 75, 15, 9, 9, 64, 255, 184, 119, 16}, + { 37, 43, 37, 154, 100, 163, 85, 160, 1}, + { 63, 9, 92, 136, 28, 64, 32, 201, 85}, + { 86, 6, 28, 5, 64, 255, 25, 248, 1}, + { 56, 8, 17, 132, 137, 255, 55, 116, 128}, + { 58, 15, 20, 82, 135, 57, 26, 121, 40} + }, + { + { 164, 50, 31, 137, 154, 133, 25, 35, 218}, + { 51, 103, 44, 131, 131, 123, 31, 6, 158}, + { 86, 40, 64, 135, 148, 224, 45, 183, 128}, + { 22, 26, 17, 131, 240, 154, 14, 1, 209}, + { 83, 12, 13, 54, 192, 255, 68, 47, 28}, + { 45, 16, 21, 91, 64, 222, 7, 1, 197}, + { 56, 21, 39, 155, 60, 138, 23, 102, 213}, + { 85, 26, 85, 85, 128, 128, 32, 146, 171}, + { 18, 11, 7, 63, 144, 171, 4, 4, 246}, + { 35, 27, 10, 146, 174, 171, 12, 26, 128} + }, + + + +Bankoski, et al. Informational [Page 49] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + { + { 190, 80, 35, 99, 180, 80, 126, 54, 45}, + { 85, 126, 47, 87, 176, 51, 41, 20, 32}, + { 101, 75, 128, 139, 118, 146, 116, 128, 85}, + { 56, 41, 15, 176, 236, 85, 37, 9, 62}, + { 146, 36, 19, 30, 171, 255, 97, 27, 20}, + { 71, 30, 17, 119, 118, 255, 17, 18, 138}, + { 101, 38, 60, 138, 55, 70, 43, 26, 142}, + { 138, 45, 61, 62, 219, 1, 81, 188, 64}, + { 32, 41, 20, 117, 151, 142, 20, 21, 163}, + { 112, 19, 12, 61, 195, 128, 48, 4, 24} + } + }; + + ---- End code block ---------------------------------------- + +12. Intraframe Prediction + + Intraframe prediction uses already-coded macroblocks within the + current frame to approximate the contents of the current macroblock. + It applies to intra-coded macroblocks in an interframe and to all + macroblocks in a key frame. + + Relative to the current macroblock "M", the already-coded macroblocks + include all macroblocks above M together with the macroblocks on the + same row as, and to the left of, M, though at most four of these + macroblocks are actually used: the block "A" directly above M, the + blocks immediately to the left and right of A, and the block + immediately to the left of M. + + Each of the prediction modes (i.e., means of extrapolation from + already-calculated values) uses fairly simple arithmetic on pixel + values whose positions, relative to the current position, are defined + by the mode. + + The chroma (U and V) and luma (Y) predictions are independent of each + other. + + The relative addressing of pixels applied to macroblocks on the upper + row or left column of the frame will sometimes cause pixels outside + the visible frame to be referenced. Usually such out-of-bounds + pixels have an assumed value of 129 for pixels to the left of the + leftmost column of the visible frame and 127 for pixels above the top + row of the visible frame (including the special case of the pixel + above and to the left of the top-left pixel in the visible frame). + Exceptions to this (associated to certain modes) will be noted below. + + + + + +Bankoski, et al. Informational [Page 50] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + The already-coded macroblocks referenced by intra-prediction have + been "reconstructed", that is, have been predicted and residue- + adjusted (as described in Section 14), but have not been loop- + filtered. While it does process the edges between individual + macroblocks and individual subblocks, loop filtering (described in + Section 15) is applied to the frame as a whole, after all of the + macroblocks have been reconstructed. + +12.1. mb_skip_coeff + + The single bool flag is decoded using prob_skip_false if and only if + mb_no_skip_coeff is set to 1 (see Sections 9.10 and 9.11). If + mb_no_skip_coeff is set to 0, then this value defaults to 0. + +12.2. Chroma Prediction + + The chroma prediction is a little simpler than the luma prediction, + so we treat it first. Each of the chroma modes treats U and V + identically; that is, the U and V prediction values are calculated in + parallel, using the same relative addressing and arithmetic in each + of the two planes. + + The modes extrapolate prediction values using the 8-pixel row "A" + lying immediately above the block (that is, the bottom chroma row of + the macroblock immediately above the current macroblock) and the + 8-pixel column "L" immediately to the left of the block (that is, the + rightmost chroma column of the macroblock immediately to the left of + the current macroblock). + + Vertical prediction (chroma mode V_PRED) simply fills each 8-pixel + row of the 8x8 chroma block with a copy of the "above" row (A). If + the current macroblock lies on the top row of the frame, all 8 of the + pixel values in A are assigned the value 127. + + Similarly, horizontal prediction (H_PRED) fills each 8-pixel column + of the 8x8 chroma block with a copy of the "left" column (L). If the + current macroblock is in the left column of the frame, all 8 pixel + values in L are assigned the value 129. + + DC prediction (DC_PRED) fills the 8x8 chroma block with a single + value. In the generic case of a macroblock lying below the top row + and right of the leftmost column of the frame, this value is the + average of the 16 (genuinely visible) pixels in the (union of the) + above row A and left column L. + + Otherwise, if the current macroblock lies on the top row of the + frame, the average of the 8 pixels in L is used; if it lies in the + left column of the frame, the average of the 8 pixels in A is used. + + + +Bankoski, et al. Informational [Page 51] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + Note that the averages used in these exceptional cases are not the + same as those that would be arrived at by using the out-of-bounds A + and L values defined for V_PRED and H_PRED. In the case of the + leftmost macroblock on the top row of the frame, the 8x8 block is + simply filled with the constant value 128. + + For DC_PRED, apart from the exceptional case of the top-left + macroblock, we are averaging either 16 or 8 pixel values to get a + single prediction value that fills the 8x8 block. The rounding is + done as follows: + + ---- Begin code block -------------------------------------- + + int sum; /* sum of 8 or 16 pixels at (at least) 16-bit precision */ + int shf; /* base 2 logarithm of the number of pixels (3 or 4) */ + + Pixel DCvalue = (sum + (1 << (shf-1))) >> shf; + + ---- End code block ---------------------------------------- + + Because the summands are all valid pixels, no "clamp" is necessary in + the calculation of DCvalue. + + The remaining "True Motion" (TM_PRED) chroma mode gets its name from + an older technique of video compression used by On2 Technologies, to + which it bears some relation. In addition to the row "A" and column + "L", TM_PRED uses the pixel "P" above and to the left of the chroma + block. + + + + + + + + + + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 52] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + The following figure gives an example of how TM_PRED works: + + ---- Begin code block -------------------------------------- + + |-----|-----|-----|-----|-----|-----|-----|-----|-----| + | P | A0 | A1 | A2 | A3 | A4 | A5 | A6 | A7 | + |-----|-----|-----|-----|-----|-----|-----|-----|-----| + | L0 | X00 | X01 | X02 | X03 | X04 | X05 | X06 | X07 | + |-----|-----|-----|-----|-----|-----|-----|-----|-----| + | L1 | X10 | X11 | X12 | X13 | X14 | X15 | X16 | X17 | + |-----|-----|-----|-----|-----|-----|-----|-----|-----| + | L2 | X20 | X21 | X22 | X23 | X24 | X25 | X26 | X27 | + |-----|-----|-----|-----|-----|-----|-----|-----|-----| + | L3 | X30 | X31 | X32 | X33 | X34 | X35 | X36 | X37 | + |-----|-----|-----|-----|-----|-----|-----|-----|-----| + | L4 | X40 | X41 | X42 | X43 | X44 | X45 | X46 | X47 | + |-----|-----|-----|-----|-----|-----|-----|-----|-----| + | L5 | X50 | X51 | X52 | X53 | X54 | X55 | X56 | X57 | + |-----|-----|-----|-----|-----|-----|-----|-----|-----| + | L6 | X60 | X61 | X62 | X63 | X64 | X65 | X66 | X67 | + |-----|-----|-----|-----|-----|-----|-----|-----|-----| + | L7 | X70 | X71 | X72 | X73 | X74 | X75 | X76 | X77 | + |-----|-----|-----|-----|-----|-----|-----|-----|-----| + + ---- End code block ---------------------------------------- + + Where P, As, and Ls represent reconstructed pixel values from + previously coded blocks, and X00 through X77 represent predicted + values for the current block. TM_PRED uses the following equation to + calculate X_ij: + + X_ij = L_i + A_j - P (i, j=0, 1, 2, 3) + + + + + + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 53] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + The exact algorithm is as follows: + + ---- Begin code block -------------------------------------- + + void TMpred( + Pixel b[8][8], /* chroma (U or V) prediction block */ + const Pixel A[8], /* row of already-constructed pixels + above block */ + const Pixel L[8], /* column of "" just to the left of + block */ + const Pixel P /* pixel just to the left of A and + above L*/ + ) { + int r = 0; /* row */ + do { + int c = 0; /* column */ + do { + b[r][c] = clamp255(L[r]+ A[c] - P); + } while (++c < 8); + } while (++r < 8); + } + + ---- End code block ---------------------------------------- + + Note that the process could equivalently be described as propagating + the vertical differences between pixels in L (starting from P), using + the pixels from A to start each column. + + An implementation of chroma intra-prediction may be found in the + reference decoder file predict.c (Section 20.14). + + Unlike DC_PRED, for macroblocks on the top row or left edge, TM_PRED + does use the out-of-bounds values of 127 and 129 (respectively) + defined for V_PRED and H_PRED. + +12.3. Luma Prediction + + The prediction processes for the first four 16x16 luma modes + (DC_PRED, V_PRED, H_PRED, and TM_PRED) are essentially identical to + the corresponding chroma prediction processes described above, the + only difference being that we are predicting a single 16x16 luma + block instead of two 8x8 chroma blocks. + + Thus, the row "A" and column "L" here contain 16 pixels, the DC + prediction is calculated using 16 or 32 pixels (and shf is 4 or 5), + and we of course fill the entire prediction buffer, that is, 16 rows + (or columns) containing 16 pixels each. The reference implementation + of 16x16 luma prediction is also in predict.c. + + + +Bankoski, et al. Informational [Page 54] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + In the remaining luma mode (B_PRED), each 4x4 Y subblock is + independently predicted using one of ten modes (listed, along with + their encodings, in Section 11). + + Also, unlike the full-macroblock modes already described, some of the + subblock modes use prediction pixels above and to the right of the + current subblock. In detail, each 4x4 subblock "B" is predicted + using (at most) the 4-pixel column "L" immediately to the left of B + and the 8-pixel row "A" immediately above B, consisting of the 4 + pixels above B followed by the 4 adjacent pixels above and to the + right of B, together with the single pixel "P" immediately to the + left of A (and immediately above L). + + For the purpose of subblock intra-prediction, the pixels immediately + to the left and right of a pixel in a subblock are the same as the + pixels immediately to the left and right of the corresponding pixel + in the frame buffer "F". Vertical offsets behave similarly: The + above row A lies immediately above B in F, and the adjacent pixels in + the left column L are separated by a single row in F. + + Because entire macroblocks (as opposed to their constituent + subblocks) are reconstructed in raster-scan order, for subblocks + lying along the right edge (and not along the top row) of the current + macroblock, the four "extra" prediction pixels in A above and to the + right of B have not yet actually been constructed. + + Subblocks 7, 11, and 15 are affected. All three of these subblocks + use the same extra pixels as does subblock 3 (at the upper right + corner of the macroblock), namely the 4 pixels immediately above and + to the right of subblock 3. Writing (R,C) for a frame buffer + position offset from the upper left corner of the current macroblock + by R rows and C columns, the extra pixels for all the right-edge + subblocks (3, 7, 11, and 15) are at positions (-1,16), (-1,17), + (-1,18), and (-1,19). For the rightmost macroblock in each + macroblock row except the top row, the extra pixels shall use the + same value as the pixel at position (-1,15), which is the rightmost + visible pixel on the line immediately above the macroblock row. For + the top macroblock row, all the extra pixels assume a value of 127. + + The details of the prediction modes are most easily described in + code. + + + + + + + + + + +Bankoski, et al. Informational [Page 55] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + ---- Begin code block -------------------------------------- + + /* Result pixels are often averages of two or three predictor + pixels. The following subroutines are used to calculate + these averages. Because the arguments are valid pixels, no + clamping is necessary. An actual implementation would + probably use inline functions or macros. */ + + /* Compute weighted average centered at y w/adjacent x, z */ + + Pixel avg3(Pixel x, Pixel y, Pixel z) { + return (x + y + y + z + 2) >> 2;} + + /* Weighted average of 3 adjacent pixels centered at p */ + + Pixel avg3p(const Pixel *p) { return avg3(p[-1], p[0], p[1]);} + + /* Simple average of x and y */ + + Pixel avg2(Pixel x, Pixel y) { return (x + y + 1) >> 1;} + + /* Average of p[0] and p[1] may be considered to be a synthetic + pixel lying between the two, that is, one half-step past p. */ + + Pixel avg2p(const Pixel *p) { return avg2(p[0], p[1]);} + + void subblock_intra_predict( + Pixel B[4][4], /* Y subblock prediction buffer */ + const Pixel *A, /* A[0]...A[7] = above row, A[-1] = P */ + const Pixel *L, /* L[0]...L[3] = left column, L[-1] = P */ + intra_bmode mode /* enum is in Section 11.2 */ + ) { + Pixel E[9]; /* 9 already-constructed edge pixels */ + E[0] = L[3]; E[1] = L[2]; E[2] = L[1]; E[3] = L[0]; + E[4] = A[-1]; /* == L[-1] == P */ + E[5] = A[0]; E[6] = A[1]; E[7] = A[2]; E[8] = A[3]; + + switch(mode) { + /* First four modes are similar to corresponding + full-block modes. */ + + case B_DC_PRED: + { + int v = 4; /* DC sum/avg, 4 is rounding adjustment */ + int i = 0; do { v += A[i] + L[i];} while (++i < 4); + v >>= 3; /* averaging 8 pixels */ + i = 0; do { /* fill prediction buffer with constant DC + value */ + + + +Bankoski, et al. Informational [Page 56] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + int j = 0; do { B[i][j] = v;} while (++j < 4); + } while (++i < 4); + break; + } + + case B_TM_PRED: /* just like 16x16 TM_PRED */ + { + int r = 0; do { + int c = 0; do { + B[r][c] = clamp255(L[r] + A[c] - A[-1]); + } while (++c < 4); + } while (++r < 4); + break; + } + + case B_VE_PRED: /* like 16x16 V_PRED except using averages */ + { + int c = 0; do { /* all 4 rows = smoothed top row */ + B[0][c] = B[1][c] = B[2][c] = B[3][c] = avg3p(A + c); + } while (++c < 4); + break; + } + + case B_HE_PRED: /* like 16x16 H_PRED except using averages */ + { + /* Bottom row is exceptional because L[4] does not exist */ + int v = avg3(L[2], L[3], L[3]); + int r = 3; while (1) { /* all 4 columns = smoothed left + column */ + B[r][0] = B[r][1] = B[r][2] = B[r][3] = v; + if (--r < 0) + break; + v = avg3p(L + r); /* upper 3 rows use average of + 3 pixels */ + } + break; + } + + /* The remaining six "diagonal" modes subdivide the + prediction buffer into diagonal lines. All the pixels + on each line are assigned the same value; this value is + (a smoothed or synthetic version of) an + already-constructed predictor value lying on the same + line. For clarity, in the comments, we express the + positions of these predictor pixels relative to the + upper left corner of the destination array B. + + + + + +Bankoski, et al. Informational [Page 57] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + These modes are unique to subblock prediction and have + no full-block analogs. The first two use lines at + +|- 45 degrees from horizontal (or, equivalently, + vertical), that is, lines whose slopes are +|- 1. */ + + case B_LD_PRED: /* southwest (left and down) step = + (-1, 1) or (1,-1) */ + /* avg3p(A + j) is the "smoothed" pixel at (-1,j) */ + B[0][0] = avg3p(A + 1); + B[0][1] = B[1][0] = avg3p(A + 2); + B[0][2] = B[1][1] = B[2][0] = avg3p(A + 3); + B[0][3] = B[1][2] = B[2][1] = B[3][0] = avg3p(A + 4); + B[1][3] = B[2][2] = B[3][1] = avg3p(A + 5); + B[2][3] = B[3][2] = avg3p(A + 6); + B[3][3] = avg3(A[6], A[7], A[7]); /* A[8] does not exist */ + break; + + case B_RD_PRED: /* southeast (right and down) step = + (1,1) or (-1,-1) */ + B[3][0] = avg3p(E + 1); /* predictor is from (2, -1) */ + B[3][1] = B[2][0] = avg3p(E + 2); /* (1, -1) */ + B[3][2] = B[2][1] = B[1][0] = avg3p(E + 3); /* (0, -1) */ + B[3][3] = B[2][2] = B[1][1] = B[0][0] = + avg3p(E + 4); /* (-1, -1) */ + B[2][3] = B[1][2] = B[0][1] = avg3p(E + 5); /* (-1, 0) */ + B[1][3] = B[0][2] = avg3p(E + 6); /* (-1, 1) */ + B[0][3] = avg3p(E + 7); /* (-1, 2) */ + break; + + /* The remaining 4 diagonal modes use lines whose slopes are + +|- 2 and +|- 1/2. The angles of these lines are roughly + +|- 27 degrees from horizontal or vertical. + + Unlike the 45 degree diagonals, here we often need to + "synthesize" predictor pixels midway between two actual + predictors using avg2p(p), which we think of as returning + the pixel "at" p[1/2]. */ + + case B_VR_PRED: /* SSE (vertical right) step = + (2,1) or (-2,-1) */ + B[3][0] = avg3p(E + 2); /* predictor is from (1, -1) */ + B[2][0] = avg3p(E + 3); /* (0, -1) */ + B[3][1] = B[1][0] = avg3p(E + 4); /* (-1, -1) */ + B[2][1] = B[0][0] = avg2p(E + 4); /* (-1, -1/2) */ + B[3][2] = B[1][1] = avg3p(E + 5); /* (-1, 0) */ + B[2][2] = B[0][1] = avg2p(E + 5); /* (-1, 1/2) */ + B[3][3] = B[1][2] = avg3p(E + 6); /* (-1, 1) */ + B[2][3] = B[0][2] = avg2p(E + 6); /* (-1, 3/2) */ + + + +Bankoski, et al. Informational [Page 58] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + B[1][3] = avg3p(E + 7); /* (-1, 2) */ + B[0][3] = avg2p(E + 7); /* (-1, 5/2) */ + break; + + case B_VL_PRED: /* SSW (vertical left) step = + (2,-1) or (-2,1) */ + B[0][0] = avg2p(A); /* predictor is from (-1, 1/2) */ + B[1][0] = avg3p(A + 1); /* (-1, 1) */ + B[2][0] = B[0][1] = avg2p(A + 1); /* (-1, 3/2) */ + B[1][1] = B[3][0] = avg3p(A + 2); /* (-1, 2) */ + B[2][1] = B[0][2] = avg2p(A + 2); /* (-1, 5/2) */ + B[3][1] = B[1][2] = avg3p(A + 3); /* (-1, 3) */ + B[2][2] = B[0][3] = avg2p(A + 3); /* (-1, 7/2) */ + B[3][2] = B[1][3] = avg3p(A + 4); /* (-1, 4) */ + /* Last two values do not strictly follow the pattern. */ + B[2][3] = avg3p(A + 5); /* (-1, 5) [avg2p(A + 4) = + (-1,9/2)] */ + B[3][3] = avg3p(A + 6); /* (-1, 6) [avg3p(A + 5) = + (-1,5)] */ + break; + + case B_HD_PRED: /* ESE (horizontal down) step = + (1,2) or (-1,-2) */ + B[3][0] = avg2p(E); /* predictor is from (5/2, -1) */ + B[3][1] = avg3p(E + 1); /* (2, -1) */ + B[2][0] = B[3][2] = svg2p(E + 1); /* ( 3/2, -1) */ + B[2][1] = B[3][3] = avg3p(E + 2); /* ( 1, -1) */ + B[2][2] = B[1][0] = avg2p(E + 2); /* ( 1/2, -1) */ + B[2][3] = B[1][1] = avg3p(E + 3); /* ( 0, -1) */ + B[1][2] = B[0][0] = avg2p(E + 3); /* (-1/2, -1) */ + B[1][3] = B[0][1] = avg3p(E + 4); /* ( -1, -1) */ + B[0][2] = avg3p(E + 5); /* (-1, 0) */ + B[0][3] = avg3p(E + 6); /* (-1, 1) */ + break; + + case B_HU_PRED: /* ENE (horizontal up) step = (1,-2) + or (-1,2) */ + B[0][0] = avg2p(L); /* predictor is from (1/2, -1) */ + B[0][1] = avg3p(L + 1); /* (1, -1) */ + B[0][2] = B[1][0] = avg2p(L + 1); /* (3/2, -1) */ + B[0][3] = B[1][1] = avg3p(L + 2); /* ( 2, -1) */ + B[1][2] = B[2][0] = avg2p(L + 2); /* (5/2, -1) */ + B[1][3] = B[2][1] = avg3(L[2], L[3], L[3]); /* (3, -1) */ + + + + + + + + +Bankoski, et al. Informational [Page 59] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /* Not possible to follow pattern for much of the bottom + row because no (nearby) already-constructed pixels lie + on the diagonals in question. */ + B[2][2] = B[2][3] = B[3][0] = B[3][1] = B[3][2] = B[3][3] + = L[3]; + } + } + + ---- End code block ---------------------------------------- + + The reference decoder implementation of subblock intra-prediction may + be found in predict.c (Section 20.14). + +13. DCT Coefficient Decoding + + The second data partition consists of an encoding of the quantized + DCT (and WHT) coefficients of the residue signal. As discussed in + the format overview (Section 2), for each macroblock, the residue is + added to the (intra- or inter-generated) prediction buffer to produce + the final (except for loop filtering) reconstructed macroblock. + + VP8 works exclusively with 4x4 DCTs and WHTs, applied to the 24 (or + 25 with the Y2 subblock) 4x4 subblocks of a macroblock. The ordering + of macroblocks within any of the "residue" partitions in general + follows the same raster scan as used in the first "prediction" + partition. + + For all intra- and inter-prediction modes apart from B_PRED (intra: + whose Y subblocks are independently predicted) and SPLITMV (inter), + each macroblock's residue record begins with the Y2 component of the + residue, coded using a WHT. B_PRED and SPLITMV coded macroblocks + omit this WHT and specify the 0th DCT coefficient in each of the 16 Y + subblocks. + + After the optional Y2 block, the residue record continues with 16 + DCTs for the Y subblocks, followed by 4 DCTs for the U subblocks, + ending with 4 DCTs for the V subblocks. The subblocks occur in the + usual order. + + The DCTs and WHT are tree-coded using a 12-element alphabet whose + members we call "tokens". Except for the end-of-block token (which + sets the remaining subblock coefficients to zero and is followed by + the next block), each token (sometimes augmented with data + immediately following the token) specifies the value of the single + coefficient at the current (implicit) position and is followed by a + token applying to the next (implicit) position. + + + + + +Bankoski, et al. Informational [Page 60] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + For all the Y and chroma subblocks, the ordering of the coefficients + follows a so-called zig-zag order. DCTs begin at coefficient 1 if Y2 + is present, and begin at coefficient 0 if Y2 is absent. The WHT for + a Y2 subblock always begins at coefficient 0. + +13.1. Macroblock without Non-Zero Coefficient Values + + If the flag within macroblock (MB) MODE_INFO indicates that a + macroblock does not have any non-zero coefficients, the decoding + process of DCT coefficients is skipped for the macroblock. + +13.2. Coding of Individual Coefficient Values + + The coding of coefficient tokens is the same for the DCT and WHT, and + for the remainder of this section "DCT" should be taken to mean + either DCT or WHT. + + All tokens (except end-of-block) specify either a single unsigned + value or a range of unsigned values (immediately) followed by a + simple probabilistic encoding of the offset of the value from the + base of that range. + + Non-zero values (of either type) are then followed by a flag + indicating the sign of the coded value (negative if 1, positive + if 0). + + Below are the tokens and decoding tree. + + ---- Begin code block -------------------------------------- + + typedef enum + { + DCT_0, /* value 0 */ + DCT_1, /* 1 */ + DCT_2, /* 2 */ + DCT_3, /* 3 */ + DCT_4, /* 4 */ + dct_cat1, /* range 5 - 6 (size 2) */ + dct_cat2, /* 7 - 10 (4) */ + dct_cat3, /* 11 - 18 (8) */ + dct_cat4, /* 19 - 34 (16) */ + dct_cat5, /* 35 - 66 (32) */ + dct_cat6, /* 67 - 2048 (1982) */ + dct_eob, /* end of block */ + + num_dct_tokens /* 12 */ + } + dct_token; + + + +Bankoski, et al. Informational [Page 61] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + const tree_index coeff_tree [2 * (num_dct_tokens - 1)] = + { + -dct_eob, 2, /* eob = "0" */ + -DCT_0, 4, /* 0 = "10" */ + -DCT_1, 6, /* 1 = "110" */ + 8, 12, + -DCT_2, 10, /* 2 = "11100" */ + -DCT_3, -DCT_4, /* 3 = "111010", 4 = "111011" */ + 14, 16, + -dct_cat1, -dct_cat2, /* cat1 = "111100", + cat2 = "111101" */ + 18, 20, + -dct_cat3, -dct_cat4, /* cat3 = "1111100", + cat4 = "1111101" */ + -dct_cat5, -dct_cat6 /* cat4 = "1111110", + cat4 = "1111111" */ + }; + + ---- End code block ---------------------------------------- + + In general, all DCT coefficients are decoded using the same tree. + However, if the preceding coefficient is a DCT_0, decoding will skip + the first branch, since it is not possible for dct_eob to follow a + DCT_0. + + The tokens dct_cat1 ... dct_cat6 specify ranges of unsigned values, + the value within the range being formed by adding an unsigned offset + (whose width is 1, 2, 3, 4, 5, or 11 bits, respectively) to the base + of the range, using the following algorithm and fixed probability + tables. + + + + + + + + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 62] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + ---- Begin code block -------------------------------------- + + uint DCTextra(bool_decoder *d, const Prob *p) + { + uint v = 0; + do { v += v + read_bool(d, *p);} while (*++p); + return v; + } + + const Prob Pcat1[] = { 159, 0}; + const Prob Pcat2[] = { 165, 145, 0}; + const Prob Pcat3[] = { 173, 148, 140, 0}; + const Prob Pcat4[] = { 176, 155, 140, 135, 0}; + const Prob Pcat5[] = { 180, 157, 141, 134, 130, 0}; + const Prob Pcat6[] = + { 254, 254, 243, 230, 196, 177, 153, 140, 133, 130, 129, 0}; + + ---- End code block ---------------------------------------- + + If v -- the unsigned value decoded using the coefficient tree, + possibly augmented by the process above -- is non-zero, its sign is + set by simply reading a flag: + + ---- Begin code block -------------------------------------- + + if (read_bool(d, 128)) + v = -v; + + ---- End code block ---------------------------------------- + +13.3. Token Probabilities + + The probability specification for the token tree (unlike that for the + "extra bits" described above) is rather involved. It uses three + pieces of context to index a large probability table, the contents of + which may be incrementally modified in the frame header. The full + (non-constant) probability table is laid out as follows. + + ---- Begin code block -------------------------------------- + + Prob coeff_probs [4] [8] [3] [num_dct_tokens-1]; + + ---- End code block ---------------------------------------- + + + + + + + + +Bankoski, et al. Informational [Page 63] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + Working from the outside in, the outermost dimension is indexed by + the type of plane being decoded: + + o 0 - Y beginning at coefficient 1 (i.e., Y after Y2) + + o 1 - Y2 + + o 2 - U or V + + o 3 - Y beginning at coefficient 0 (i.e., Y in the absence of Y2). + + The next dimension is selected by the position of the coefficient + being decoded. That position, c, steps by ones up to 15, starting + from zero for block types 1, 2, or 3 and starting from one for block + type 0. The second array index is then + + ---- Begin code block -------------------------------------- + + coeff_bands [c] + + ---- End code block ---------------------------------------- + + Where: + + ---- Begin code block -------------------------------------- + + const int coeff_bands [16] = { + 0, 1, 2, 3, 6, 4, 5, 6, 6, 6, 6, 6, 6, 6, 6, 7 + }; + + ---- End code block ---------------------------------------- + + is a fixed mapping of position to "band". + + The third dimension is the trickiest. Roughly speaking, it measures + the "local complexity" or extent to which nearby coefficients are + non-zero. + + For the first coefficient (DC, unless the block type is 0), we + consider the (already encoded) blocks within the same plane (Y2, Y, + U, or V) above and to the left of the current block. The context + index is then the number (0, 1, or 2) of these blocks that had at + least one non-zero coefficient in their residue record. Specifically + for Y2, because macroblocks above and to the left may or may not have + a Y2 block, the block above is determined by the most recent + macroblock in the same column that has a Y2 block, and the block to + the left is determined by the most recent macroblock in the same row + that has a Y2 block. + + + +Bankoski, et al. Informational [Page 64] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + Beyond the first coefficient, the context index is determined by the + absolute value of the most recently decoded coefficient (necessarily + within the current block) and is 0 if the last coefficient was a + zero, 1 if it was plus or minus one, and 2 if its absolute value + exceeded one. + + Note that the intuitive meaning of this measure changes as + coefficients are decoded. For example, prior to the first token, a + zero means that the neighbors are empty, suggesting that the current + block may also be empty. After the first token, because an end-of- + block token must have at least one non-zero value before it, a zero + means that we just decoded a zero and hence guarantees that a + non-zero coefficient will appear later in this block. However, this + shift in meaning is perfectly okay because the complete context + depends also on the coefficient band (and since band 0 is occupied + exclusively by position 0). + + As with other contexts used by VP8, the "neighboring block" context + described here needs a special definition for subblocks lying along + the top row or left edge of the frame. These "non-existent" + predictors above and to the left of the image are simply taken to be + empty -- that is, taken to contain no non-zero coefficients. + + The residue decoding of each macroblock then requires, in each of two + directions (above and to the left), an aggregate coefficient + predictor consisting of a single Y2 predictor, two predictors for + each of U and V, and four predictors for Y. In accordance with the + scan-ordering of macroblocks, a decoder needs to maintain a single + "left" aggregate predictor and a row of "above" aggregate predictors. + + Before decoding any residue, these maintained predictors may simply + be cleared, in compliance with the definition of "non-existent" + prediction. After each block is decoded, the two predictors + referenced by the block are replaced with the (empty or non-empty) + state of the block, in preparation for the later decoding of the + blocks below and to the right of the block just decoded. + + The fourth, and final, dimension of the token probability array is of + course indexed by (half) the position in the token tree structure, as + are all tree probability arrays. + + The pseudocode below illustrates the decoding process. Note that + criteria, functions, etc. delimited with ** are either dependent on + decoder architecture or are elaborated on elsewhere in this document. + + + + + + + +Bankoski, et al. Informational [Page 65] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + ---- Begin code block -------------------------------------- + + int block[16] = { 0 }; /* current 4x4 block coeffs */ + int firstCoeff = 0; + int plane; + int ctx2; + int ctx3 = 0; /* the 3rd context referred to in above description */ + Prob *probTable; + int token; + int sign; + int absValue; + int extraBits; + bool prevCoeffWasZero = false; + bool currentBlockHasCoeffs = false; + /* base coeff abs values per each category, elem #0 is + DCT_VAL_CATEGORY1, * #1 is DCT_VAL_CATEGORY2, etc. */ + int categoryBase[6] = { 5, 7, 11, 19, 35, 67 }; + + /* Determine plane to use */ + if ( **current_block_is_Y2_block** ) plane = 0; + else if ( **current_block_is_chroma** ) plane = 2; + else if ( **current_macroblock_has_Y2** ) plane = 1; + else plane = 3; + + /* For luma blocks of a "Y2 macroblock" we skip coeff index #0 */ + if ( plane == 1 ) + firstCoeff++; + + /* Determine whether neighbor 4x4 blocks have coefficients. + This is dependent on the plane we are currently decoding; + i.e., we check only coefficients from the same plane as the + current block. */ + if ( **left_neighbor_block_has_coefficients(plane)** ) + ctx3++; + if ( **above_neighbor_block_has_coefficients(plane)** ) + ctx3++; + + for( i = firstCoeff; i < 16; ++i ) + { + ctx2 = coeff_bands[i]; + probTable = coeff_probs[plane][ctx2][ctx3]; + + /* skip first code (dct_eob) if previous token was DCT_0 */ + if ( prevCoeffWasZero ) + token = treed_read ( d, **coeff_tree_without_eob**, + probTable ); + else + token = treed_read ( d, coeff_tree, probTable ); + + + +Bankoski, et al. Informational [Page 66] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + if ( token == dct_eob ) + break; + + if ( token != DCT_0 ) + { + currentBlockHasCoeffs = true; + if ( **token_has_extra_bits(token)** ) + { + extraBits = DCTextra( token ); + absValue = + categoryBase[**token_to_cat_index(token)**] + + extraBits; + } + else + { + absValue = **token_to_abs_value(token)**; + } + + sign = read_bool(d, 128); + block[i] = sign ? -absValue : absValue; + } + else + { + absValue = 0; + } + + /* Set contexts and stuff for next coeff */ + if ( absValue == 0 ) ctx3 = 0; + else if ( absValue == 1 ) ctx3 = 1; + else ctx3 = 2; + prevCoeffWasZero = true; + } + + /* Store current block status to decoder internals */ + **block_has_coefficients[currentMb][currentBlock]** = + currentBlockHasCoeffs; + + ---- End code block ---------------------------------------- + + While we have in fact completely described the coefficient decoding + procedure, the reader will probably find it helpful to consult the + reference implementation, which can be found in the file tokens.c + (Section 20.16). + + + + + + + + +Bankoski, et al. Informational [Page 67] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +13.4. Token Probability Updates + + As mentioned above, the token-decoding probabilities may change from + frame to frame. After detection of a key frame, they are of course + set to their defaults as shown in Section 13.5; this must occur + before decoding the remainder of the header, as both key frames and + interframes may adjust these probabilities. + + The layout and semantics of the coefficient probability update record + (Section I of the frame header) are straightforward. For each + position in the coeff_probs array there occurs a fixed-probability + bool indicating whether or not the corresponding probability should + be updated. If the bool is true, there follows a P(8) replacing that + probability. Note that updates are cumulative; that is, a + probability updated on one frame is in effect for all ensuing frames + until the next key frame, or until the probability is explicitly + updated by another frame. + + The algorithm to effect the foregoing is simple: + + ---- Begin code block -------------------------------------- + + int i = 0; do { + int j = 0; do { + int k = 0; do { + int t = 0; do { + + if (read_bool(d, coeff_update_probs [i] [j] [k] [t])) + coeff_probs [i] [j] [k] [t] = read_literal(d, 8); + + } while (++t < num_dct_tokens - 1); + } while (++k < 3); + } while (++j < 8); + } while (++i < 4); + + ---- End code block ---------------------------------------- + + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 68] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + The (constant) update probabilities are as follows: + + ---- Begin code block -------------------------------------- + + const Prob coeff_update_probs [4] [8] [3] [num_dct_tokens-1] = + { + { + { + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} + }, + { + { 176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 223, 241, 252, 255, 255, 255, 255, 255, 255, 255, 255}, + { 249, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255} + }, + { + { 255, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255}, + { 234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + { 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} + }, + { + { 255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + { 239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + { 254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255} + }, + { + { 255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + { 251, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} + }, + { + { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + { 251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + { 254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255} + }, + { + { 255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255}, + { 250, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255}, + { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} + }, + { + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} + } + }, + + + +Bankoski, et al. Informational [Page 69] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + { + { + { 217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255}, + { 234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255} + }, + { + { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + { 238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255} + }, + { + { 255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + { 249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} + }, + { + { 255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} + }, + { + { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + { 252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} + }, + { + { 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + { 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} + }, + { + { 255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255}, + { 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} + }, + { + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} + } + }, + { + { + { 186, 251, 250, 255, 255, 255, 255, 255, 255, 255, 255}, + { 234, 251, 244, 254, 255, 255, 255, 255, 255, 255, 255}, + { 251, 251, 243, 253, 254, 255, 254, 255, 255, 255, 255} + }, + + + +Bankoski, et al. Informational [Page 70] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + { + { 255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + { 236, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + { 251, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255} + }, + { + { 255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + { 254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} + }, + { + { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} + }, + { + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} + }, + { + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} + }, + { + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} + }, + { + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} + } + }, + { + { + { 248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 250, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255}, + { 248, 254, 249, 253, 255, 255, 255, 255, 255, 255, 255} + }, + { + { 255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255}, + { 246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255}, + { 252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255} + }, + + + + +Bankoski, et al. Informational [Page 71] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + { + { 255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255}, + { 248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255}, + { 253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255} + }, + { + { 255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + { 245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + { 253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255} + }, + { + { 255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255}, + { 252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + { 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255} + }, + { + { 255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 249, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + { 255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255} + }, + { + { 255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255}, + { 250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} + }, + { + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} + } + } + }; + + ---- End code block ---------------------------------------- + + + + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 72] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +13.5. Default Token Probability Table + + The default token probabilities are as follows. + + ---- Begin code block -------------------------------------- + + const Prob default_coeff_probs [4] [8] [3] [num_dct_tokens - 1] = + { + { + { + { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, + { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, + { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128} + }, + { + { 253, 136, 254, 255, 228, 219, 128, 128, 128, 128, 128}, + { 189, 129, 242, 255, 227, 213, 255, 219, 128, 128, 128}, + { 106, 126, 227, 252, 214, 209, 255, 255, 128, 128, 128} + }, + { + { 1, 98, 248, 255, 236, 226, 255, 255, 128, 128, 128}, + { 181, 133, 238, 254, 221, 234, 255, 154, 128, 128, 128}, + { 78, 134, 202, 247, 198, 180, 255, 219, 128, 128, 128} + }, + { + { 1, 185, 249, 255, 243, 255, 128, 128, 128, 128, 128}, + { 184, 150, 247, 255, 236, 224, 128, 128, 128, 128, 128}, + { 77, 110, 216, 255, 236, 230, 128, 128, 128, 128, 128} + }, + { + { 1, 101, 251, 255, 241, 255, 128, 128, 128, 128, 128}, + { 170, 139, 241, 252, 236, 209, 255, 255, 128, 128, 128}, + { 37, 116, 196, 243, 228, 255, 255, 255, 128, 128, 128} + }, + { + { 1, 204, 254, 255, 245, 255, 128, 128, 128, 128, 128}, + { 207, 160, 250, 255, 238, 128, 128, 128, 128, 128, 128}, + { 102, 103, 231, 255, 211, 171, 128, 128, 128, 128, 128} + }, + { + { 1, 152, 252, 255, 240, 255, 128, 128, 128, 128, 128}, + { 177, 135, 243, 255, 234, 225, 128, 128, 128, 128, 128}, + { 80, 129, 211, 255, 194, 224, 128, 128, 128, 128, 128} + }, + + + + + + + +Bankoski, et al. Informational [Page 73] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + { + { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, + { 246, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, + { 255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128} + } + }, + { + { + { 198, 35, 237, 223, 193, 187, 162, 160, 145, 155, 62}, + { 131, 45, 198, 221, 172, 176, 220, 157, 252, 221, 1}, + { 68, 47, 146, 208, 149, 167, 221, 162, 255, 223, 128} + }, + { + { 1, 149, 241, 255, 221, 224, 255, 255, 128, 128, 128}, + { 184, 141, 234, 253, 222, 220, 255, 199, 128, 128, 128}, + { 81, 99, 181, 242, 176, 190, 249, 202, 255, 255, 128} + }, + { + { 1, 129, 232, 253, 214, 197, 242, 196, 255, 255, 128}, + { 99, 121, 210, 250, 201, 198, 255, 202, 128, 128, 128}, + { 23, 91, 163, 242, 170, 187, 247, 210, 255, 255, 128} + }, + { + { 1, 200, 246, 255, 234, 255, 128, 128, 128, 128, 128}, + { 109, 178, 241, 255, 231, 245, 255, 255, 128, 128, 128}, + { 44, 130, 201, 253, 205, 192, 255, 255, 128, 128, 128} + }, + { + { 1, 132, 239, 251, 219, 209, 255, 165, 128, 128, 128}, + { 94, 136, 225, 251, 218, 190, 255, 255, 128, 128, 128}, + { 22, 100, 174, 245, 186, 161, 255, 199, 128, 128, 128} + }, + { + { 1, 182, 249, 255, 232, 235, 128, 128, 128, 128, 128}, + { 124, 143, 241, 255, 227, 234, 128, 128, 128, 128, 128}, + { 35, 77, 181, 251, 193, 211, 255, 205, 128, 128, 128} + }, + { + { 1, 157, 247, 255, 236, 231, 255, 255, 128, 128, 128}, + { 121, 141, 235, 255, 225, 227, 255, 255, 128, 128, 128}, + { 45, 99, 188, 251, 195, 217, 255, 224, 128, 128, 128} + }, + { + { 1, 1, 251, 255, 213, 255, 128, 128, 128, 128, 128}, + { 203, 1, 248, 255, 255, 128, 128, 128, 128, 128, 128}, + { 137, 1, 177, 255, 224, 255, 128, 128, 128, 128, 128} + } + }, + + + +Bankoski, et al. Informational [Page 74] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + { + { + { 253, 9, 248, 251, 207, 208, 255, 192, 128, 128, 128}, + { 175, 13, 224, 243, 193, 185, 249, 198, 255, 255, 128}, + { 73, 17, 171, 221, 161, 179, 236, 167, 255, 234, 128} + }, + { + { 1, 95, 247, 253, 212, 183, 255, 255, 128, 128, 128}, + { 239, 90, 244, 250, 211, 209, 255, 255, 128, 128, 128}, + { 155, 77, 195, 248, 188, 195, 255, 255, 128, 128, 128} + }, + { + { 1, 24, 239, 251, 218, 219, 255, 205, 128, 128, 128}, + { 201, 51, 219, 255, 196, 186, 128, 128, 128, 128, 128}, + { 69, 46, 190, 239, 201, 218, 255, 228, 128, 128, 128} + }, + { + { 1, 191, 251, 255, 255, 128, 128, 128, 128, 128, 128}, + { 223, 165, 249, 255, 213, 255, 128, 128, 128, 128, 128}, + { 141, 124, 248, 255, 255, 128, 128, 128, 128, 128, 128} + }, + { + { 1, 16, 248, 255, 255, 128, 128, 128, 128, 128, 128}, + { 190, 36, 230, 255, 236, 255, 128, 128, 128, 128, 128}, + { 149, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128} + }, + { + { 1, 226, 255, 128, 128, 128, 128, 128, 128, 128, 128}, + { 247, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128}, + { 240, 128, 255, 128, 128, 128, 128, 128, 128, 128, 128} + }, + { + { 1, 134, 252, 255, 255, 128, 128, 128, 128, 128, 128}, + { 213, 62, 250, 255, 255, 128, 128, 128, 128, 128, 128}, + { 55, 93, 255, 128, 128, 128, 128, 128, 128, 128, 128} + }, + { + { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, + { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, + { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128} + } + }, + { + { + { 202, 24, 213, 235, 186, 191, 220, 160, 240, 175, 255}, + { 126, 38, 182, 232, 169, 184, 228, 174, 255, 187, 128}, + { 61, 46, 138, 219, 151, 178, 240, 170, 255, 216, 128} + }, + + + +Bankoski, et al. Informational [Page 75] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + { + { 1, 112, 230, 250, 199, 191, 247, 159, 255, 255, 128}, + { 166, 109, 228, 252, 211, 215, 255, 174, 128, 128, 128}, + { 39, 77, 162, 232, 172, 180, 245, 178, 255, 255, 128} + }, + { + { 1, 52, 220, 246, 198, 199, 249, 220, 255, 255, 128}, + { 124, 74, 191, 243, 183, 193, 250, 221, 255, 255, 128}, + { 24, 71, 130, 219, 154, 170, 243, 182, 255, 255, 128} + }, + { + { 1, 182, 225, 249, 219, 240, 255, 224, 128, 128, 128}, + { 149, 150, 226, 252, 216, 205, 255, 171, 128, 128, 128}, + { 28, 108, 170, 242, 183, 194, 254, 223, 255, 255, 128} + }, + { + { 1, 81, 230, 252, 204, 203, 255, 192, 128, 128, 128}, + { 123, 102, 209, 247, 188, 196, 255, 233, 128, 128, 128}, + { 20, 95, 153, 243, 164, 173, 255, 203, 128, 128, 128} + }, + { + { 1, 222, 248, 255, 216, 213, 128, 128, 128, 128, 128}, + { 168, 175, 246, 252, 235, 205, 255, 255, 128, 128, 128}, + { 47, 116, 215, 255, 211, 212, 255, 255, 128, 128, 128} + }, + { + { 1, 121, 236, 253, 212, 214, 255, 255, 128, 128, 128}, + { 141, 84, 213, 252, 201, 202, 255, 219, 128, 128, 128}, + { 42, 80, 160, 240, 162, 185, 255, 205, 128, 128, 128} + }, + { + { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, + { 244, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, + { 238, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128} + } + } + }; + + ---- End code block ---------------------------------------- + +14. DCT and WHT Inversion and Macroblock Reconstruction + +14.1. Dequantization + + After decoding the DCTs/WHTs as described above, each (quantized) + coefficient in each subblock is multiplied by one of six + dequantization factors, the choice of factor depending on the plane + (Y2, Y, or chroma) and position (DC = coefficient zero, AC = any + + + +Bankoski, et al. Informational [Page 76] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + other coefficient). If the current macroblock has overridden the + quantizer level (as described in Section 10), then the six factors + are looked up from two dequantization tables with appropriate scaling + and clamping using the single index supplied by the override. + Otherwise, the frame-level dequantization factors (as described in + Section 9.6) are used. In either case, the multiplies are computed + and stored using 16-bit signed integers. + + The two dequantization tables, which may also be found in the + reference decoder file dequant_data.h (Section 20.3), are as follows. + + ---- Begin code block -------------------------------------- + + static const int dc_qlookup[QINDEX_RANGE] = + { + 4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, 15, + 16, 17, 17, 18, 19, 20, 20, 21, 21, 22, 22, 23, 23, + 24, 25, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 46, + 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, + 73, 74, 75, 76, 76, 77, 78, 79, 80, 81, 82, 83, 84, + 85, 86, 87, 88, 89, 91, 93, 95, 96, 98, 100, 101, 102, + 104, 106, 108, 110, 112, 114, 116, 118, 122, 124, 126, 128, 130, + 132, 134, 136, 138, 140, 143, 145, 148, 151, 154, 157, + }; + + static const int ac_qlookup[QINDEX_RANGE] = + { + 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, + 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, + 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, + 56, 57, 58, 60, 62, 64, 66, 68, 70, 72, 74, 76, 78, + 80, 82, 84, 86, 88, 90, 92, 94, 96, 98, 100, 102, 104, + 106, 108, 110, 112, 114, 116, 119, 122, 125, 128, 131, 134, 137, + 140, 143, 146, 149, 152, 155, 158, 161, 164, 167, 170, 173, 177, + 181, 185, 189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, + 234, 239, 245, 249, 254, 259, 264, 269, 274, 279, 284, + }; + + ---- End code block ---------------------------------------- + + Lookup values from the above two tables are directly used in the DC + and AC coefficients in Y1, respectively. For Y2 and chroma, values + from the above tables undergo either scaling or clamping before the + multiplies. Details regarding these scaling and clamping processes + can be found in related lookup functions in dixie.c (Section 20.4). + + + +Bankoski, et al. Informational [Page 77] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +14.2. Inverse Transforms + + If the Y2 residue block exists (i.e., the macroblock luma mode is not + SPLITMV or B_PRED), it is inverted first (using the inverse WHT) and + the element of the result at row i, column j is used as the 0th + coefficient of the Y subblock at position (i, j), that is, the Y + subblock whose index is (i * 4) + j. As discussed in Section 13, if + the luma mode is B_PRED or SPLITMV, the 0th Y coefficients are part + of the residue signal for the subblocks themselves. + + In either case, the inverse transforms for the sixteen Y subblocks + and eight chroma subblocks are computed next. All 24 of these + inversions are independent of each other; their results may (at least + conceptually) be stored in 24 separate 4x4 arrays. + + As is done by the reference decoder, an implementation may wish to + represent the prediction and residue buffers as macroblock-sized + arrays (that is, a 16x16 Y buffer and two 8x8 chroma buffers). + Regarding the inverse DCT implementation given below, this requires a + simple adjustment to the address calculation for the resulting + residue pixels. + +14.3. Implementation of the WHT Inversion + + As previously discussed (see Sections 2 and 13), for macroblocks + encoded using prediction modes other than B_PRED and SPLITMV, the DC + values derived from the DCT transform on the 16 Y blocks are + collected to construct a 25th block of a macroblock (16 Y, 4 U, 4 V + constitute the 24 blocks). This 25th block is transformed using a + Walsh-Hadamard transform (WHT). + + The inputs to the inverse WHT (that is, the dequantized + coefficients), the intermediate "horizontally detransformed" signal, + and the completely detransformed residue signal are all stored as + arrays of 16-bit signed integers. + + Following the tradition of specifying bitstream format using the + decoding process, we specify the inverse WHT in the decoding process + using the following C-style source code: + + + + + + + + + + + + +Bankoski, et al. Informational [Page 78] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + ---- Begin code block -------------------------------------- + + void vp8_short_inv_walsh4x4_c(short *input, short *output) + { + int i; + int a1, b1, c1, d1; + int a2, b2, c2, d2; + short *ip = input; + short *op = output; + int temp1, temp2; + + for(i=0;i<4;i++) + { + a1 = ip[0] + ip[12]; + b1 = ip[4] + ip[8]; + c1 = ip[4] - ip[8]; + d1 = ip[0] - ip[12]; + + op[0] = a1 + b1; + op[4] = c1 + d1; + op[8] = a1 - b1; + op[12]= d1 - c1; + ip++; + op++; + } + ip = output; + op = output; + for(i=0;i<4;i++) + { + a1 = ip[0] + ip[3]; + b1 = ip[1] + ip[2]; + c1 = ip[1] - ip[2]; + d1 = ip[0] - ip[3]; + + a2 = a1 + b1; + b2 = c1 + d1; + c2 = a1 - b1; + d2 = d1 - c1; + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 79] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + op[0] = (a2+3)>>3; + op[1] = (b2+3)>>3; + op[2] = (c2+3)>>3; + op[3] = (d2+3)>>3; + + ip+=4; + op+=4; + } + } + + ---- End code block ---------------------------------------- + + In the case that there is only one non-zero DC value in input, the + inverse transform can be simplified to the following: + + ---- Begin code block -------------------------------------- + + void vp8_short_inv_walsh4x4_1_c(short *input, short *output) + { + int i; + int a1; + short *op=output; + + a1 = ((input[0] + 3)>>3); + + for(i=0;i<4;i++) + { + op[0] = a1; + op[1] = a1; + op[2] = a1; + op[3] = a1; + op+=4; + } + } + + ---- End code block ---------------------------------------- + + It should be noted that a conforming decoder should implement the + inverse transform using exactly the same rounding to achieve bit-wise + matching output to the output of the process specified by the above + C source code. + + The reference decoder WHT inversion may be found in the file + idct_add.c (Section 20.8). + + + + + + + +Bankoski, et al. Informational [Page 80] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +14.4. Implementation of the DCT Inversion + + All of the DCT inversions are computed in exactly the same way. In + principle, VP8 uses a classical 2-D inverse discrete cosine + transform, implemented as two passes of 1-D inverse DCT. The 1-D + inverse DCT was calculated using a similar algorithm to what was + described in [Loeffler]. However, the paper only provided the + 8-point and 16-point version of the algorithms, which was adapted by + On2 to perform the 4-point 1-D DCT. + + Accurate calculation of 1-D DCT of the above algorithm requires + infinite precision. VP8 of course can use only a finite-precision + approximation. Also, the inverse DCT used by VP8 takes care of + normalization of the standard unitary transform; that is, every + dequantized coefficient has roughly double the size of the + corresponding unitary coefficient. However, at all but the highest + datarates, the discrepancy between transmitted and ideal coefficients + is due almost entirely to (lossy) compression and not to errors + induced by finite-precision arithmetic. + + The inputs to the inverse DCT (that is, the dequantized + coefficients), the intermediate "horizontally detransformed" signal, + and the completely detransformed residue signal are all stored as + arrays of 16-bit signed integers. The details of the computation are + as follows. + + It should also be noted that this implementation makes use of the + 16-bit fixed-point version of two multiplication constants: + + sqrt(2) * cos (pi/8) + + sqrt(2) * sin (pi/8) + + Because the first constant is bigger than 1, to maintain the same + 16-bit fixed-point precision as the second one, we make use of the + fact that + + x * a = x + x*(a-1) + + therefore + + x * sqrt(2) * cos (pi/8) = x + x * (sqrt(2) * cos(pi/8)-1) + + + + + + + + + +Bankoski, et al. Informational [Page 81] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + ---- Begin code block -------------------------------------- + + /* IDCT implementation */ + static const int cospi8sqrt2minus1=20091; + static const int sinpi8sqrt2 =35468; + void short_idct4x4llm_c(short *input, short *output, int pitch) + { + int i; + int a1, b1, c1, d1; + + short *ip=input; + short *op=output; + int temp1, temp2; + int shortpitch = pitch>>1; + + for(i=0;i<4;i++) + { + a1 = ip[0]+ip[8]; + b1 = ip[0]-ip[8]; + + temp1 = (ip[4] * sinpi8sqrt2)>>16; + temp2 = ip[12]+((ip[12] * cospi8sqrt2minus1)>>16); + c1 = temp1 - temp2; + + temp1 = ip[4] + ((ip[4] * cospi8sqrt2minus1)>>16); + temp2 = (ip[12] * sinpi8sqrt2)>>16; + d1 = temp1 + temp2; + + op[shortpitch*0] = a1+d1; + op[shortpitch*3] = a1-d1; + op[shortpitch*1] = b1+c1; + op[shortpitch*2] = b1-c1; + + ip++; + op++; + } + ip = output; + op = output; + for(i=0;i<4;i++) + { + a1 = ip[0]+ip[2]; + b1 = ip[0]-ip[2]; + + temp1 = (ip[1] * sinpi8sqrt2)>>16; + temp2 = ip[3]+((ip[3] * cospi8sqrt2minus1)>>16); + c1 = temp1 - temp2; + + temp1 = ip[1] + ((ip[1] * cospi8sqrt2minus1)>>16); + + + +Bankoski, et al. Informational [Page 82] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + temp2 = (ip[3] * sinpi8sqrt2)>>16; + d1 = temp1 + temp2; + + op[0] = (a1+d1+4)>>3; + op[3] = (a1-d1+4)>>3; + op[1] = (b1+c1+4)>>3; + op[2] = (b1-c1+4)>>3; + + ip+=shortpitch; + op+=shortpitch; + } + } + + ---- End code block ---------------------------------------- + + The reference decoder DCT inversion may be found in the file + idct_add.c (Section 20.8). + +14.5. Summation of Predictor and Residue + + Finally, the prediction and residue signals are summed to form the + reconstructed macroblock, which, except for loop filtering (taken up + next), completes the decoding process. + + The summing procedure is fairly straightforward, having only a couple + of details. The prediction and residue buffers are both arrays of + 16-bit signed integers. Each individual (Y, U, and V pixel) result + is calculated first as a 32-bit sum of the prediction and residue, + and is then saturated to 8-bit unsigned range (using, say, the + clamp255 function defined above) before being stored as an 8-bit + unsigned pixel value. + + VP8 also supports a mode where the encoding of a bitstream guarantees + all reconstructed pixel values between 0 and 255; compliant + bitstreams of such requirements have the clamp_type bit in the frame + header set to 1. In such a case, the clamp255 function is no longer + required. + + The summation process is the same, regardless of the (intra or inter) + mode of prediction in effect for the macroblock. The reference + decoder implementation of reconstruction may be found in the file + idct_add.c. + + + + + + + + + +Bankoski, et al. Informational [Page 83] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +15. Loop Filter + + Loop filtering is the last stage of frame reconstruction and the + next-to-last stage of the decoding process. The loop filter is + applied to the entire frame after the summation of predictor and + residue signals, as described in Section 14. + + The purpose of the loop filter is to eliminate (or at least reduce) + visually objectionable artifacts associated with the semi- + independence of the coding of macroblocks and their constituent + subblocks. + + As was discussed in Section 5, the loop filter is "integral" to + decoding, in that the results of loop filtering are used in the + prediction of subsequent frames. Consequently, a functional decoder + implementation must perform loop filtering exactly as described here. + This is distinct from any postprocessing that may be applied only to + the image immediately before display; such postprocessing is entirely + at the option of the implementor (and/or user) and has no effect on + decoding per se. + + The baseline frame-level parameters controlling the loop filter are + defined in the frame header (Section 9.4) along with a mechanism for + adjustment based on a macroblock's prediction mode and/or reference + frame. The first is a flag (filter_type) selecting the type of + filter (normal or simple); the other two are numbers + (loop_filter_level and sharpness_level) that adjust the strength or + sensitivity of the filter. As described in Sections 9.3 and 10, + loop_filter_level may also be overridden on a per-macroblock basis + using segmentation. + + Loop filtering is one of the more computationally intensive aspects + of VP8 decoding. This is the reason for the existence of the + optional, less-demanding simple filter type. + + Note carefully that loop filtering must be skipped entirely if + loop_filter_level at either the frame header level or macroblock + override level is 0. In no case should the loop filter be run with a + value of 0; it should instead be skipped. + + We begin by discussing the aspects of loop filtering that are + independent of the controlling parameters and type of filter chosen. + + + + + + + + + +Bankoski, et al. Informational [Page 84] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +15.1. Filter Geometry and Overall Procedure + + The Y, U, and V planes are processed independently and identically. + + The loop filter acts on the edges between adjacent macroblocks and on + the edges between adjacent subblocks of a macroblock. All such edges + are horizontal or vertical. For each pixel position on an edge, a + small number (two or three) of pixels adjacent to either side of the + position are examined and possibly modified. The displacements of + these pixels are at a right angle to the edge orientation; that is, + for a horizontal edge, we treat the pixels immediately above and + below the edge position, and for a vertical edge, we treat the pixels + immediately to the left and right of the edge. + + We call this collection of pixels associated to an edge position a + segment; the length of a segment is 2, 4, 6, or 8. Excepting that + the normal filter uses slightly different algorithms for, and either + filter may apply different control parameters to, the edges between + macroblocks and those between subblocks, the treatment of edges is + quite uniform: All segments straddling an edge are treated + identically; there is no distinction between the treatment of + horizontal and vertical edges, whether between macroblocks or between + subblocks. + + As a consequence, adjacent subblock edges within a macroblock may be + concatenated and processed in their entirety. There is a single + 8-pixel-long vertical edge horizontally centered in each of the U and + V blocks (the concatenation of upper and lower 4-pixel edges between + chroma subblocks), and three 16-pixel-long vertical edges at + horizontal positions 1/4, 1/2, and 3/4 the width of the luma + macroblock, each representing the concatenation of four 4-pixel + sub-edges between pairs of Y subblocks. + + The macroblocks comprising the frame are processed in the usual + raster-scan order. Each macroblock is "responsible for" the + inter-macroblock edges immediately above and to the left of it (but + not the edges below and to the right of it), as well as the edges + between its subblocks. + + For each macroblock M, there are four filtering steps, which are, + (almost) in order: + + 1. If M is not on the leftmost column of macroblocks, filter across + the left (vertical) inter-macroblock edge of M. + + 2. Filter across the vertical subblock edges within M. + + + + + +Bankoski, et al. Informational [Page 85] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + 3. If M is not on the topmost row of macroblocks, filter across the + top (horizontal) inter-macroblock edge of M. + + 4. Filter across the horizontal subblock edges within M. + + We write MY, MU, and MV for the planar constituents of M, that is, + the 16x16 luma block, 8x8 U block, and 8x8 V block comprising M. + + In step 1, for each of the three blocks MY, MU, and MV, we filter + each of the (16 luma or 8 chroma) segments straddling the column + separating the block from the block immediately to the left of it, + using the inter-macroblock filter and controls associated to the + loop_filter_level and sharpness_level. + + In step 4, we filter across the (three luma and one each for U and V) + vertical subblock edges described above, this time using the + inter-subblock filter and controls. + + Steps 2 and 4 are skipped for macroblocks that satisfy both of the + following two conditions: + + 1. Macroblock coding mode is neither B_PRED nor SPLITMV; and + + 2. There is no DCT coefficient coded for the whole macroblock. + + For these macroblocks, loop filtering for edges between subblocks + internal to a macroblock is effectively skipped. This skip strategy + significantly reduces VP8 loop-filtering complexity. + + Edges between macroblocks and those between subblocks are treated + with different control parameters (and, in the case of the normal + filter, with different algorithms). Except for pixel addressing, + there is no distinction between the treatment of vertical and + horizontal edges. Luma edges are always 16 pixels long, chroma edges + are always 8 pixels long, and the segments straddling an edge are + treated identically; this of course facilitates vector processing. + + Because many pixels belong to segments straddling two or more edges, + and so will be filtered more than once, the order in which edges are + processed given above must be respected by any implementation. + Within a single edge, however, the segments straddling that edge are + disjoint, and the order in which these segments are processed is + immaterial. + + Before taking up the filtering algorithms themselves, we should + emphasize a point already made: Even though the pixel segments + associated to a macroblock are antecedent to the macroblock (that is, + lie within the macroblock or in already-constructed macroblocks), a + + + +Bankoski, et al. Informational [Page 86] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + macroblock must not be filtered immediately after its + "reconstruction" (described in Section 14). Rather, the loop filter + applies after all the macroblocks have been "reconstructed" (i.e., + had their predictor summed with their residue); correct decoding is + predicated on the fact that already-constructed portions of the + current frame referenced via intra-prediction (described in + Section 12) are not yet filtered. + +15.2. Simple Filter + + Having described the overall procedure of, and pixels affected by, + the loop filter, we turn our attention to the treatment of individual + segments straddling edges. We begin by describing the simple filter, + which, as the reader might guess, is somewhat simpler than the normal + filter. + + Note that the simple filter only applies to luma edges. Chroma edges + are left unfiltered. + + Roughly speaking, the idea of loop filtering is, within limits, to + reduce the difference between pixels straddling an edge. Differences + in excess of a threshold (associated to the loop_filter_level) are + assumed to be "natural" and are unmodified; differences below the + threshold are assumed to be artifacts of quantization and the + (partially) separate coding of blocks, and are reduced via the + procedures described below. While the loop_filter_level is in + principle arbitrary, the levels chosen by a VP8 compressor tend to be + correlated to quantizer levels. + + Most of the filtering arithmetic is done using 8-bit signed operands + (having a range of -128 to +127, inclusive), supplemented by 16-bit + temporaries holding results of multiplies. + + Sums and other temporaries need to be "clamped" to a valid signed + 8-bit range: + + ---- Begin code block -------------------------------------- + + int8 c(int v) + { + return (int8) (v < -128 ? -128 : (v < 128 ? v : 127)); + } + + ---- End code block ---------------------------------------- + + + + + + + +Bankoski, et al. Informational [Page 87] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + Since pixel values themselves are unsigned 8-bit numbers, we need to + convert between signed and unsigned values: + + ---- Begin code block -------------------------------------- + + /* Convert pixel value (0 <= v <= 255) to an 8-bit signed + number. */ + int8 u2s(Pixel v) { return (int8) (v - 128);} + + /* Clamp, then convert signed number back to pixel value. */ + Pixel s2u(int v) { return (Pixel) (c(v) + 128);} + + ---- End code block ---------------------------------------- + + Filtering is often predicated on absolute-value thresholds. The + following function is the equivalent of the standard library function + abs, whose prototype is found in the standard header file stdlib.h. + For us, the argument v is always the difference between two pixels + and lies in the range -255 <= v <= +255. + + ---- Begin code block -------------------------------------- + + int abs(int v) { return v < 0? -v : v;} + + ---- End code block ---------------------------------------- + + An actual implementation would of course use inline functions or + macros to accomplish these trivial procedures (which are used by both + the normal and simple loop filters). An optimal implementation would + probably express them in machine language, perhaps using single + instruction, multiple data (SIMD) vector instructions. On many SIMD + processors, the saturation accomplished by the above clamping + function is often folded into the arithmetic instructions themselves, + obviating the explicit step taken here. + + To simplify the specification of relative pixel positions, we use the + word "before" to mean "immediately above" (for a vertical segment + straddling a horizontal edge) or "immediately to the left of" (for a + horizontal segment straddling a vertical edge), and the word "after" + to mean "immediately below" or "immediately to the right of". + + Given an edge, a segment, and a limit value, the simple loop filter + computes a value based on the four pixels that straddle the edge (two + either side). If that value is below a supplied limit, then, very + roughly speaking, the two pixel values are brought closer to each + other, "shaving off" something like a quarter of the difference. The + + + + + +Bankoski, et al. Informational [Page 88] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + same procedure is used for all segments straddling any type of edge, + regardless of the nature (inter-macroblock, inter-subblock, luma, or + chroma) of the edge; only the limit value depends on the edge type. + + The exact procedure (for a single segment) is as follows; the + subroutine common_adjust is used by both the simple filter presented + here and the normal filters discussed in Section 15.3. + + ---- Begin code block -------------------------------------- + + int8 common_adjust( + int use_outer_taps, /* filter is 2 or 4 taps wide */ + const Pixel *P1, /* pixel before P0 */ + Pixel *P0, /* pixel before edge */ + Pixel *Q0, /* pixel after edge */ + const Pixel *Q1 /* pixel after Q0 */ + ) { + cint8 p1 = u2s(*P1); /* retrieve and convert all 4 pixels */ + cint8 p0 = u2s(*P0); + cint8 q0 = u2s(*Q0); + cint8 q1 = u2s(*Q1); + + /* Disregarding clamping, when "use_outer_taps" is false, + "a" is 3*(q0-p0). Since we are about to divide "a" by + 8, in this case we end up multiplying the edge + difference by 5/8. + + When "use_outer_taps" is true (as for the simple filter), + "a" is p1 - 3*p0 + 3*q0 - q1, which can be thought of as + a refinement of 2*(q0 - p0), and the adjustment is + something like (q0 - p0)/4. */ + + int8 a = c((use_outer_taps? c(p1 - q1) : 0) + 3*(q0 - p0)); + + /* b is used to balance the rounding of a/8 in the case where + the "fractional" part "f" of a/8 is exactly 1/2. */ + + cint8 b = (c(a + 3)) >> 3; + + /* Divide a by 8, rounding up when f >= 1/2. + Although not strictly part of the C language, + the right shift is assumed to propagate the sign bit. */ + + a = c(a + 4) >> 3; + + /* Subtract "a" from q0, "bringing it closer" to p0. */ + + *Q0 = s2u(q0 - a); + + + +Bankoski, et al. Informational [Page 89] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /* Add "a" (with adjustment "b") to p0, "bringing it closer" + to q0. + + The clamp of "a+b", while present in the reference decoder, + is superfluous; we have -16 <= a <= 15 at this point. */ + + *P0 = s2u(p0 + b); + + return a; + } + + ---- End code block ---------------------------------------- + + ---- Begin code block -------------------------------------- + + void simple_segment( + uint8 edge_limit, /* do nothing if edge difference + exceeds limit */ + const Pixel *P1, /* pixel before P0 */ + Pixel *P0, /* pixel before edge */ + Pixel *Q0, /* pixel after edge */ + const Pixel *Q1 /* pixel after Q0 */ + ) { + if ((abs(*P0 - *Q0)*2 + abs(*P1 - *Q1)/2) <= edge_limit)) + common_adjust(1, P1, P0, Q0, Q1); /* use outer taps */ + } + + ---- End code block ---------------------------------------- + + We make a couple of remarks about the rounding procedure above. When + b is zero (that is, when the "fractional part" of a is not 1/2), we + are (except for clamping) adding the same number to p0 as we are + subtracting from q0. This preserves the average value of p0 and q0, + but the resulting difference between p0 and q0 is always even; in + particular, the smallest non-zero gradation +-1 is not possible here. + + When b is one, the value we add to p0 (again except for clamping) is + one less than the value we are subtracting from q0. In this case, + the resulting difference is always odd (and the small gradation +-1 + is possible), but the average value is reduced by 1/2, yielding, for + instance, a very slight darkening in the luma plane. (In the very + unlikely event of appreciable darkening after a large number of + interframes, a compressor would of course eventually compensate for + this in the selection of predictor and/or residue.) + + + + + + + +Bankoski, et al. Informational [Page 90] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + The derivation of the edge_limit value used above, which depends on + the loop_filter_level and sharpness_level, as well as the type of + edge being processed, will be taken up after we describe the normal + loop filtering algorithm below. + +15.3. Normal Filter + + The normal loop filter is a refinement of the simple loop filter; all + of the general discussion above applies here as well. In particular, + the functions c, u2s, s2u, abs, and common_adjust are used by both + the normal and simple filters. + + As mentioned above, the normal algorithms for inter-macroblock and + inter-subblock edges differ. Nonetheless, they have a great deal in + common: They use similar threshold algorithms to disable the filter + and to detect high internal edge variance (which influences the + filtering algorithm). Both algorithms also use, at least + conditionally, the simple filter adjustment procedure described + above. + + The common thresholding algorithms are as follows. + + ---- Begin code block -------------------------------------- + + /* All functions take (among other things) a segment (of length + at most 4 + 4 = 8) symmetrically straddling an edge. + + The pixel values (or pointers) are always given in order, + from the "beforemost" to the "aftermost". So, for a + horizontal edge (written "|"), an 8-pixel segment would be + ordered p3 p2 p1 p0 | q0 q1 q2 q3. */ + + /* Filtering is disabled if the difference between any two + adjacent "interior" pixels in the 8-pixel segment exceeds + the relevant threshold (I). A more complex thresholding + calculation is done for the group of four pixels that + straddle the edge, in line with the calculation in + simple_segment() above. */ + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 91] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + int filter_yes( + uint8 I, /* limit on interior differences */ + uint8 E, /* limit at the edge */ + + cint8 p3, cint8 p2, cint8 p1, cint8 p0, /* pixels before + edge */ + cint8 q0, cint8 q1, cint8 q2, cint8 q3 /* pixels after + edge */ + ) { + return (abs(p0 - q0)*2 + abs(p1 - q1)/2) <= E + && abs(p3 - p2) <= I && abs(p2 - p1) <= I && + abs(p1 - p0) <= I + && abs(q3 - q2) <= I && abs(q2 - q1) <= I && + abs(q1 - q0) <= I; + } + + ---- End code block ---------------------------------------- + + ---- Begin code block -------------------------------------- + + /* Filtering is altered if (at least) one of the differences + on either side of the edge exceeds a threshold (we have + "high edge variance"). */ + + int hev( + uint8 threshold, + cint8 p1, cint8 p0, /* pixels before edge */ + cint8 q0, cint8 q1 /* pixels after edge */ + ) { + return abs(p1 - p0) > threshold || abs(q1 - q0) > threshold; + } + + ---- End code block ---------------------------------------- + + The subblock filter is a variant of the simple filter. In fact, if + we have high edge variance, the adjustment is exactly as for the + simple filter. Otherwise, the simple adjustment (without outer taps) + is applied, and the two pixels one step in from the edge pixels are + adjusted by roughly half the amount by which the two edge pixels are + adjusted; since the edge adjustment here is essentially 3/8 the edge + difference, the inner adjustment is approximately 3/16 the edge + difference. + + + + + + + + + +Bankoski, et al. Informational [Page 92] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + ---- Begin code block -------------------------------------- + + void subblock_filter( + uint8 hev_threshold, /* detect high edge variance */ + uint8 interior_limit, /* possibly disable filter */ + uint8 edge_limit, + cint8 *P3, cint8 *P2, int8 *P1, int8 *P0, /* pixels before + edge */ + int8 *Q0, int8 *Q1, cint8 *Q2, cint8 *Q3 /* pixels after + edge */ + ) { + cint8 p3 = u2s(*P3), p2 = u2s(*P2), p1 = u2s(*P1), + p0 = u2s(*P0); + cint8 q0 = u2s(*Q0), q1 = u2s(*Q1), q2 = u2s(*Q2), + q3 = u2s(*Q3); + + if (filter_yes(interior_limit, edge_limit, q3, q2, q1, q0, + p0, p1, p2, p3)) + { + const int hv = hev(hev_threshold, p1, p0, q0, q1); + + cint8 a = (common_adjust(hv, P1, P0, Q0, Q1) + 1) >> 1; + + if (!hv) { + *Q1 = s2u(q1 - a); + *P1 = s2u(p1 + a); + } + } + } + + ---- End code block ---------------------------------------- + + The inter-macroblock filter has potentially wider scope. If the edge + variance is high, it performs the simple adjustment (using the outer + taps, just like the simple filter and the corresponding case of the + normal subblock filter). If the edge variance is low, we begin with + the same basic filter calculation and apply multiples of it to pixel + pairs symmetric about the edge; the magnitude of adjustment decays as + we move away from the edge and six of the pixels in the segment are + affected. + + + + + + + + + + + +Bankoski, et al. Informational [Page 93] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + ---- Begin code block -------------------------------------- + + void MBfilter( + uint8 hev_threshold, /* detect high edge variance */ + uint8 interior_limit, /* possibly disable filter */ + uint8 edge_limit, + cint8 *P3, int8 *P2, int8 *P1, int8 *P0, /* pixels before + edge */ + int8 *Q0, int8 *Q1, int8 *Q2, cint8 *Q3 /* pixels after + edge */ + ) { + cint8 p3 = u2s(*P3), p2 = u2s(*P2), p1 = u2s(*P1), + p0 = u2s(*P0); + cint8 q0 = u2s(*Q0), q1 = u2s(*Q1), q2 = u2s(*Q2), + q3 = u2s(*Q3); + + if (filter_yes(interior_limit, edge_limit, q3, q2, q1, q0, + p0, p1, p2, p3)) + { + if (!hev(hev_threshold, p1, p0, q0, q1)) + { + /* Same as the initial calculation in "common_adjust", + w is something like twice the edge difference */ + + const int8 w = c(c(p1 - q1) + 3*(q0 - p0)); + + /* 9/64 is approximately 9/63 = 1/7, and 1<<7 = 128 = + 2*64. So this a, used to adjust the pixels adjacent + to the edge, is something like 3/7 the edge + difference. */ + + int8 a = c((27*w + 63) >> 7); + + *Q0 = s2u(q0 - a); *P0 = s2u(p0 + a); + + /* Next two are adjusted by 2/7 the edge difference */ + + a = c((18*w + 63) >> 7); + + *Q1 = s2u(q1 - a); *P1 = s2u(p1 + a); + + /* Last two are adjusted by 1/7 the edge difference */ + + a = c((9*w + 63) >> 7); + + *Q2 = s2u(q2 - a); *P2 = s2u(p2 + a); + + + + + +Bankoski, et al. Informational [Page 94] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + } else /* if hev, do simple filter */ + common_adjust(1, P1, P0, Q0, Q1); /* using outer + taps */ + } + } + + ---- End code block ---------------------------------------- + +15.4. Calculation of Control Parameters + + We conclude the discussion of loop filtering by showing how the + thresholds supplied to the procedures above are derived from the two + control parameters sharpness_level (an unsigned 3-bit number having + maximum value 7) and loop_filter_level (an unsigned 6-bit number + having maximum value 63). + + While the sharpness_level is constant over the frame, individual + macroblocks may override the loop_filter_level with one of four + possibilities supplied in the frame header (as described in + Section 10). + + Both the simple and normal filters disable filtering if a value + derived from the four pixels that straddle the edge (2 either side) + exceeds a threshold / limit value. + + ---- Begin code block -------------------------------------- + + /* Luma and Chroma use the same inter-macroblock edge limit */ + uint8 mbedge_limit = ((loop_filter_level + 2) * 2) + + interior_limit; + + /* Luma and Chroma use the same inter-subblock edge limit */ + uint8 sub_bedge_limit = (loop_filter_level * 2) + interior_limit; + + ---- End code block ---------------------------------------- + + The remaining thresholds are used only by the normal filters. The + filter-disabling interior difference limit is the same for all edges + (luma, chroma, inter-subblock, inter-macroblock) and is given by the + following. + + + + + + + + + + + +Bankoski, et al. Informational [Page 95] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + ---- Begin code block -------------------------------------- + + uint8 interior_limit = loop_filter_level; + + if (sharpness_level) + { + interior_limit >>= sharpness_level > 4 ? 2 : 1; + if (interior_limit > 9 - sharpness_level) + interior_limit = 9 - sharpness_level; + } + if (!interior_limit) + interior_limit = 1; + + ---- End code block ---------------------------------------- + + Finally, we give the derivation of the high edge-variance threshold, + which is also the same for all edge types. + + ---- Begin code block -------------------------------------- + + uint8 hev_threshold = 0; + + if (we_are_decoding_akey_frame) /* current frame is a key frame */ + { + if (loop_filter_level >= 40) + hev_threshold = 2; + else if (loop_filter_level >= 15) + hev_threshold = 1; + } + else /* current frame is an interframe */ + { + if (loop_filter_level >= 40) + hev_threshold = 3; + else if (loop_filter_level >= 20) + hev_threshold = 2; + else if (loop_filter_level >= 15) + hev_threshold = 1; + } + + ---- End code block ---------------------------------------- + + + + + + + + + + + +Bankoski, et al. Informational [Page 96] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +16. Interframe Macroblock Prediction Records + + We describe the layout and semantics of the prediction records for + macroblocks in an interframe. + + After the feature specification (which is described in Section 10 and + is identical for intraframes and interframes), there comes a + Bool(prob_intra), which indicates inter-prediction (i.e., prediction + from prior frames) when true and intra-prediction (i.e., prediction + from already-coded portions of the current frame) when false. The + zero-probability prob_intra is set by field J of the frame header. + +16.1. Intra-Predicted Macroblocks + + For intra-prediction, the layout of the prediction data is + essentially the same as the layout for key frames, although the + contexts used by the decoding process are slightly different. + + As discussed in Section 8, the "outer" Y mode here uses a different + tree from that used in key frames, repeated here for convenience. + + ---- Begin code block -------------------------------------- + + const tree_index ymode_tree [2 * (num_ymodes - 1)] = + { + -DC_PRED, 2, /* root: DC_PRED = "0", "1" subtree */ + 4, 6, /* "1" subtree has 2 descendant subtrees */ + -V_PRED, -H_PRED, /* "10" subtree: V_PRED = "100", + H_PRED = "101" */ + -TM_PRED, -B_PRED /* "11" subtree: TM_PRED = "110", + B_PRED = "111" */ + }; + + ---- End code block ---------------------------------------- + + The probability table used to decode this tree is variable. As + described in Section 11, it (along with the similarly treated UV + table) can be updated by field J of the frame header. Similar to the + coefficient-decoding probabilities, such updates are cumulative and + affect all ensuing frames until the next key frame or explicit + update. The default probabilities for the Y and UV tables are: + + ---- Begin code block -------------------------------------- + + Prob ymode_prob [num_ymodes - 1] = { 112, 86, 140, 37}; + Prob uv_mode_prob [num_uv_modes - 1] = { 162, 101, 204}; + + ---- End code block ---------------------------------------- + + + +Bankoski, et al. Informational [Page 97] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + These defaults must be restored after detection of a key frame. + + Just as for key frames, if the Y mode is B_PRED, there next comes an + encoding of the intra_bpred mode used by each of the sixteen Y + subblocks. These encodings use the same tree as does that for key + frames but, in place of the contexts used in key frames, these + encodings use the single fixed probability table. + + ---- Begin code block -------------------------------------- + + const Prob bmode_prob [num_intra_bmodes - 1] = { + 120, 90, 79, 133, 87, 85, 80, 111, 151 + }; + + ---- End code block ---------------------------------------- + + Last comes the chroma mode, again coded using the same tree as that + used for key frames, this time using the dynamic uv_mode_prob table + described above. + + The calculation of the intra-prediction buffer is identical to that + described for key frames in Section 12. + +16.2. Inter-Predicted Macroblocks + + 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. + + + + + + + + +Bankoski, et al. Informational [Page 98] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + 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. + + ---- Begin code block -------------------------------------- + + 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" */ + }; + + ---- End code block ---------------------------------------- + +16.3. Mode and Motion Vector Contexts + + The probability table used to decode the mv_ref, along with three + reference motion vectors used by the selected mode, is calculated via + a survey of the already-decoded motion vectors in (up to) 3 nearby + macroblocks. + + The algorithm generates a sorted list of distinct motion vectors + adjacent to the search site. The best_mv is the vector with the + highest score. The mv_nearest is the non-zero vector with the + highest score. The mv_near is the non-zero vector with the next + highest score. The number of motion vectors coded using the SPLITMV + mode is scored using the same weighting and is returned with the + scores of the best, nearest, and near vectors. + + + + + +Bankoski, et al. Informational [Page 99] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + The three adjacent macroblocks above, left, and above-left are + considered in order. If the macroblock is intra-coded, no action is + taken. Otherwise, the motion vector is compared to other previously + found motion vectors to determine if it has been seen before, and if + so contributes its weight to that vector; otherwise, it enters a new + vector in the list. The above and left vectors have twice the weight + of the above-left vector. + + As is the case with many contexts used by VP8, it is possible for + macroblocks near the top or left edges of the image to reference + blocks that are outside the visible image. VP8 provides a border of + 1 macroblock filled with 0x0 motion vectors left of the left edge, + and a border filled with 0,0 motion vectors of 1 macroblocks above + the top edge. + + Much of the process is more easily described in C than in English. + The reference code for this can be found in modemv.c (Section 20.11). + The calculation of reference vectors, probability table, and, + finally, the inter-prediction mode itself is implemented as follows. + + ---- Begin code block -------------------------------------- + + typedef union + { + unsigned int as_int; + MV as_mv; + } int_mv; /* facilitates rapid equality tests */ + + + static void mv_bias(MODE_INFO *x,int refframe, int_mv *mvp, + int * ref_frame_sign_bias) + { + MV xmv; + xmv = x->mbmi.mv.as_mv; + if ( ref_frame_sign_bias[x->mbmi.ref_frame] != + ref_frame_sign_bias[refframe] ) + { + xmv.row*=-1; + xmv.col*=-1; + } + mvp->as_mv = xmv; + } + + ---- End code block ---------------------------------------- + + + + + + + +Bankoski, et al. Informational [Page 100] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + ---- Begin code block -------------------------------------- + + void vp8_clamp_mv(MV *mv, const MACROBLOCKD *xd) + { + if ( mv->col < (xd->mb_to_left_edge - LEFT_TOP_MARGIN) ) + mv->col = xd->mb_to_left_edge - LEFT_TOP_MARGIN; + else if ( mv->col > xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN ) + mv->col = xd->mb_to_right_edge + RIGHT_BOTTOM_MARGIN; + + if ( mv->row < (xd->mb_to_top_edge - LEFT_TOP_MARGIN) ) + mv->row = xd->mb_to_top_edge - LEFT_TOP_MARGIN; + else if ( mv->row > xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN ) + mv->row = xd->mb_to_bottom_edge + RIGHT_BOTTOM_MARGIN; + } + + ---- End code block ---------------------------------------- + + In the function vp8_find_near_mvs(), the vectors "nearest" and "near" + are used by the corresponding modes. + + The vector best_mv is used as a base for explicitly coded motion + vectors. + + The first three entries in the return value cnt are (in order) + weighted census values for "zero", "nearest", and "near" vectors. + The final value indicates the extent to which SPLITMV was used by the + neighboring macroblocks. The largest possible "weight" value in each + case is 5. + + ---- Begin code block -------------------------------------- + + void vp8_find_near_mvs + ( + MACROBLOCKD *xd, + const MODE_INFO *here, + MV *nearest, + MV *near, + MV *best_mv, + int cnt[4], + int refframe, + int * ref_frame_sign_bias + ) + + + + + + + + + +Bankoski, et al. Informational [Page 101] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + { + const MODE_INFO *above = here - xd->mode_info_stride; + const MODE_INFO *left = here - 1; + const MODE_INFO *aboveleft = above - 1; + int_mv near_mvs[4]; + int_mv *mv = near_mvs; + int *cntx = cnt; + enum {CNT_ZERO, CNT_NEAREST, CNT_NEAR, CNT_SPLITMV}; + + /* Zero accumulators */ + mv[0].as_int = mv[1].as_int = mv[2].as_int = 0; + cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0; + + /* Process above */ + if (above->mbmi.ref_frame != INTRA_FRAME) { + if (above->mbmi.mv.as_int) { + (++mv)->as_int = above->mbmi.mv.as_int; + mv_bias(above, refframe, mv, ref_frame_sign_bias); + ++cntx; + } + *cntx += 2; + } + + /* Process left */ + if (left->mbmi.ref_frame != INTRA_FRAME) { + if (left->mbmi.mv.as_int) { + int_mv this_mv; + + this_mv.as_int = left->mbmi.mv.as_int; + mv_bias(left, refframe, &this_mv, ref_frame_sign_bias); + + if (this_mv.as_int != mv->as_int) { + (++mv)->as_int = this_mv.as_int; + ++cntx; + } + *cntx += 2; + } else + cnt[CNT_ZERO] += 2; + } + + /* Process above left */ + if (aboveleft->mbmi.ref_frame != INTRA_FRAME) { + if (aboveleft->mbmi.mv.as_int) { + int_mv this_mv; + + this_mv.as_int = aboveleft->mbmi.mv.as_int; + mv_bias(aboveleft, refframe, &this_mv, + ref_frame_sign_bias); + + + +Bankoski, et al. Informational [Page 102] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + if (this_mv.as_int != mv->as_int) { + (++mv)->as_int = this_mv.as_int; + ++cntx; + } + *cntx += 1; + } else + cnt[CNT_ZERO] += 1; + } + + /* If we have three distinct MVs ... */ + if (cnt[CNT_SPLITMV]) { + /* See if above-left MV can be merged with NEAREST */ + if (mv->as_int == near_mvs[CNT_NEAREST].as_int) + cnt[CNT_NEAREST] += 1; + } + + cnt[CNT_SPLITMV] = ((above->mbmi.mode == SPLITMV) + + (left->mbmi.mode == SPLITMV)) * 2 + + (aboveleft->mbmi.mode == SPLITMV); + + /* Swap near and nearest if necessary */ + if (cnt[CNT_NEAR] > cnt[CNT_NEAREST]) { + int tmp; + tmp = cnt[CNT_NEAREST]; + cnt[CNT_NEAREST] = cnt[CNT_NEAR]; + cnt[CNT_NEAR] = tmp; + tmp = near_mvs[CNT_NEAREST].as_int; + near_mvs[CNT_NEAREST].as_int = near_mvs[CNT_NEAR].as_int; + near_mvs[CNT_NEAR].as_int = tmp; + } + + /* Use near_mvs[0] to store the "best" MV */ + if (cnt[CNT_NEAREST] >= cnt[CNT_ZERO]) + near_mvs[CNT_ZERO] = near_mvs[CNT_NEAREST]; + + /* Set up return values */ + *best_mv = near_mvs[0].as_mv; + *nearest = near_mvs[CNT_NEAREST].as_mv; + *near = near_mvs[CNT_NEAR].as_mv; + + vp8_clamp_mv(nearest, xd); + vp8_clamp_mv(near, xd); + vp8_clamp_mv(best_mv, xd); //TODO: Move this up before + the copy + } + + ---- End code block ---------------------------------------- + + + + +Bankoski, et al. Informational [Page 103] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + The mv_ref probability table (mv_ref_p) is then derived from the + census as follows. + + ---- Begin code block -------------------------------------- + + const int vp8_mode_contexts[6][4] = + { + { 7, 1, 1, 143, }, + { 14, 18, 14, 107, }, + { 135, 64, 57, 68, }, + { 60, 56, 128, 65, }, + { 159, 134, 128, 34, }, + { 234, 188, 128, 28, }, + } + + ---- End code block ---------------------------------------- + + ---- Begin code block -------------------------------------- + + vp8_prob *vp8_mv_ref_probs(vp8_prob mv_ref_p[VP8_MVREFS-1], + int cnt[4]) + { + mv_ref_p[0] = vp8_mode_contexts [cnt[0]] [0]; + mv_ref_p[1] = vp8_mode_contexts [cnt[1]] [1]; + mv_ref_p[2] = vp8_mode_contexts [cnt[2]] [2]; + mv_ref_p[3] = vp8_mode_contexts [cnt[3]] [3]; + return p; + } + + ---- End code block ---------------------------------------- + + Once mv_ref_p is established, the mv_ref is decoded as usual. + + ---- Begin code block -------------------------------------- + + mvr = (mv_ref) treed_read(d, mv_ref_tree, mv_ref_p); + + ---- End code block ---------------------------------------- + + For the first four inter-coding modes, the same motion vector is used + for all the Y subblocks. The first three modes use an implicit + motion vector. + + + + + + + + + +Bankoski, et al. Informational [Page 104] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + +------------+------------------------------------------------------+ + | Mode | Instruction | + +------------+------------------------------------------------------+ + | mv_nearest | Use the nearest vector returned by | + | | vp8_find_near_mvs. | + | | | + | mv_near | Use the near vector returned by vp8_find_near_mvs. | + | | | + | mv_zero | Use a zero vector; that is, predict the current | + | | macroblock from the corresponding macroblock in the | + | | prediction frame. | + | | | + | NEWMV | This mode is followed by an explicitly coded motion | + | | vector (the format of which is described in the next | + | | section) that is added (component-wise) to the | + | | best_mv reference vector returned by find_near_mvs | + | | and applied to all 16 subblocks. | + +------------+------------------------------------------------------+ + +16.4. Split Prediction + + 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. + + ---- Begin code block -------------------------------------- + + 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; + + + + + + + + + +Bankoski, et al. Informational [Page 105] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + 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" */ + }; + + ---- End code block ---------------------------------------- + + The partition is decoded using a fixed, constant probability table: + + ---- Begin code block -------------------------------------- + + const Prob mvpartition_probs [mvnum_partition - 1] = + { 110, 111, 150}; + part = (MVpartition) treed_read(d, mvpartition_tree, + mvpartition_probs); + + ---- End code block ---------------------------------------- + + 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. + + ---- Begin code block -------------------------------------- + + 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; + + + + +Bankoski, et al. Informational [Page 106] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + 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 neighbor + is zero */ + int aez = (a->row == 0 && a->col == 0); /* above neighbor + is zero */ + int lea = (l->row == a->row && l->col == a->col); /* left + neighbor equals above neighbor */ + + 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]); + + ---- End code block ---------------------------------------- + + + +Bankoski, et al. Informational [Page 107] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + 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 that NEW4x4 is applied only to + the current subset. It is followed by a two-dimensional motion + vector offset (described in the next section) 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 modemv.c + (Section 20.11). + +17. Motion Vector Decoding + + As discussed above, motion vectors appear in two places in the VP8 + datastream: applied to whole macroblocks in NEWMV mode and applied to + subsets of macroblocks in NEW4x4 mode. The format of the vectors is + identical in both cases. + + Each vector has two pieces: a vertical component (row) followed by a + horizontal component (column). The row and column use separate + coding probabilities but are otherwise represented identically. + +17.1. Coding of Each Component + + Each component is a signed integer V representing a vertical or + horizontal luma displacement of V quarter-pixels (and a chroma + displacement of V eighth-pixels). The absolute value of V, if + non-zero, is followed by a boolean sign. V may take any value + between -1023 and +1023, inclusive. + + + + + + + + +Bankoski, et al. Informational [Page 108] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + The absolute value A is coded in one of two different ways according + to its size. For 0 <= A <= 7, A is tree-coded, and for 8 <= A <= + 1023, the bits in the binary expansion of A are coded using + independent boolean probabilities. The coding of A begins with a + bool specifying which range is in effect. + + Decoding a motion vector component then requires a 19-position + probability table, whose offsets, along with the procedure used to + decode components, are as follows: + + ---- Begin code block -------------------------------------- + + typedef enum + { + mvpis_short, /* short (<= 7) vs long (>= 8) */ + MVPsign, /* sign for non-zero */ + MVPshort, /* 8 short values = 7-position tree */ + + MVPbits = MVPshort + 7, /* 8 long value bits + w/independent probs */ + + MVPcount = MVPbits + 10 /* 19 probabilities in total */ + } + MVPindices; + + typedef Prob MV_CONTEXT [MVPcount]; /* Decoding spec for + a single component */ + + /* Tree used for small absolute values (has expected + correspondence). */ + + const tree_index small_mvtree [2 * (8 - 1)] = + { + 2, 8, /* "0" subtree, "1" subtree */ + 4, 6, /* "00" subtree, "01" subtree */ + -0, -1, /* 0 = "000", 1 = "001" */ + -2, -3, /* 2 = "010", 3 = "011" */ + 10, 12, /* "10" subtree, "11" subtree */ + -4, -5, /* 4 = "100", 5 = "101" */ + -6, -7 /* 6 = "110", 7 = "111" */ + }; + + /* Read MV component at current decoder position, using + supplied probs. */ + + int read_mvcomponent(bool_decoder *d, const MV_CONTEXT *mvc) + { + const Prob * const p = (const Prob *) mvc; + + + +Bankoski, et al. Informational [Page 109] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + int A = 0; + + if (read_bool(d, p [mvpis_short])) /* 8 <= A <= 1023 */ + { + /* Read bits 0, 1, 2 */ + + int i = 0; + do { A += read_bool(d, p [MVPbits + i]) << i;} + while (++i < 3); + + /* Read bits 9, 8, 7, 6, 5, 4 */ + + i = 9; + do { A += read_bool(d, p [MVPbits + i]) << i;} + while (--i > 3); + + /* We know that A >= 8 because it is coded long, + so if A <= 15, bit 3 is one and is not + explicitly coded. */ + + if (!(A & 0xfff0) || read_bool(d, p [MVPbits + 3])) + A += 8; + } + else /* 0 <= A <= 7 */ + A = treed_read(d, small_mvtree, p + MVPshort); + + return A && read_bool(r, p [MVPsign]) ? -A : A; + } + + ---- End code block ---------------------------------------- + +17.2. Probability Updates + + The decoder should maintain an array of two MV_CONTEXTs for decoding + row and column components, respectively. These MV_CONTEXTs should be + set to their defaults every key frame. Each individual probability + may be updated every interframe (by field J of the frame header) + using a constant table of update probabilities. Each optional update + is of the form B? P(7), that is, a bool followed by a 7-bit + probability specification if true. + + As with other dynamic probabilities used by VP8, the updates remain + in effect until the next key frame or until replaced via another + update. + + + + + + + +Bankoski, et al. Informational [Page 110] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + In detail, the probabilities should then be managed as follows. + + ---- Begin code block -------------------------------------- + + /* Never-changing table of update probabilities for each + individual probability used in decoding motion vectors. */ + + const MV_CONTEXT vp8_mv_update_probs[2] = + { + { + 237, + 246, + 253, 253, 254, 254, 254, 254, 254, + 254, 254, 254, 254, 254, 250, 250, 252, 254, 254 + }, + { + 231, + 243, + 245, 253, 254, 254, 254, 254, 254, + 254, 254, 254, 254, 254, 251, 251, 254, 254, 254 + } + }; + + /* Default MV decoding probabilities. */ + + const MV_CONTEXT default_mv_context[2] = + { + { // row + 162, // is short + 128, // sign + 225, 146, 172, 147, 214, 39, 156, // short tree + 128, 129, 132, 75, 145, 178, 206, 239, 254, 254 // long bits + }, + + { // same for column + 164, // is short + 128, + 204, 170, 119, 235, 140, 230, 228, + 128, 130, 130, 74, 148, 180, 203, 236, 254, 254 // long bits + + } + }; + + /* Current MV decoding probabilities, set to above defaults + every key frame. */ + + MV_CONTEXT mvc [2]; /* always row, then column */ + + + + +Bankoski, et al. Informational [Page 111] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /* Procedure for decoding a complete motion vector. */ + + typedef struct { int16 row, col;} MV; /* as in previous section */ + + MV read_mv(bool_decoder *d) + { + MV v; + v.row = (int16) read_mvcomponent(d, mvc); + v.col = (int16) read_mvcomponent(d, mvc + 1); + return v; + } + + /* Procedure for updating MV decoding probabilities, called + every interframe with "d" at the appropriate position in + the frame header. */ + + void update_mvcontexts(bool_decoder *d) + { + int i = 0; + do { /* component = row, then column */ + const Prob *up = mv_update_probs[i]; /* update probs + for component */ + Prob *p = mvc[i]; /* start decode tbl "" */ + Prob * const pstop = p + MVPcount; /* end decode tbl "" */ + do { + if (read_bool(d, *up++)) /* update this position */ + { + const Prob x = read_literal(d, 7); + + *p = x? x<<1 : 1; + } + } while (++p < pstop); /* next position */ + } while (++i < 2); /* next component */ + } + + ---- End code block ---------------------------------------- + + This completes the description of the motion-vector decoding + procedure and, with it, the procedure for decoding interframe + macroblock prediction records. + + + + + + + + + + + +Bankoski, et al. Informational [Page 112] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +18. Interframe Prediction + + Given an inter-prediction specification for the current macroblock, + that is, a reference frame together with a motion vector for each of + the sixteen Y subblocks, we describe the calculation of the + prediction buffer for the macroblock. Frame reconstruction is then + completed via the previously described processes of residue summation + (Section 14) and loop filtering (Section 15). + + The management of inter-predicted subblocks and sub-pixel + interpolation may be found in the reference decoder file predict.c + (Section 20.14). + +18.1. Bounds on, and Adjustment of, Motion Vectors + + Since each motion vector is differentially encoded from a neighboring + block or macroblock and the only clamp is to ensure that the + referenced motion vector represents a valid location inside a + reference frame buffer, it is technically possible within the VP8 + format for a block or macroblock to have arbitrarily large motion + vectors, up to the size of the input image plus the extended border + areas. For practical reasons, VP8 imposes a motion vector size range + limit of -4096 to 4095 full pixels, regardless of image size (VP8 + defines 14 raw bits for width and height; 16383x16383 is the maximum + possible image size). Bitstream-compliant encoders and decoders + shall enforce this limit. + + Because the motion vectors applied to the chroma subblocks have + 1/8-pixel resolution, the synthetic pixel calculation, outlined in + Section 5 and detailed below, uses this resolution for the luma + subblocks as well. In accordance, the stored luma motion vectors are + all doubled, each component of each luma vector becoming an even + integer in the range -2046 to +2046, inclusive. + + The vector applied to each chroma subblock is calculated by averaging + the vectors for the 4 luma subblocks occupying the same visible area + as the chroma subblock in the usual correspondence; that is, the + vector for U and V block 0 is the average of the vectors for the Y + subblocks { 0, 1, 4, 5}, chroma block 1 corresponds to Y blocks { 2, + 3, 6, 7}, chroma block 2 to Y blocks { 8, 9, 12, 13}, and chroma + block 3 to Y blocks { 10, 11, 14, 15}. + + + + + + + + + + +Bankoski, et al. Informational [Page 113] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + In detail, each of the two components of the vectors for each of the + chroma subblocks is calculated from the corresponding luma vector + components as follows: + + ---- Begin code block -------------------------------------- + + int avg(int c1, int c2, int c3, int c4) + { + int s = c1 + c2 + c3 + c4; + + /* The shift divides by 8 (not 4) because chroma pixels + have twice the diameter of luma pixels. The handling + of negative motion vector components is slightly + cumbersome because, strictly speaking, right shifts + of negative numbers are not well-defined in C. */ + + return s >= 0 ? (s + 4) >> 3 : -((-s + 4) >> 3); + } + + ---- End code block ---------------------------------------- + + Furthermore, if the version number in the frame tag specifies only + full-pel chroma motion vectors, then the fractional parts of both + components of the vector are truncated to zero, as illustrated in the + following pseudocode (assuming 3 bits of fraction for both luma and + chroma vectors): + + ---- Begin code block -------------------------------------- + + x = x & (~7); + y = y & (~7); + + ---- End code block ---------------------------------------- + + Earlier in this document we described the vp8_clamp_mv() function to + limit "nearest" and "near" motion vector predictors inside specified + margins within the frame boundaries. Additional clamping is + performed for NEWMV macroblocks, for which the final motion vector is + clamped again after combining the "best" predictor and the + differential vector decoded from the stream. + + However, the secondary clamping is not performed for SPLITMV + macroblocks, meaning that any subblock's motion vector within the + SPLITMV macroblock may point outside the clamping zone. These + non-clamped vectors are also used when determining the decoding tree + context for subsequent subblocks' modes in the vp8_mvCont() function. + + + + + +Bankoski, et al. Informational [Page 114] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +18.2. Prediction Subblocks + + The prediction calculation for each subblock is then as follows. + Temporarily disregarding the fractional part of the motion vector + (that is, rounding "up" or "left" by right-shifting each component + 3 bits with sign propagation) and adding the origin (upper left + position) of the (16x16 luma or 8x8 chroma) current macroblock gives + us an origin in the Y, U, or V plane of the predictor frame (either + the golden frame or previous frame). + + Considering that origin to be the upper left corner of a (luma or + chroma) macroblock, we need to specify the relative positions of the + pixels associated to that subblock, that is, any pixels that might be + involved in the sub-pixel interpolation processes for the subblock. + +18.3. Sub-Pixel Interpolation + + The sub-pixel interpolation is effected via two one-dimensional + convolutions. These convolutions may be thought of as operating on a + two-dimensional array of pixels whose origin is the subblock origin, + that is the origin of the prediction macroblock described above plus + the offset to the subblock. Because motion vectors are arbitrary, so + are these "prediction subblock origins". + + The integer part of the motion vector is subsumed in the origin of + the prediction subblock; the 16 (synthetic) pixels we need to + construct are given by 16 offsets from the origin. The integer part + of each of these offsets is the offset of the corresponding pixel + from the subblock origin (using the vertical stride). To these + integer parts is added a constant fractional part, which is simply + the difference between the actual motion vector and its integer + truncation used to calculate the origins of the prediction macroblock + and subblock. Each component of this fractional part is an integer + between 0 and 7, representing a forward displacement in eighths of a + pixel. + + It is these fractional displacements that determine the filtering + process. If they both happen to be zero (that is, we had a "whole + pixel" motion vector), the prediction subblock is simply copied into + the corresponding piece of the current macroblock's prediction + buffer. As discussed in Section 14, the layout of the macroblock's + prediction buffer can depend on the specifics of the reconstruction + implementation chosen. Of course, the vertical displacement between + lines of the prediction subblock is given by the stride, as are all + vertical displacements used here. + + + + + + +Bankoski, et al. Informational [Page 115] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + Otherwise, at least one of the fractional displacements is non-zero. + We then synthesize the missing pixels via a horizontal, followed by a + vertical, one-dimensional interpolation. + + The two interpolations are essentially identical. Each uses a (at + most) six-tap filter (the choice of which of course depends on the + one-dimensional offset). Thus, every calculated pixel references at + most three pixels before (above or to the left of) it and at most + three pixels after (below or to the right of) it. The horizontal + interpolation must calculate two extra rows above and three extra + rows below the 4x4 block, to provide enough samples for the vertical + interpolation to proceed. + + Depending on the reconstruction filter type given in the version + number field in the frame tag, either a bicubic or a bilinear tap set + is used. + + The exact implementation of subsampling is as follows. + + ---- Begin code block -------------------------------------- + + /* Filter taps taken to 7-bit precision. + Because DC is always passed, taps always sum to 128. */ + + const int BilinearFilters[8][6] = + { + { 0, 0, 128, 0, 0, 0 }, + { 0, 0, 112, 16, 0, 0 }, + { 0, 0, 96, 32, 0, 0 }, + { 0, 0, 80, 48, 0, 0 }, + { 0, 0, 64, 64, 0, 0 }, + { 0, 0, 48, 80, 0, 0 }, + { 0, 0, 32, 96, 0, 0 }, + { 0, 0, 16, 112, 0, 0 } + }; + + const int filters [8] [6] = { /* indexed by displacement */ + { 0, 0, 128, 0, 0, 0 }, /* degenerate whole-pixel */ + { 0, -6, 123, 12, -1, 0 }, /* 1/8 */ + { 2, -11, 108, 36, -8, 1 }, /* 1/4 */ + { 0, -9, 93, 50, -6, 0 }, /* 3/8 */ + { 3, -16, 77, 77, -16, 3 }, /* 1/2 is symmetric */ + { 0, -6, 50, 93, -9, 0 }, /* 5/8 = reverse of 3/8 */ + { 1, -8, 36, 108, -11, 2 }, /* 3/4 = reverse of 1/4 */ + { 0, -1, 12, 123, -6, 0 } /* 7/8 = reverse of 1/8 */ + }; + + + + + +Bankoski, et al. Informational [Page 116] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /* One-dimensional synthesis of a single sample. + Filter is determined by fractional displacement */ + + Pixel interp( + const int fil[6], /* filter to apply */ + const Pixel *p, /* origin (rounded "before") in + prediction area */ + const int s /* size of one forward step "" */ + ) { + int32 a = 0; + int i = 0; + p -= s + s; /* move back two positions */ + + do { + a += *p * fil[i]; + p += s; + } while (++i < 6); + + return clamp255((a + 64) >> 7); /* round to nearest + 8-bit value */ + } + + + /* First do horizontal interpolation, producing intermediate + buffer. */ + + void Hinterp( + Pixel temp[9][4], /* 9 rows of 4 (intermediate) + destination values */ + const Pixel *p, /* subblock origin in prediction + frame */ + int s, /* vertical stride to be used in + prediction frame */ + uint hfrac, /* 0 <= horizontal displacement <= 7 */ + uint bicubic /* 1=bicubic filter, 0=bilinear */ + ) { + const int * const fil = bicubic ? filters [hfrac] : + BilinearFilters[hfrac]; + + int r = 0; do /* for each row */ + { + int c = 0; do /* for each destination sample */ + { + /* Pixel separation = one horizontal step = 1 */ + + temp[r][c] = interp(fil, p + c, 1); + } + + + + +Bankoski, et al. Informational [Page 117] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + while (++c < 4); + } + while (p += s, ++r < 9); /* advance p to next row */ + } + + /* Finish with vertical interpolation, producing final results. + Input array "temp" is of course that computed above. */ + + void Vinterp( + Pixel final[4][4], /* 4 rows of 4 (final) destination values */ + const Pixel temp[9][4], + uint vfrac, /* 0 <= vertical displacement <= 7 */ + uint bicubic /* 1=bicubic filter, 0=bilinear */ + ) { + const int * const fil = bicubic ? filters [vfrac] : + BilinearFilters[vfrac]; + + int r = 0; do /* for each row */ + { + int c = 0; do /* for each destination sample */ + { + /* Pixel separation = one vertical step = width + of array = 4 */ + + final[r][c] = interp(fil, temp[r] + c, 4); + } + while (++c < 4); + } + while (++r < 4); + } + + ---- End code block ---------------------------------------- + +18.4. Filter Properties + + We discuss briefly the rationale behind the choice of filters. Our + approach is necessarily cursory; a genuinely accurate discussion + would require a couple of books. Readers unfamiliar with signal + processing may or may not wish to skip this. + + All digital signals are of course sampled in some fashion. The case + where the inter-sample spacing (say in time for audio samples, or + space for pixels) is uniform, that is, the same at all positions, is + particularly common and amenable to analysis. Many aspects of the + treatment of such signals are best-understood in the frequency domain + via Fourier Analysis, particularly those aspects of the signal that + are not changed by shifts in position, especially when those + positional shifts are not given by a whole number of samples. + + + +Bankoski, et al. Informational [Page 118] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + Non-integral translates of a sampled signal are a textbook example of + the foregoing. In our case of non-integral motion vectors, we wish + to say what the underlying image "really is" at these pixels; + although we don't have values for them, we feel that it makes sense + to talk about them. The correctness of this feeling is predicated on + the underlying signal being band-limited, that is, not containing any + energy in spatial frequencies that cannot be faithfully rendered at + the pixel resolution at our disposal. In one dimension, this range + of "OK" frequencies is called the Nyquist band; in our two- + dimensional case of integer-grid samples, this range might be termed + a Nyquist rectangle. The finer the grid, the more we know about the + image, and the wider the Nyquist rectangle. + + It turns out that, for such band-limited signals, there is indeed an + exact mathematical formula to produce the correct sample value at an + arbitrary point. Unfortunately, this calculation requires the + consideration of every single sample in the image, as well as needing + to operate at infinite precision. Also, strictly speaking, all band- + limited signals have infinite spatial (or temporal) extent, so + everything we are discussing is really some sort of approximation. + + It is true that the theoretically correct subsampling procedure, as + well as any approximation thereof, is always given by a translation- + invariant weighted sum (or filter) similar to that used by VP8. It + is also true that the reconstruction error made by such a filter can + be simply represented as a multiplier in the frequency domain; that + is, such filters simply multiply the Fourier transform of any signal + to which they are applied by a fixed function associated to the + filter. This fixed function is usually called the frequency response + (or transfer function); the ideal subsampling filter has a frequency + response equal to one in the Nyquist rectangle and zero everywhere + else. + + Another basic fact about approximations to "truly correct" + subsampling is that the wider the subrectangle (within the Nyquist + rectangle) of spatial frequencies one wishes to "pass" (that is, + correctly render) or, put more accurately, the closer one wishes to + approximate the ideal transfer function, the more samples of the + original signal must be considered by the subsampling, and the wider + the calculation precision necessitated. + + The filters chosen by VP8 were chosen, within the constraints of 4 or + 6 taps and 7-bit precision, to do the best possible job of handling + the low spatial frequencies near the 0th DC frequency along with + introducing no resonances (places where the absolute value of the + frequency response exceeds one). + + + + + +Bankoski, et al. Informational [Page 119] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + The justification for the foregoing has two parts. First, resonances + can produce extremely objectionable visible artifacts when, as often + happens in actual compressed video streams, filters are applied + repeatedly. Second, the vast majority of energy in real-world images + lies near DC and not at the high end. + + To get slightly more specific, the filters chosen by VP8 are the best + resonance-free 4- or 6-tap filters possible, where "best" describes + the frequency response near the origin: The response at 0 is required + to be 1, and the graph of the response at 0 is as flat as possible. + + To provide an intuitively more obvious point of reference, the "best" + 2-tap filter is given by simple linear interpolation between the + surrounding actual pixels. + + Finally, it should be noted that, because of the way motion vectors + are calculated, the (shorter) 4-tap filters (used for odd fractional + displacements) are applied in the chroma plane only. Human color + perception is notoriously poor, especially where higher spatial + frequencies are involved. The shorter filters are easier to + understand mathematically, and the difference between them and a + theoretically slightly better 6-tap filter is negligible where chroma + is concerned. + +19. Annex A: Bitstream Syntax + + This annex presents the bitstream syntax in a tabular form. All the + information elements have been introduced and explained in the + previous sections but are collected here for a quick reference. Each + syntax element is briefly described after the tabular representation + along with a reference to the corresponding paragraph in the main + document. The meaning of each syntax element value is not repeated + here. + + The top-level hierarchy of the bitstream is introduced in Section 4. + + Definition of syntax element coding types can be found in Section 8. + The types used in the representation in this annex are: + + o f(n), n-bit value from stream (n successive bits, not boolean + encoded) + + o L(n), n-bit number encoded as n booleans (with equal probability + of being 0 or 1) + + o B(p), bool with probability p of being 0 + + o T, tree-encoded value + + + +Bankoski, et al. Informational [Page 120] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +19.1. Uncompressed Data Chunk + + | Frame Tag | Type | + | ------------------------------------------------- | ----- | + | frame_tag | f(24) | + | if (key_frame) { | | + | start_code | f(24) | + | horizontal_size_code | f(16) | + | vertical_size_code | f(16) | + | } | | + + The 3-byte frame tag can be parsed as follows: + + ---- Begin code block -------------------------------------- + + unsigned char *c = pbi->source; + unsigned int tmp; + + tmp = (c[2] << 16) | (c[1] << 8) | c[0]; + + key_frame = tmp & 0x1; + version = (tmp >> 1) & 0x7; + show_frame = (tmp >> 4) & 0x1; + first_part_size = (tmp >> 5) & 0x7FFFF; + + ---- End code block ---------------------------------------- + + Where: + + o key_frame indicates whether the current frame is a key frame + or not. + + o version determines the bitstream version. + + o show_frame indicates whether the current frame is meant to be + displayed or not. + + o first_part_size determines the size of the first partition + (control partition), excluding the uncompressed data chunk. + + + + + + + + + + + + +Bankoski, et al. Informational [Page 121] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + The start_code is a constant 3-byte pattern having value 0x9d012a. + The latter part of the uncompressed chunk (after the start_code) can + be parsed as follows: + + ---- Begin code block -------------------------------------- + + unsigned char *c = pbi->source + 6; + unsigned int tmp; + + tmp = (c[1] << 8) | c[0]; + + width = tmp & 0x3FFF; + horizontal_scale = tmp >> 14; + + tmp = (c[3] << 8) | c[2]; + + height = tmp & 0x3FFF; + vertical_scale = tmp >> 14; + + ---- End code block ---------------------------------------- + +19.2. Frame Header + + | Frame Header | Type | + | ------------------------------------------------- | ----- | + | if (key_frame) { | | + | color_space | L(1) | + | clamping_type | L(1) | + | } | | + | segmentation_enabled | L(1) | + | if (segmentation_enabled) | | + | update_segmentation() | | + | filter_type | L(1) | + | loop_filter_level | L(6) | + | sharpness_level | L(3) | + | mb_lf_adjustments() | | + | log2_nbr_of_dct_partitions | L(2) | + | quant_indices() | | + | if (key_frame) | | + | refresh_entropy_probs | L(1) | + + + + + + + + + + + +Bankoski, et al. Informational [Page 122] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + | else { | | + | refresh_golden_frame | L(1) | + | refresh_alternate_frame | L(1) | + | if (!refresh_golden_frame) | | + | copy_buffer_to_golden | L(2) | + | if (!refresh_alternate_frame) | | + | copy_buffer_to_alternate | L(2) | + | sign_bias_golden | L(1) | + | sign_bias_alternate | L(1) | + | refresh_entropy_probs | L(1) | + | refresh_last | L(1) | + | } | | + | token_prob_update() | | + | mb_no_skip_coeff | L(1) | + | if (mb_no_skip_coeff) | | + | prob_skip_false | L(8) | + | if (!key_frame) { | | + | prob_intra | L(8) | + | prob_last | L(8) | + | prob_gf | L(8) | + | intra_16x16_prob_update_flag | L(1) | + | if (intra_16x16_prob_update_flag) { | | + | for (i = 0; i < 4; i++) | | + | intra_16x16_prob | L(8) | + | } | | + | intra_chroma prob_update_flag | L(1) | + | if (intra_chroma_prob_update_flag) { | | + | for (i = 0; i < 3; i++) | | + | intra_chroma_prob | L(8) | + | } | | + | mv_prob_update() | | + | } | | + + o color_space defines the YUV color space of the sequence + (Section 9.2) + + o clamping_type specifies if the decoder is required to clamp the + reconstructed pixel values (Section 9.2) + + o segmentation_enabled enables the segmentation feature for the + current frame (Section 9.3) + + o filter_type determines whether the normal or the simple loop + filter is used (Sections 9.4, 15) + + o loop_filter_level controls the deblocking filter + (Sections 9.4, 15) + + + + +Bankoski, et al. Informational [Page 123] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + o sharpness_level controls the deblocking filter (Sections 9.4, 15) + + o log2_nbr_of_dct_partitions determines the number of separate + partitions containing the DCT coefficients of the macroblocks + (Section 9.5) + + o refresh_entropy_probs determines whether updated token + probabilities are used only for this frame or until further update + + o refresh_golden_frame determines if the current decoded frame + refreshes the golden frame (Section 9.7) + + o refresh_alternate_frame determines if the current decoded frame + refreshes the alternate reference frame (Section 9.7) + + o copy_buffer_to_golden determines if the golden reference is + replaced by another reference (Section 9.7) + + o copy_buffer_to_alternate determines if the alternate reference is + replaced by another reference (Section 9.7) + + o sign_bias_golden controls the sign of motion vectors when the + golden frame is referenced (Section 9.7) + + o sign_bias_alternate controls the sign of motion vectors when the + alternate frame is referenced (Section 9.7) + + o refresh_last determines if the current decoded frame refreshes the + last frame reference buffer (Section 9.8) + + o mb_no_skip_coeff enables or disables the skipping of macroblocks + containing no non-zero coefficients (Section 9.10) + + o prob_skip_false indicates the probability that the macroblock is + not skipped (flag indicating skipped macroblock is false) + (Section 9.10) + + o prob_intra indicates the probability of an intra macroblock + (Section 9.10) + + o prob_last indicates the probability that the last reference frame + is used for inter-prediction (Section 9.10) + + o prob_gf indicates the probability that the golden reference frame + is used for inter-prediction (Section 9.10) + + + + + + +Bankoski, et al. Informational [Page 124] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + o intra_16x16_prob_update_flag indicates if the branch probabilities + used in the decoding of the luma intra-prediction mode are updated + (Section 9.10) + + o intra_16x16_prob indicates the branch probabilities of the luma + intra-prediction mode decoding tree + + o intra_chroma_prob_update_flag indicates if the branch + probabilities used in the decoding of the chroma intra-prediction + mode are updated (Section 9.10) + + o intra_chroma_prob indicates the branch probabilities of the chroma + intra-prediction mode decoding tree + + | update_segmentation() | Type | + | ------------------------------------------------- | ----- | + | update_mb_segmentation_map | L(1) | + | update_segment_feature_data | L(1) | + | if (update_segment_feature_data) { | | + | segment_feature_mode | L(1) | + | for (i = 0; i < 4; i++) { | | + | quantizer_update | L(1) | + | if (quantizer_update) { | | + | quantizer_update_value | L(7) | + | quantizer_update_sign | L(1) | + | } | | + | } | | + | for (i = 0; i < 4; i++) { | | + | loop_filter_update | L(1) | + | if (loop_filter_update) { | | + | lf_update_value | L(6) | + | lf_update_sign | L(1) | + | } | | + | } | | + | } | | + | if (update_mb_segmentation_map) { | | + | for (i = 0; i < 3; i++) { | | + | segment_prob_update | L(1) | + | if (segment_prob_update) | | + | segment_prob | L(8) | + | } | | + | } | | + + o update_mb_segmentation_map determines if the MB segmentation map + is updated in the current frame (Section 9.3) + + o update_segment_feature_data indicates if the segment feature data + is updated in the current frame (Section 9.3) + + + +Bankoski, et al. Informational [Page 125] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + o segment_feature_mode indicates the feature data update mode, 0 for + delta and 1 for the absolute value (Section 9.3) + + o quantizer_update indicates if the quantizer value is updated for + the i^(th) segment (Section 9.3) + + o quantizer_update_value indicates the update value for the segment + quantizer (Section 9.3) + + o quantizer_update_sign indicates the update sign for the segment + quantizer (Section 9.3) + + o loop_filter_update indicates if the loop filter level value is + updated for the i^(th) segment (Section 9.3) + + o lf_update_value indicates the update value for the loop filter + level (Section 9.3) + + o lf_update_sign indicates the update sign for the loop filter level + (Section 9.3) + + o segment_prob_update indicates whether the branch probabilities + used to decode the segment_id in the MB header are decoded from + the stream or use the default value of 255 (Section 9.3) + + o segment_prob indicates the branch probabilities of the segment_id + decoding tree (Section 9.3) + + + + + + + + + + + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 126] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + | mb_lf_adjustments() | Type | + | ------------------------------------------------- | ----- | + | loop_filter_adj_enable | L(1) | + | if (loop_filter_adj_enable) { | | + | mode_ref_lf_delta_update | L(1) | + | if (mode_ref_lf_delta_update) { | | + | for (i = 0; i < 4; i++) { | | + | ref_frame_delta_update_flag | L(1) | + | if (ref_frame_delta_update_flag) { | | + | delta_magnitude | L(6) | + | delta_sign | L(1) | + | } | | + | } | | + | for (i = 0; i < 4; i++) { | | + | mb_mode_delta_update_flag | L(1) | + | if (mb_mode_delta_update_flag) { | | + | delta_magnitude | L(6) | + | delta_sign | L(1) | + | } | | + | } | | + | } | | + | } | | + + o loop_filter_adj_enable indicates if the MB-level loop filter + adjustment (based on the used reference frame and coding mode) is + on for the current frame (Section 9.4) + + o mode_ref_lf_delta_update indicates if the delta values used in an + adjustment are updated in the current frame (Section 9.4) + + o ref_frame_delta_update_flag indicates if the adjustment delta + value corresponding to a certain used reference frame is updated + (Section 9.4) + + o delta_magnitude is the absolute value of the delta value + + o delta_sign is the sign of the delta value + + o mb_mode_delta_update_flag indicates if the adjustment delta value + corresponding to a certain MB prediction mode is updated + (Section 9.4) + + + + + + + + + + +Bankoski, et al. Informational [Page 127] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + | quant_indices() | Type | + | ------------------------------------------------- | ----- | + | y_ac_qi | L(7) | + | y_dc_delta_present | L(1) | + | if (y_dc_delta_present) { | | + | y_dc_delta_magnitude | L(4) | + | y_dc_delta_sign | L(1) | + | } | | + | y2_dc_delta_present | L(1) | + | if (y2_dc_delta_present) { | | + | y2_dc_delta_magnitude | L(4) | + | y2_dc_delta_sign | L(1) | + | } | | + | y2_ac_delta_present | L(1) | + | if (y2_ac_delta_present) { | | + | y2_ac_delta_magnitude | L(4) | + | y2_ac_delta_sign | L(1) | + | } | | + | uv_dc_delta_present | L(1) | + | if (uv_dc_delta_present) { | | + | uv_dc_delta_magnitude | L(4) | + | uv_dc_delta_sign | L(1) | + | } | | + | uv_ac_delta_present | L(1) | + | if (uv_ac_delta_present) { | | + | uv_ac_delta_magnitude | L(4) | + | uv_ac_delta_sign | L(1) | + | } | | + + o y_ac_qi is the dequantization table index used for the luma AC + coefficients (and other coefficient groups if no delta value is + present) (Section 9.6) + + o y_dc_delta_present indicates if the stream contains a delta value + that is added to the baseline index to obtain the luma DC + coefficient dequantization index (Section 9.6) + + o y_dc_delta_magnitude is the magnitude of the delta value + (Section 9.6) + + o y_dc_delta_sign is the sign of the delta value (Section 9.6) + + o y2_dc_delta_present indicates if the stream contains a delta value + that is added to the baseline index to obtain the Y2 block DC + coefficient dequantization index (Section 9.6) + + + + + + +Bankoski, et al. Informational [Page 128] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + o y2_ac_delta_present indicates if the stream contains a delta value + that is added to the baseline index to obtain the Y2 block AC + coefficient dequantization index (Section 9.6) + + o uv_dc_delta_present indicates if the stream contains a delta value + that is added to the baseline index to obtain the chroma DC + coefficient dequantization index (Section 9.6) + + o uv_ac_delta_present indicates if the stream contains a delta value + that is added to the baseline index to obtain the chroma AC + coefficient dequantization index (Section 9.6) + + | token_prob_update() | Type | + | ------------------------------------------------- | ----- | + | for (i = 0; i < 4; i++) { | | + | for (j = 0; j < 8; j++) { | | + | for (k = 0; k < 3; k++) { | | + | for (l = 0; l < 11; l++) { | | + | coeff_prob_update_flag | L(1) | + | if (coeff_prob_update_flag) | | + | coeff_prob | L(8) | + | } | | + | } | | + | } | | + | } | | + + o coeff_prob_update_flag indicates if the corresponding branch + probability is updated in the current frame (Section 13.4) + + o coeff_prob is the new branch probability (Section 13.4) + + | mv_prob_update() | Type | + | ------------------------------------------------- | ----- | + | for (i = 0; i < 2; i++) { | | + | for (j = 0; j < 19; j++) { | | + | mv_prob_update_flag | L(1) | + | if (mv_prob_update_flag) | | + | prob | L(7) | + | } | | + | } | | + + o mv_prob_update_flag indicates if the corresponding MV decoding + probability is updated in the current frame (Section 17.2) + + o prob is the updated probability (Section 17.2) + + + + + + +Bankoski, et al. Informational [Page 129] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +19.3. Macroblock Data + + | Macroblock Data | Type | + | ------------------------------------------------- | ----- | + | macroblock_header() | | + | residual_data() | | + + + | macroblock_header() | Type | + | ------------------------------------------------- | ----- | + | if (update_mb_segmentation_map) | | + | segment_id | T | + | if (mb_no_skip_coeff) | | + | mb_skip_coeff | B(p) | + | if (!key_frame) | | + | is_inter_mb | B(p) | + | if (is_inter_mb) { | | + | mb_ref_frame_sel1 | B(p) | + | if (mb_ref_frame_sel1) | | + | mb_ref_frame_sel2 | B(p) | + | mv_mode | T | + | if (mv_mode == SPLITMV) { | | + | mv_split_mode | T | + | for (i = 0; i < numMvs; i++) { | | + | sub_mv_mode | T | + | if (sub_mv_mode == NEWMV4x4) { | | + | read_mvcomponent() | | + | read_mvcomponent() | | + | } | | + | } | | + | } else if (mv_mode == NEWMV) { | | + | read_mvcomponent() | | + | read_mvcomponent() | | + | } | | + | } else { /* intra mb */ | | + | intra_y_mode | T | + | if (intra_y_mode == B_PRED) { | | + | for (i = 0; i < 16; i++) | | + | intra_b_mode | T | + | } | | + | intra_uv_mode | T | + | } | | + + o segment_id indicates to which segment the macroblock belongs + (Section 10) + + o mb_skip_coeff indicates whether the macroblock contains any coded + coefficients or not (Section 11.1) + + + +Bankoski, et al. Informational [Page 130] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + o is_inter_mb indicates whether the macroblock is intra- or inter- + coded (Section 16) + + o mb_ref_frame_sel1 selects the reference frame to be used; last + frame (0), golden/alternate (1) (Section 16.2) + + o mb_ref_frame_sel2 selects whether the golden (0) or alternate + reference frame (1) is used (Section 16.2) + + o mv_mode determines the macroblock motion vector mode + (Section 16.2) + + o mv_split_mode gives the macroblock partitioning specification and + determines the number of motion vectors used (numMvs) + (Section 16.2) + + o sub_mv_mode determines the sub-macroblock motion vector mode for + macroblocks coded using the SPLITMV motion vector mode + (Section 16.2) + + o intra_y_mode selects the luminance intra-prediction mode + (Section 16.1) + + o intra_b_mode selects the sub-macroblock luminance prediction mode + for macroblocks coded using B_PRED mode (Section 16.1) + + o intra_uv_mode selects the chrominance intra-prediction mode + (Section 16.1) + + | residual_data() | Type | + | ------------------------------------------------- | ----- | + | if (!mb_skip_coeff) { | | + | if ( (is_inter_mb && mv_mode != SPLITMV) || | | + | (!is_inter_mb && intra_y_mode != B_PRED) ) | | + | residual_block() /* Y2 */ | | + | for (i = 0; i < 24; i++) | | + | residual_block() /* 16 Y, 4 U, 4 V */ | | + | } | | + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 131] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + | residual_block() | Type | + | ------------------------------------------------- | ----- | + | for (i = firstCoeff; i < 16; i++) { | | + | token | T | + | if (token == EOB) break; | | + | if (token_has_extra_bits) | | + | extra_bits | L(n) | + | if (coefficient != 0) | | + | sign | L(1) | + | } | | + + o firstCoeff is 1 for luma blocks of macroblocks containing Y2 + subblock; otherwise 0 + + o token defines the value of the coefficient, the value range of the + coefficient, or the end of block (Section 13.2) + + o extra_bits determines the value of the coefficient within the + value range defined by the token (Section 13.2) + + o sign indicates the sign of the coefficient (Section 13.2) + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 132] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +20. Attachment One: Reference Decoder Source Code + +20.1. bit_ops.h + + ---- Begin code block -------------------------------------- + + /* + * Copyright (c) 2010, 2011, Google Inc. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be + * found in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + #ifndef BIT_OPS_H + #define BIT_OPS_H + + /* Evaluates to a mask with n bits set */ + #define BITS_MASK(n) ((1<<(n))-1) + + /* Returns len bits, with the LSB at position bit */ + #define BITS_GET(val, bit, len) (((val)>>(bit))&BITS_MASK(len)) + + #endif + + ---- End code block ---------------------------------------- + +20.2. bool_decoder.h + + ---- Begin code block -------------------------------------- + + /* + * Copyright (c) 2010, 2011, Google Inc. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be + * found in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + #ifndef BOOL_DECODER_H + #define BOOL_DECODER_H + #include <stddef.h> + + + + + + + +Bankoski, et al. Informational [Page 133] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + struct bool_decoder + { + const unsigned char *input; /* next compressed data byte */ + size_t input_len; /* length of the input buffer */ + unsigned int range; /* identical to encoder's + * range */ + unsigned int value; /* contains at least 8 + * significant bits */ + int bit_count; /* # of bits shifted out of + * value, max 7 */ + }; + + static void + init_bool_decoder(struct bool_decoder *d, + const unsigned char *start_partition, + size_t sz) + { + if (sz >= 2) + { + d->value = (start_partition[0] << 8) /* first 2 input + * bytes */ + | start_partition[1]; + d->input = start_partition + 2; /* ptr to next byte */ + d->input_len = sz - 2; + } + else + { + d->value = 0; + d->input = NULL; + d->input_len = 0; + } + + d->range = 255; /* initial range is full */ + d->bit_count = 0; /* have not yet shifted out any bits */ + } + + static int bool_get(struct bool_decoder *d, int probability) + { + /* range and split are identical to the corresponding values + used by the encoder when this bool was written */ + + unsigned int split = 1 + (((d->range - 1) * probability) >> 8); + unsigned int SPLIT = split << 8; + int retval; /* will be 0 or 1 */ + + + + + + + +Bankoski, et al. Informational [Page 134] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + if (d->value >= SPLIT) /* encoded a one */ + { + retval = 1; + d->range -= split; /* reduce range */ + d->value -= SPLIT; /* subtract off left endpoint of + * interval */ + } + else /* encoded a zero */ + { + retval = 0; + d->range = split; /* reduce range, no change in left + * endpoint */ + } + + while (d->range < 128) /* shift out irrelevant value bits */ + { + d->value <<= 1; + d->range <<= 1; + + if (++d->bit_count == 8) /* shift in new bits 8 at a time */ + { + d->bit_count = 0; + + if (d->input_len) + { + d->value |= *d->input++; + d->input_len--; + } + } + } + + return retval; + } + + static int bool_get_bit(struct bool_decoder *br) + { + return bool_get(br, 128); + } + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 135] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static int bool_get_uint(struct bool_decoder *br, int bits) + { + int z = 0; + int bit; + + for (bit = bits - 1; bit >= 0; bit--) + { + z |= (bool_get_bit(br) << bit); + } + + return z; + } + + static int bool_get_int(struct bool_decoder *br, int bits) + { + int z = 0; + int bit; + + for (bit = bits - 1; bit >= 0; bit--) + { + z |= (bool_get_bit(br) << bit); + } + + return bool_get_bit(br) ? -z : z; + } + + static int bool_maybe_get_int(struct bool_decoder *br, int bits) + { + return bool_get_bit(br) ? bool_get_int(br, bits) : 0; + } + + static int + bool_read_tree(struct bool_decoder *bool, + const int *t, + const unsigned char *p) + { + int i = 0; + + while ((i = t[ i + bool_get(bool, p[i>>1])]) > 0); + + return -i; + } + #endif + + + ---- End code block ---------------------------------------- + + + + + +Bankoski, et al. Informational [Page 136] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +20.3. dequant_data.h + + ---- Begin code block -------------------------------------- + + /* + * Copyright (c) 2010, 2011, Google Inc. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be + * found in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + static const int dc_q_lookup[128] = + { + 4, 5, 6, 7, 8, 9, 10, 10, + 11, 12, 13, 14, 15, 16, 17, 17, + 18, 19, 20, 20, 21, 21, 22, 22, + 23, 23, 24, 25, 25, 26, 27, 28, + 29, 30, 31, 32, 33, 34, 35, 36, + 37, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 46, 47, 48, 49, 50, + 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 76, 77, 78, 79, 80, 81, + 82, 83, 84, 85, 86, 87, 88, 89, + 91, 93, 95, 96, 98, 100, 101, 102, + 104, 106, 108, 110, 112, 114, 116, 118, + 122, 124, 126, 128, 130, 132, 134, 136, + 138, 140, 143, 145, 148, 151, 154, 157 + }; + + static const int ac_q_lookup[128] = + { + 4, 5, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, + 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, + 52, 53, 54, 55, 56, 57, 58, 60, + 62, 64, 66, 68, 70, 72, 74, 76, + 78, 80, 82, 84, 86, 88, 90, 92, + 94, 96, 98, 100, 102, 104, 106, 108, + 110, 112, 114, 116, 119, 122, 125, 128, + 131, 134, 137, 140, 143, 146, 149, 152, + + + +Bankoski, et al. Informational [Page 137] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + 155, 158, 161, 164, 167, 170, 173, 177, + 181, 185, 189, 193, 197, 201, 205, 209, + 213, 217, 221, 225, 229, 234, 239, 245, + 249, 254, 259, 264, 269, 274, 279, 284 + }; + + ---- End code block ---------------------------------------- + +20.4. dixie.c + + ---- Begin code block -------------------------------------- + + /* + * Copyright (c) 2010, 2011, Google Inc. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be + * found in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + #include "vpx_codec_internal.h" + #include "bit_ops.h" + #include "dixie.h" + #include "vp8_prob_data.h" + #include "dequant_data.h" + #include "modemv.h" + #include "tokens.h" + #include "predict.h" + #include "dixie_loopfilter.h" + #include <string.h> + #include <assert.h> + + enum + { + FRAME_HEADER_SZ = 3, + KEYFRAME_HEADER_SZ = 7 + }; + + + #define ARRAY_COPY(a,b) {\ + assert(sizeof(a)==sizeof(b));memcpy(a,b,sizeof(a));} + static void + decode_entropy_header(struct vp8_decoder_ctx *ctx, + struct bool_decoder *bool, + struct vp8_entropy_hdr *hdr) + + + + + +Bankoski, et al. Informational [Page 138] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + { + int i, j, k, l; + + /* Read coefficient probability updates */ + for (i = 0; i < BLOCK_TYPES; i++) + for (j = 0; j < COEFF_BANDS; j++) + for (k = 0; k < PREV_COEFF_CONTEXTS; k++) + for (l = 0; l < ENTROPY_NODES; l++) + if (bool_get(bool, + k_coeff_entropy_update_probs + [i][j][k][l])) + hdr->coeff_probs[i][j][k][l] = + bool_get_uint(bool, 8); + + /* Read coefficient skip mode probability */ + hdr->coeff_skip_enabled = bool_get_bit(bool); + + if (hdr->coeff_skip_enabled) + hdr->coeff_skip_prob = bool_get_uint(bool, 8); + + /* Parse interframe probability updates */ + if (!ctx->frame_hdr.is_keyframe) + { + hdr->prob_inter = bool_get_uint(bool, 8); + hdr->prob_last = bool_get_uint(bool, 8); + hdr->prob_gf = bool_get_uint(bool, 8); + + if (bool_get_bit(bool)) + for (i = 0; i < 4; i++) + hdr->y_mode_probs[i] = bool_get_uint(bool, 8); + + if (bool_get_bit(bool)) + for (i = 0; i < 3; i++) + hdr->uv_mode_probs[i] = bool_get_uint(bool, 8); + + for (i = 0; i < 2; i++) + for (j = 0; j < MV_PROB_CNT; j++) + if (bool_get(bool, k_mv_entropy_update_probs[i][j])) + { + int x = bool_get_uint(bool, 7); + hdr->mv_probs[i][j] = x ? x << 1 : 1; + } + } + } + + + + + + + +Bankoski, et al. Informational [Page 139] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static void + decode_reference_header(struct vp8_decoder_ctx *ctx, + struct bool_decoder *bool, + struct vp8_reference_hdr *hdr) + { + unsigned int key = ctx->frame_hdr.is_keyframe; + + hdr->refresh_gf = key ? 1 : bool_get_bit(bool); + hdr->refresh_arf = key ? 1 : bool_get_bit(bool); + hdr->copy_gf = key ? 0 : !hdr->refresh_gf + ? bool_get_uint(bool, 2) : 0; + hdr->copy_arf = key ? 0 : !hdr->refresh_arf + ? bool_get_uint(bool, 2) : 0; + hdr->sign_bias[GOLDEN_FRAME] = key ? 0 : bool_get_bit(bool); + hdr->sign_bias[ALTREF_FRAME] = key ? 0 : bool_get_bit(bool); + hdr->refresh_entropy = bool_get_bit(bool); + hdr->refresh_last = key ? 1 : bool_get_bit(bool); + } + + + static void + decode_quantizer_header(struct vp8_decoder_ctx *ctx, + struct bool_decoder *bool, + struct vp8_quant_hdr *hdr) + { + int update; + int last_q = hdr->q_index; + + hdr->q_index = bool_get_uint(bool, 7); + update = last_q != hdr->q_index; + update |= (hdr->y1_dc_delta_q = bool_maybe_get_int(bool, 4)); + update |= (hdr->y2_dc_delta_q = bool_maybe_get_int(bool, 4)); + update |= (hdr->y2_ac_delta_q = bool_maybe_get_int(bool, 4)); + update |= (hdr->uv_dc_delta_q = bool_maybe_get_int(bool, 4)); + update |= (hdr->uv_ac_delta_q = bool_maybe_get_int(bool, 4)); + hdr->delta_update = update; + } + + + static void + decode_and_init_token_partitions(struct vp8_decoder_ctx *ctx, + struct bool_decoder *bool, + const unsigned char *data, + unsigned int sz, + struct vp8_token_hdr *hdr) + + + + + + +Bankoski, et al. Informational [Page 140] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + { + int i; + + hdr->partitions = 1 << bool_get_uint(bool, 2); + + if (sz < 3 *(hdr->partitions - 1)) + vpx_internal_error(&ctx->error, VPX_CODEC_CORRUPT_FRAME, + "Truncated packet found parsing partition" + " lengths."); + + sz -= 3 * (hdr->partitions - 1); + + for (i = 0; i < hdr->partitions; i++) + { + if (i < hdr->partitions - 1) + { + hdr->partition_sz[i] = (data[2] << 16) + | (data[1] << 8) | data[0]; + data += 3; + } + else + hdr->partition_sz[i] = sz; + + if (sz < hdr->partition_sz[i]) + vpx_internal_error(&ctx->error, VPX_CODEC_CORRUPT_FRAME, + "Truncated partition %d", i); + + sz -= hdr->partition_sz[i]; + } + + + for (i = 0; i < ctx->token_hdr.partitions; i++) + { + init_bool_decoder(&ctx->tokens[i].bool, data, + ctx->token_hdr.partition_sz[i]); + data += ctx->token_hdr.partition_sz[i]; + } + } + + + static void + decode_loopfilter_header(struct vp8_decoder_ctx *ctx, + struct bool_decoder *bool, + struct vp8_loopfilter_hdr *hdr) + + + + + + + +Bankoski, et al. Informational [Page 141] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + { + if (ctx->frame_hdr.is_keyframe) + memset(hdr, 0, sizeof(*hdr)); + + hdr->use_simple = bool_get_bit(bool); + hdr->level = bool_get_uint(bool, 6); + hdr->sharpness = bool_get_uint(bool, 3); + hdr->delta_enabled = bool_get_bit(bool); + + if (hdr->delta_enabled && bool_get_bit(bool)) + { + int i; + + for (i = 0; i < BLOCK_CONTEXTS; i++) + hdr->ref_delta[i] = bool_maybe_get_int(bool, 6); + + for (i = 0; i < BLOCK_CONTEXTS; i++) + hdr->mode_delta[i] = bool_maybe_get_int(bool, 6); + } + } + + + static void + decode_segmentation_header(struct vp8_decoder_ctx *ctx, + struct bool_decoder *bool, + struct vp8_segment_hdr *hdr) + { + if (ctx->frame_hdr.is_keyframe) + memset(hdr, 0, sizeof(*hdr)); + + hdr->enabled = bool_get_bit(bool); + + if (hdr->enabled) + { + int i; + + hdr->update_map = bool_get_bit(bool); + hdr->update_data = bool_get_bit(bool); + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 142] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + if (hdr->update_data) + { + hdr->abs = bool_get_bit(bool); + + for (i = 0; i < MAX_MB_SEGMENTS; i++) + hdr->quant_idx[i] = bool_maybe_get_int(bool, 7); + + for (i = 0; i < MAX_MB_SEGMENTS; i++) + hdr->lf_level[i] = bool_maybe_get_int(bool, 6); + } + + if (hdr->update_map) + { + for (i = 0; i < MB_FEATURE_TREE_PROBS; i++) + hdr->tree_probs[i] = bool_get_bit(bool) + ? bool_get_uint(bool, 8) + : 255; + } + } + else + { + hdr->update_map = 0; + hdr->update_data = 0; + } + } + + + static void + dequant_global_init(struct dequant_factors dqf[MAX_MB_SEGMENTS]) + { + int i; + + for (i = 0; i < MAX_MB_SEGMENTS; i++) + dqf[i].quant_idx = -1; + } + + + static int + clamp_q(int q) + { + if (q < 0) return 0; + else if (q > 127) return 127; + + return q; + } + + + + + + +Bankoski, et al. Informational [Page 143] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static int + dc_q(int q) + { + return dc_q_lookup[clamp_q(q)]; + } + + + static int + ac_q(int q) + { + return ac_q_lookup[clamp_q(q)]; + } + + + static void + dequant_init(struct dequant_factors factors[MAX_MB_SEGMENTS], + const struct vp8_segment_hdr *seg, + const struct vp8_quant_hdr *quant_hdr) + { + int i, q; + struct dequant_factors *dqf = factors; + + for (i = 0; i < (seg->enabled ? MAX_MB_SEGMENTS : 1); i++) + { + q = quant_hdr->q_index; + + if (seg->enabled) + q = (!seg->abs) ? q + seg->quant_idx[i] + : seg->quant_idx[i]; + + if (dqf->quant_idx != q || quant_hdr->delta_update) + { + dqf->factor[TOKEN_BLOCK_Y1][0] = + dc_q(q + quant_hdr->y1_dc_delta_q); + dqf->factor[TOKEN_BLOCK_Y1][1] = + ac_q(q); + dqf->factor[TOKEN_BLOCK_UV][0] = + dc_q(q + quant_hdr->uv_dc_delta_q); + dqf->factor[TOKEN_BLOCK_UV][1] = + ac_q(q + quant_hdr->uv_ac_delta_q); + dqf->factor[TOKEN_BLOCK_Y2][0] = + dc_q(q + quant_hdr->y2_dc_delta_q) * 2; + dqf->factor[TOKEN_BLOCK_Y2][1] = + ac_q(q + quant_hdr->y2_ac_delta_q) * 155 / 100; + + if (dqf->factor[TOKEN_BLOCK_Y2][1] < 8) + dqf->factor[TOKEN_BLOCK_Y2][1] = 8; + + + + +Bankoski, et al. Informational [Page 144] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + if (dqf->factor[TOKEN_BLOCK_UV][0] > 132) + dqf->factor[TOKEN_BLOCK_UV][0] = 132; + + dqf->quant_idx = q; + } + + dqf++; + } + } + + + static void + decode_frame(struct vp8_decoder_ctx *ctx, + const unsigned char *data, + unsigned int sz) + { + vpx_codec_err_t res; + struct bool_decoder bool; + int i, row, partition; + + ctx->saved_entropy_valid = 0; + + if ((res = vp8_parse_frame_header(data, sz, &ctx->frame_hdr))) + vpx_internal_error(&ctx->error, res, + "Failed to parse frame header"); + + if (ctx->frame_hdr.is_experimental) + vpx_internal_error(&ctx->error, VPX_CODEC_UNSUP_BITSTREAM, + "Experimental bitstreams not supported."); + + data += FRAME_HEADER_SZ; + sz -= FRAME_HEADER_SZ; + + if (ctx->frame_hdr.is_keyframe) + { + data += KEYFRAME_HEADER_SZ; + sz -= KEYFRAME_HEADER_SZ; + ctx->mb_cols = (ctx->frame_hdr.kf.w + 15) / 16; + ctx->mb_rows = (ctx->frame_hdr.kf.h + 15) / 16; + } + + /* Start the bitreader for the header/entropy partition */ + init_bool_decoder(&bool, data, ctx->frame_hdr.part0_sz); + + + + + + + + +Bankoski, et al. Informational [Page 145] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /* Skip the colorspace and clamping bits */ + if (ctx->frame_hdr.is_keyframe) + if (bool_get_uint(&bool, 2)) + vpx_internal_error( + &ctx->error, VPX_CODEC_UNSUP_BITSTREAM, + "Reserved bits not supported."); + + decode_segmentation_header(ctx, &bool, &ctx->segment_hdr); + decode_loopfilter_header(ctx, &bool, &ctx->loopfilter_hdr); + decode_and_init_token_partitions(ctx, + &bool, + data + ctx->frame_hdr.part0_sz, + sz - ctx->frame_hdr.part0_sz, + &ctx->token_hdr); + decode_quantizer_header(ctx, &bool, &ctx->quant_hdr); + decode_reference_header(ctx, &bool, &ctx->reference_hdr); + + /* Set keyframe entropy defaults. These get updated on keyframes + * regardless of the refresh_entropy setting. + */ + if (ctx->frame_hdr.is_keyframe) + { + ARRAY_COPY(ctx->entropy_hdr.coeff_probs, + k_default_coeff_probs); + ARRAY_COPY(ctx->entropy_hdr.mv_probs, + k_default_mv_probs); + ARRAY_COPY(ctx->entropy_hdr.y_mode_probs, + k_default_y_mode_probs); + ARRAY_COPY(ctx->entropy_hdr.uv_mode_probs, + k_default_uv_mode_probs); + } + + if (!ctx->reference_hdr.refresh_entropy) + { + ctx->saved_entropy = ctx->entropy_hdr; + ctx->saved_entropy_valid = 1; + } + + decode_entropy_header(ctx, &bool, &ctx->entropy_hdr); + + vp8_dixie_modemv_init(ctx); + vp8_dixie_tokens_init(ctx); + vp8_dixie_predict_init(ctx); + dequant_init(ctx->dequant_factors, &ctx->segment_hdr, + &ctx->quant_hdr); + + + + + + +Bankoski, et al. Informational [Page 146] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + for (row = 0, partition = 0; row < ctx->mb_rows; row++) + { + vp8_dixie_modemv_process_row( + ctx, &bool, row, 0, ctx->mb_cols); + vp8_dixie_tokens_process_row(ctx, partition, row, 0, + ctx->mb_cols); + vp8_dixie_predict_process_row(ctx, row, 0, ctx->mb_cols); + + if (ctx->loopfilter_hdr.level && row) + vp8_dixie_loopfilter_process_row(ctx, row - 1, 0, + ctx->mb_cols); + + if (++partition == ctx->token_hdr.partitions) + partition = 0; + } + + if (ctx->loopfilter_hdr.level) + vp8_dixie_loopfilter_process_row( + ctx, row - 1, 0, ctx->mb_cols); + + ctx->frame_cnt++; + + if (!ctx->reference_hdr.refresh_entropy) + { + ctx->entropy_hdr = ctx->saved_entropy; + ctx->saved_entropy_valid = 0; + } + + /* Handle reference frame updates */ + if (ctx->reference_hdr.copy_arf == 1) + { + vp8_dixie_release_ref_frame(ctx->ref_frames[ALTREF_FRAME]); + ctx->ref_frames[ALTREF_FRAME] = + vp8_dixie_ref_frame(ctx->ref_frames[LAST_FRAME]); + } + else if (ctx->reference_hdr.copy_arf == 2) + { + vp8_dixie_release_ref_frame(ctx->ref_frames[ALTREF_FRAME]); + ctx->ref_frames[ALTREF_FRAME] = + vp8_dixie_ref_frame(ctx->ref_frames[GOLDEN_FRAME]); + } + + if (ctx->reference_hdr.copy_gf == 1) + { + vp8_dixie_release_ref_frame(ctx->ref_frames[GOLDEN_FRAME]); + ctx->ref_frames[GOLDEN_FRAME] = + vp8_dixie_ref_frame(ctx->ref_frames[LAST_FRAME]); + } + + + +Bankoski, et al. Informational [Page 147] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + else if (ctx->reference_hdr.copy_gf == 2) + { + vp8_dixie_release_ref_frame(ctx->ref_frames[GOLDEN_FRAME]); + ctx->ref_frames[GOLDEN_FRAME] = + vp8_dixie_ref_frame(ctx->ref_frames[ALTREF_FRAME]); + } + + if (ctx->reference_hdr.refresh_gf) + { + vp8_dixie_release_ref_frame(ctx->ref_frames[GOLDEN_FRAME]); + ctx->ref_frames[GOLDEN_FRAME] = + vp8_dixie_ref_frame(ctx->ref_frames[CURRENT_FRAME]); + } + + if (ctx->reference_hdr.refresh_arf) + { + vp8_dixie_release_ref_frame(ctx->ref_frames[ALTREF_FRAME]); + ctx->ref_frames[ALTREF_FRAME] = + vp8_dixie_ref_frame(ctx->ref_frames[CURRENT_FRAME]); + } + + if (ctx->reference_hdr.refresh_last) + { + vp8_dixie_release_ref_frame(ctx->ref_frames[LAST_FRAME]); + ctx->ref_frames[LAST_FRAME] = + vp8_dixie_ref_frame(ctx->ref_frames[CURRENT_FRAME]); + } + + } + + + void + vp8_dixie_decode_init(struct vp8_decoder_ctx *ctx) + { + dequant_global_init(ctx->dequant_factors); + } + + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 148] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + #define CHECK_FOR_UPDATE(lval,rval,update_flag) do {\ + unsigned int old = lval; \ + update_flag |= (old != (lval = rval)); \ + } while (0) + + vpx_codec_err_t + vp8_parse_frame_header(const unsigned char *data, + unsigned int sz, + struct vp8_frame_hdr *hdr) + { + unsigned long raw; + + if (sz < 10) + return VPX_CODEC_CORRUPT_FRAME; + + /* The frame header is defined as a three-byte little endian + * value + */ + raw = data[0] | (data[1] << 8) | (data[2] << 16); + hdr->is_keyframe = !BITS_GET(raw, 0, 1); + hdr->version = BITS_GET(raw, 1, 2); + hdr->is_experimental = BITS_GET(raw, 3, 1); + hdr->is_shown = BITS_GET(raw, 4, 1); + hdr->part0_sz = BITS_GET(raw, 5, 19); + + if (sz <= hdr->part0_sz + (hdr->is_keyframe ? 10 : 3)) + return VPX_CODEC_CORRUPT_FRAME; + + hdr->frame_size_updated = 0; + + if (hdr->is_keyframe) + { + unsigned int update = 0; + + /* Keyframe header consists of a three-byte sync code + * followed by the width and height and associated scaling + * factors. + */ + if (data[3] != 0x9d || data[4] != 0x01 || data[5] != 0x2a) + return VPX_CODEC_UNSUP_BITSTREAM; + + + + + + + + + + + +Bankoski, et al. Informational [Page 149] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + raw = data[6] | (data[7] << 8) + | (data[8] << 16) | (data[9] << 24); + CHECK_FOR_UPDATE(hdr->kf.w, BITS_GET(raw, 0, 14), + update); + CHECK_FOR_UPDATE(hdr->kf.scale_w, BITS_GET(raw, 14, 2), + update); + CHECK_FOR_UPDATE(hdr->kf.h, BITS_GET(raw, 16, 14), + update); + CHECK_FOR_UPDATE(hdr->kf.scale_h, BITS_GET(raw, 30, 2), + update); + + hdr->frame_size_updated = update; + + if (!hdr->kf.w || !hdr->kf.h) + return VPX_CODEC_UNSUP_BITSTREAM; + } + + return VPX_CODEC_OK; + } + + + vpx_codec_err_t + vp8_dixie_decode_frame(struct vp8_decoder_ctx *ctx, + const unsigned char *data, + unsigned int sz) + { + volatile struct vp8_decoder_ctx *ctx_ = ctx; + + ctx->error.error_code = VPX_CODEC_OK; + ctx->error.has_detail = 0; + + if (!setjmp(ctx->error.jmp)) + decode_frame(ctx, data, sz); + + return ctx_->error.error_code; + } + + + void + vp8_dixie_decode_destroy(struct vp8_decoder_ctx *ctx) + { + vp8_dixie_predict_destroy(ctx); + vp8_dixie_tokens_destroy(ctx); + vp8_dixie_modemv_destroy(ctx); + } + + ---- End code block ---------------------------------------- + + + + +Bankoski, et al. Informational [Page 150] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +20.5. dixie.h + + ---- Begin code block -------------------------------------- + + /* + * Copyright (c) 2010, 2011, Google Inc. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be + * found in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + #ifndef DIXIE_H + #define DIXIE_H + #include "vpx_codec_internal.h" + #include "bool_decoder.h" + + struct vp8_frame_hdr + { + unsigned int is_keyframe; /* Frame is a keyframe */ + unsigned int is_experimental; /* Frame is a keyframe */ + unsigned int version; /* Bitstream version */ + unsigned int is_shown; /* Frame is to be displayed. */ + unsigned int part0_sz; /* Partition 0 length, in bytes */ + + struct vp8_kf_hdr + { + unsigned int w; /* Width */ + unsigned int h; /* Height */ + unsigned int scale_w; /* Scaling factor, Width */ + unsigned int scale_h; /* Scaling factor, Height */ + } kf; + + unsigned int frame_size_updated; /* Flag to indicate a resolution + * update. + */ + }; + + + enum + { + MB_FEATURE_TREE_PROBS = 3, + MAX_MB_SEGMENTS = 4 + }; + + + + + + +Bankoski, et al. Informational [Page 151] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + struct vp8_segment_hdr + { + unsigned int enabled; + unsigned int update_data; + unsigned int update_map; + unsigned int abs; /* 0=deltas, 1=absolute values */ + unsigned int tree_probs[MB_FEATURE_TREE_PROBS]; + int lf_level[MAX_MB_SEGMENTS]; + int quant_idx[MAX_MB_SEGMENTS]; + + }; + + + enum + { + BLOCK_CONTEXTS = 4 + }; + + + struct vp8_loopfilter_hdr + { + unsigned int use_simple; + unsigned int level; + unsigned int sharpness; + unsigned int delta_enabled; + int ref_delta[BLOCK_CONTEXTS]; + int mode_delta[BLOCK_CONTEXTS]; + }; + + + enum + { + MAX_PARTITIONS = 8 + }; + + struct vp8_token_hdr + { + unsigned int partitions; + unsigned int partition_sz[MAX_PARTITIONS]; + }; + + + + + + + + + + + +Bankoski, et al. Informational [Page 152] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + struct vp8_quant_hdr + { + unsigned int q_index; + int delta_update; + int y1_dc_delta_q; + int y2_dc_delta_q; + int y2_ac_delta_q; + int uv_dc_delta_q; + int uv_ac_delta_q; + }; + + + struct vp8_reference_hdr + { + unsigned int refresh_last; + unsigned int refresh_gf; + unsigned int refresh_arf; + unsigned int copy_gf; + unsigned int copy_arf; + unsigned int sign_bias[4]; + unsigned int refresh_entropy; + }; + + + enum + { + BLOCK_TYPES = 4, + PREV_COEFF_CONTEXTS = 3, + COEFF_BANDS = 8, + ENTROPY_NODES = 11, + }; + typedef unsigned char coeff_probs_table_t[BLOCK_TYPES][COEFF_BANDS] + [PREV_COEFF_CONTEXTS] + [ENTROPY_NODES]; + + + enum + { + MV_PROB_CNT = 2 + 8 - 1 + 10 /* from entropymv.h */ + }; + typedef unsigned char mv_component_probs_t[MV_PROB_CNT]; + + + + + + + + + + +Bankoski, et al. Informational [Page 153] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + struct vp8_entropy_hdr + { + coeff_probs_table_t coeff_probs; + mv_component_probs_t mv_probs[2]; + unsigned int coeff_skip_enabled; + unsigned char coeff_skip_prob; + unsigned char y_mode_probs[4]; + unsigned char uv_mode_probs[3]; + unsigned char prob_inter; + unsigned char prob_last; + unsigned char prob_gf; + }; + + + enum reference_frame + { + CURRENT_FRAME, + LAST_FRAME, + GOLDEN_FRAME, + ALTREF_FRAME, + NUM_REF_FRAMES + }; + + + enum prediction_mode + { + /* 16x16 intra modes */ + DC_PRED, V_PRED, H_PRED, TM_PRED, B_PRED, + + /* 16x16 inter modes */ + NEARESTMV, NEARMV, ZEROMV, NEWMV, SPLITMV, + + MB_MODE_COUNT, + + /* 4x4 intra modes */ + B_DC_PRED = 0, B_TM_PRED, B_VE_PRED, B_HE_PRED, B_LD_PRED, + B_RD_PRED, B_VR_PRED, B_VL_PRED, B_HD_PRED, B_HU_PRED, + + /* 4x4 inter modes */ + LEFT4X4, ABOVE4X4, ZERO4X4, NEW4X4, + + B_MODE_COUNT + }; + + + + + + + + +Bankoski, et al. Informational [Page 154] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + enum splitmv_partitioning + { + SPLITMV_16X8, + SPLITMV_8X16, + SPLITMV_8X8, + SPLITMV_4X4 + }; + + + typedef short filter_t[6]; + + + typedef union mv + { + struct + { + int16_t x, y; + } d; + uint32_t raw; + } mv_t; + + + struct mb_base_info + { + unsigned char y_mode : 4; + unsigned char uv_mode : 4; + unsigned char segment_id : 2; + unsigned char ref_frame : 2; + unsigned char skip_coeff : 1; + unsigned char need_mc_border : 1; + enum splitmv_partitioning partitioning : 2; + union mv mv; + unsigned int eob_mask; + }; + + + struct mb_info + { + struct mb_base_info base; + union + { + union mv mvs[16]; + enum prediction_mode modes[16]; + } split; + }; + + + + + + +Bankoski, et al. Informational [Page 155] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /* A "token entropy context" has 4 Y values, 2 U, 2 V, and 1 Y2 */ + typedef int token_entropy_ctx_t[4 + 2 + 2 + 1]; + + struct token_decoder + { + struct bool_decoder bool; + token_entropy_ctx_t left_token_entropy_ctx; + short *coeffs; + }; + + enum token_block_type + { + TOKEN_BLOCK_Y1, + TOKEN_BLOCK_UV, + TOKEN_BLOCK_Y2, + TOKEN_BLOCK_TYPES, + }; + + struct dequant_factors + { + int quant_idx; + short factor[TOKEN_BLOCK_TYPES][2]; /* [ Y1, UV, Y2 ] + * [ DC, AC ] */ + }; + + struct ref_cnt_img + { + vpx_image_t img; + unsigned int ref_cnt; + }; + + + struct vp8_decoder_ctx + { + struct vpx_internal_error_info error; + unsigned int frame_cnt; + + struct vp8_frame_hdr frame_hdr; + struct vp8_segment_hdr segment_hdr; + struct vp8_loopfilter_hdr loopfilter_hdr; + struct vp8_token_hdr token_hdr; + struct vp8_quant_hdr quant_hdr; + struct vp8_reference_hdr reference_hdr; + struct vp8_entropy_hdr entropy_hdr; + + struct vp8_entropy_hdr saved_entropy; + unsigned int saved_entropy_valid; + + + + +Bankoski, et al. Informational [Page 156] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + unsigned int mb_rows; + unsigned int mb_cols; + struct mb_info *mb_info_storage; + struct mb_info **mb_info_rows_storage; + struct mb_info **mb_info_rows; + + token_entropy_ctx_t *above_token_entropy_ctx; + struct token_decoder tokens[MAX_PARTITIONS]; + struct dequant_factors dequant_factors[MAX_MB_SEGMENTS]; + + struct ref_cnt_img frame_strg[NUM_REF_FRAMES]; + struct ref_cnt_img *ref_frames[NUM_REF_FRAMES]; + ptrdiff_t ref_frame_offsets[4]; + + const filter_t *subpixel_filters; + }; + + + void + vp8_dixie_decode_init(struct vp8_decoder_ctx *ctx); + + + void + vp8_dixie_decode_destroy(struct vp8_decoder_ctx *ctx); + + vpx_codec_err_t + vp8_parse_frame_header(const unsigned char *data, + unsigned int sz, + struct vp8_frame_hdr *hdr); + + + vpx_codec_err_t + vp8_dixie_decode_frame(struct vp8_decoder_ctx *ctx, + const unsigned char *data, + unsigned int sz); + + + #define CLAMP_255(x) ((x)<0?0:((x)>255?255:(x))) + + #endif + + ---- End code block ---------------------------------------- + + + + + + + + + +Bankoski, et al. Informational [Page 157] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +20.6. dixie_loopfilter.c + + ---- Begin code block -------------------------------------- + + /* + * Copyright (c) 2010, 2011, Google Inc. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be + * found in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + #include "dixie.h" + #include "dixie_loopfilter.h" + + #define ABS(x) ((x) >= 0 ? (x) : -(x)) + + #define p3 pixels[-4*stride] + #define p2 pixels[-3*stride] + #define p1 pixels[-2*stride] + #define p0 pixels[-1*stride] + #define q0 pixels[ 0*stride] + #define q1 pixels[ 1*stride] + #define q2 pixels[ 2*stride] + #define q3 pixels[ 3*stride] + + #define static + static int + + saturate_int8(int x) + { + if (x < -128) + return -128; + + if (x > 127) + return 127; + + return x; + } + + + + + + + + + + + +Bankoski, et al. Informational [Page 158] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static int + saturate_uint8(int x) + { + if (x < 0) + return 0; + + if (x > 255) + return 255; + + return x; + } + + + static int + high_edge_variance(unsigned char *pixels, + int stride, + int hev_threshold) + { + return ABS(p1 - p0) > hev_threshold || + ABS(q1 - q0) > hev_threshold; + } + + + static int + simple_threshold(unsigned char *pixels, + int stride, + int filter_limit) + { + return (ABS(p0 - q0) * 2 + (ABS(p1 - q1) >> 1)) <= filter_limit; + } + + + static int + normal_threshold(unsigned char *pixels, + int stride, + int edge_limit, + int interior_limit) + { + int E = edge_limit; + int I = interior_limit; + + return simple_threshold(pixels, stride, 2 * E + I) + && ABS(p3 - p2) <= I && ABS(p2 - p1) <= I + && ABS(p1 - p0) <= I && ABS(q3 - q2) <= I + && ABS(q2 - q1) <= I && ABS(q1 - q0) <= I; + } + + + + + +Bankoski, et al. Informational [Page 159] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static void + filter_common(unsigned char *pixels, + int stride, + int use_outer_taps) + { + int a, f1, f2; + + a = 3 * (q0 - p0); + + if (use_outer_taps) + a += saturate_int8(p1 - q1); + + a = saturate_int8(a); + + f1 = ((a + 4 > 127) ? 127 : a + 4) >> 3; + f2 = ((a + 3 > 127) ? 127 : a + 3) >> 3; + + p0 = saturate_uint8(p0 + f2); + q0 = saturate_uint8(q0 - f1); + + if (!use_outer_taps) + { + /* This handles the case of subblock_filter() + * (from the bitstream guide. + */ + a = (f1 + 1) >> 1; + p1 = saturate_uint8(p1 + a); + q1 = saturate_uint8(q1 - a); + } + } + + + + + + + + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 160] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static void + filter_mb_edge(unsigned char *pixels, + int stride) + { + int w, a; + + w = saturate_int8(saturate_int8(p1 - q1) + 3 * (q0 - p0)); + + a = (27 * w + 63) >> 7; + p0 = saturate_uint8(p0 + a); + q0 = saturate_uint8(q0 - a); + + a = (18 * w + 63) >> 7; + p1 = saturate_uint8(p1 + a); + q1 = saturate_uint8(q1 - a); + + a = (9 * w + 63) >> 7; + p2 = saturate_uint8(p2 + a); + q2 = saturate_uint8(q2 - a); + } + + + static void + filter_mb_v_edge(unsigned char *src, + int stride, + int edge_limit, + int interior_limit, + int hev_threshold, + int size) + { + int i; + + for (i = 0; i < 8 * size; i++) + { + if (normal_threshold(src, 1, edge_limit, interior_limit)) + { + if (high_edge_variance(src, 1, hev_threshold)) + filter_common(src, 1, 1); + else + filter_mb_edge(src, 1); + } + + src += stride; + } + } + + + + + + +Bankoski, et al. Informational [Page 161] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static void + filter_subblock_v_edge(unsigned char *src, + int stride, + int edge_limit, + int interior_limit, + int hev_threshold, + int size) + { + int i; + + for (i = 0; i < 8 * size; i++) + { + if (normal_threshold(src, 1, edge_limit, interior_limit)) + filter_common(src, 1, + high_edge_variance(src, 1, hev_threshold)); + + src += stride; + } + } + + + static void + filter_mb_h_edge(unsigned char *src, + int stride, + int edge_limit, + int interior_limit, + int hev_threshold, + int size) + { + int i; + + for (i = 0; i < 8 * size; i++) + { + if (normal_threshold(src, stride, edge_limit, + interior_limit)) + { + if (high_edge_variance(src, stride, hev_threshold)) + filter_common(src, stride, 1); + else + filter_mb_edge(src, stride); + } + + src += 1; + } + } + + + + + + +Bankoski, et al. Informational [Page 162] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static void + filter_subblock_h_edge(unsigned char *src, + int stride, + int edge_limit, + int interior_limit, + int hev_threshold, + int size) + { + int i; + + for (i = 0; i < 8 * size; i++) + { + if (normal_threshold(src, stride, edge_limit, + interior_limit)) + filter_common(src, stride, + high_edge_variance(src, stride, + hev_threshold)); + + src += 1; + } + } + + + static void + filter_v_edge_simple(unsigned char *src, + int stride, + int filter_limit) + { + int i; + + for (i = 0; i < 16; i++) + { + if (simple_threshold(src, 1, filter_limit)) + filter_common(src, 1, 1); + + src += stride; + } + } + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 163] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static void + filter_h_edge_simple(unsigned char *src, + int stride, + int filter_limit) + { + int i; + + for (i = 0; i < 16; i++) + { + if (simple_threshold(src, stride, filter_limit)) + filter_common(src, stride, 1); + + src += 1; + } + } + + + static void + calculate_filter_parameters(struct vp8_decoder_ctx *ctx, + struct mb_info *mbi, + int *edge_limit_, + int *interior_limit_, + int *hev_threshold_) + { + int filter_level, interior_limit, hev_threshold; + + /* Reference code/spec seems to conflate filter_level and + * edge_limit + */ + + filter_level = ctx->loopfilter_hdr.level; + + if (ctx->segment_hdr.enabled) + { + if (!ctx->segment_hdr.abs) + filter_level += + ctx->segment_hdr.lf_level[mbi->base.segment_id]; + else + filter_level = + ctx->segment_hdr.lf_level[mbi->base.segment_id]; + } + + if (filter_level > 63) + filter_level = 63; + else if (filter_level < 0) + filter_level = 0; + + + + + +Bankoski, et al. Informational [Page 164] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + if (ctx->loopfilter_hdr.delta_enabled) + { + filter_level += + ctx->loopfilter_hdr.ref_delta[mbi->base.ref_frame]; + + if (mbi->base.ref_frame == CURRENT_FRAME) + { + if (mbi->base.y_mode == B_PRED) + filter_level += ctx->loopfilter_hdr.mode_delta[0]; + } + else if (mbi->base.y_mode == ZEROMV) + filter_level += ctx->loopfilter_hdr.mode_delta[1]; + else if (mbi->base.y_mode == SPLITMV) + filter_level += ctx->loopfilter_hdr.mode_delta[3]; + else + filter_level += ctx->loopfilter_hdr.mode_delta[2]; + } + + if (filter_level > 63) + filter_level = 63; + else if (filter_level < 0) + filter_level = 0; + + interior_limit = filter_level; + + if (ctx->loopfilter_hdr.sharpness) + { + interior_limit >>= ctx->loopfilter_hdr.sharpness > 4 ? 2 : 1; + + if (interior_limit > 9 - ctx->loopfilter_hdr.sharpness) + interior_limit = 9 - ctx->loopfilter_hdr.sharpness; + } + + if (interior_limit < 1) + interior_limit = 1; + + hev_threshold = (filter_level >= 15); + + if (filter_level >= 40) + hev_threshold++; + + if (filter_level >= 20 && !ctx->frame_hdr.is_keyframe) + hev_threshold++; + + *edge_limit_ = filter_level; + *interior_limit_ = interior_limit; + *hev_threshold_ = hev_threshold; + } + + + +Bankoski, et al. Informational [Page 165] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static void + filter_row_normal(struct vp8_decoder_ctx *ctx, + unsigned int row, + unsigned int start_col, + unsigned int num_cols) + { + unsigned char *y, *u, *v; + int stride, uv_stride; + struct mb_info *mbi; + unsigned int col; + + /* Adjust pointers based on row, start_col */ + + stride = ctx->ref_frames[CURRENT_FRAME]->img.stride[PLANE_Y]; + uv_stride = ctx->ref_frames[CURRENT_FRAME]->img.stride[PLANE_U]; + y = ctx->ref_frames[CURRENT_FRAME]->img.planes[PLANE_Y]; + u = ctx->ref_frames[CURRENT_FRAME]->img.planes[PLANE_U]; + v = ctx->ref_frames[CURRENT_FRAME]->img.planes[PLANE_V]; + y += (stride * row + start_col) * 16; + u += (uv_stride * row + start_col) * 8; + v += (uv_stride * row + start_col) * 8; + mbi = ctx->mb_info_rows[row] + start_col; + + for (col = start_col; col < start_col + num_cols; col++) + { + int edge_limit, interior_limit, hev_threshold; + + /* TODO: Only need to recalculate every MB if segmentation is + * enabled. + */ + calculate_filter_parameters(ctx, mbi, &edge_limit, + &interior_limit, &hev_threshold); + + if (edge_limit) + { + if (col) + { + filter_mb_v_edge(y, stride, edge_limit + 2, + interior_limit, hev_threshold, 2); + filter_mb_v_edge(u, uv_stride, edge_limit + 2, + interior_limit, hev_threshold, 1); + filter_mb_v_edge(v, uv_stride, edge_limit + 2, + interior_limit, hev_threshold, 1); + } + + + + + + + +Bankoski, et al. Informational [Page 166] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /* NOTE: This conditional is actually dependent on the + * number of coefficients decoded, not the skip flag as + * coded in the bitstream. The tokens task is expected + * to set 31 if there is *any* non-zero data. + */ + if (mbi->base.eob_mask + || mbi->base.y_mode == SPLITMV + || mbi->base.y_mode == B_PRED) + { + filter_subblock_v_edge(y + 4, stride, edge_limit, + interior_limit, hev_threshold, + 2); + filter_subblock_v_edge(y + 8, stride, edge_limit, + interior_limit, hev_threshold, + 2); + filter_subblock_v_edge(y + 12, stride, edge_limit, + interior_limit, hev_threshold, + 2); + filter_subblock_v_edge(u + 4, uv_stride, edge_limit, + interior_limit, hev_threshold, + 1); + filter_subblock_v_edge(v + 4, uv_stride, edge_limit, + interior_limit, hev_threshold, + 1); + } + + if (row) + { + filter_mb_h_edge(y, stride, edge_limit + 2, + interior_limit, hev_threshold, 2); + filter_mb_h_edge(u, uv_stride, edge_limit + 2, + interior_limit, hev_threshold, 1); + filter_mb_h_edge(v, uv_stride, edge_limit + 2, + interior_limit, hev_threshold, 1); + } + + + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 167] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + if (mbi->base.eob_mask + || mbi->base.y_mode == SPLITMV + || mbi->base.y_mode == B_PRED) + { + filter_subblock_h_edge(y + 4 * stride, stride, + edge_limit, interior_limit, + hev_threshold, 2); + filter_subblock_h_edge(y + 8 * stride, stride, + edge_limit, interior_limit, + hev_threshold, 2); + filter_subblock_h_edge(y + 12 * stride, stride, + edge_limit, interior_limit, + hev_threshold, 2); + filter_subblock_h_edge(u + 4 * uv_stride, uv_stride, + edge_limit, interior_limit, + hev_threshold, 1); + filter_subblock_h_edge(v + 4 * uv_stride, uv_stride, + edge_limit, interior_limit, + hev_threshold, 1); + } + } + + y += 16; + u += 8; + v += 8; + mbi++; + } + } + + static void + filter_row_simple(struct vp8_decoder_ctx *ctx, + unsigned int row, + unsigned int start_col, + unsigned int num_cols) + { + unsigned char *y; + int stride; + struct mb_info *mbi; + unsigned int col; + + /* Adjust pointers based on row, start_col */ + stride = ctx->ref_frames[CURRENT_FRAME]->img.stride[PLANE_Y]; + y = ctx->ref_frames[CURRENT_FRAME]->img.planes[PLANE_Y]; + y += (stride * row + start_col) * 16; + mbi = ctx->mb_info_rows[row] + start_col; + + + + + + +Bankoski, et al. Informational [Page 168] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + for (col = start_col; col < start_col + num_cols; col++) + { + int edge_limit, interior_limit, hev_threshold; + + /* TODO: Only need to recalculate every MB if segmentation is + * enabled. + */ + calculate_filter_parameters(ctx, mbi, &edge_limit, + &interior_limit, &hev_threshold); + + if (edge_limit) + { + + /* NOTE: This conditional is actually dependent on the + * number of coefficients decoded, not the skip flag as + * coded in the bitstream. The tokens task is expected + * to set 31 if there is *any* non-zero data. + */ + int filter_subblocks = (mbi->base.eob_mask + || mbi->base.y_mode == SPLITMV + || mbi->base.y_mode == B_PRED); + int mb_limit = (edge_limit + 2) * 2 + interior_limit; + int b_limit = edge_limit * 2 + interior_limit; + + if (col) + filter_v_edge_simple(y, stride, mb_limit); + + if (filter_subblocks) + { + filter_v_edge_simple(y + 4, stride, b_limit); + filter_v_edge_simple(y + 8, stride, b_limit); + filter_v_edge_simple(y + 12, stride, b_limit); + } + + if (row) + filter_h_edge_simple(y, stride, mb_limit); + + if (filter_subblocks) + { + filter_h_edge_simple(y + 4 * stride, stride, + b_limit); + filter_h_edge_simple(y + 8 * stride, stride, + b_limit); + filter_h_edge_simple(y + 12 * stride, stride, + b_limit); + } + } + + + + +Bankoski, et al. Informational [Page 169] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + y += 16; + mbi++; + } + } + + + void + vp8_dixie_loopfilter_process_row(struct vp8_decoder_ctx *ctx, + unsigned int row, + unsigned int start_col, + unsigned int num_cols) + { + if (ctx->loopfilter_hdr.use_simple) + filter_row_simple(ctx, row, start_col, num_cols); + else + filter_row_normal(ctx, row, start_col, num_cols); + } + + ---- End code block ---------------------------------------- + +20.7. dixie_loopfilter.h + + ---- Begin code block -------------------------------------- + + /* + * Copyright (c) 2010, 2011, Google Inc. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be + * found in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + #ifndef DIXIE_LOOPFILTER_H + #define DIXIE_LOOPFILTER_H + + void + vp8_dixie_loopfilter_process_row(struct vp8_decoder_ctx *ctx, + unsigned int row, + unsigned int start_col, + unsigned int num_cols); + + #endif + + ---- End code block ---------------------------------------- + + + + + + +Bankoski, et al. Informational [Page 170] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +20.8. idct_add.c + + ---- Begin code block -------------------------------------- + + /* + * Copyright (c) 2010, 2011, Google Inc. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be + * found in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + #include "dixie.h" + #include "idct_add.h" + #include <assert.h> + + void + vp8_dixie_walsh(const short *input, short *output) + { + int i; + int a1, b1, c1, d1; + int a2, b2, c2, d2; + const short *ip = input; + short *op = output; + + for (i = 0; i < 4; i++) + { + a1 = ip[0] + ip[12]; + b1 = ip[4] + ip[8]; + c1 = ip[4] - ip[8]; + d1 = ip[0] - ip[12]; + + op[0] = a1 + b1; + op[4] = c1 + d1; + op[8] = a1 - b1; + op[12] = d1 - c1; + ip++; + op++; + } + + ip = output; + op = output; + + + + + + + + +Bankoski, et al. Informational [Page 171] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + for (i = 0; i < 4; i++) + { + a1 = ip[0] + ip[3]; + b1 = ip[1] + ip[2]; + c1 = ip[1] - ip[2]; + d1 = ip[0] - ip[3]; + + a2 = a1 + b1; + b2 = c1 + d1; + c2 = a1 - b1; + d2 = d1 - c1; + + op[0] = (a2 + 3) >> 3; + op[1] = (b2 + 3) >> 3; + op[2] = (c2 + 3) >> 3; + op[3] = (d2 + 3) >> 3; + + ip += 4; + op += 4; + } + } + + + #define cospi8sqrt2minus1 20091 + #define sinpi8sqrt2 35468 + #define rounding 0 + static void + idct_columns(const short *input, short *output) + { + int i; + int a1, b1, c1, d1; + + const short *ip = input; + short *op = output; + int temp1, temp2; + int shortpitch = 4; + + for (i = 0; i < 4; i++) + { + a1 = ip[0] + ip[8]; + b1 = ip[0] - ip[8]; + + temp1 = (ip[4] * sinpi8sqrt2 + rounding) >> 16; + temp2 = ip[12] + + ((ip[12] * cospi8sqrt2minus1 + rounding) >> 16); + c1 = temp1 - temp2; + + + + + +Bankoski, et al. Informational [Page 172] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + temp1 = ip[4] + + ((ip[4] * cospi8sqrt2minus1 + rounding) >> 16); + temp2 = (ip[12] * sinpi8sqrt2 + rounding) >> 16; + d1 = temp1 + temp2; + + op[shortpitch*0] = a1 + d1; + op[shortpitch*3] = a1 - d1; + + op[shortpitch*1] = b1 + c1; + op[shortpitch*2] = b1 - c1; + + ip++; + op++; + } + } + + + void + vp8_dixie_idct_add(unsigned char *recon, + const unsigned char *predict, + int stride, + const short *coeffs) + { + int i; + int a1, b1, c1, d1, temp1, temp2; + short tmp[16]; + idct_columns(coeffs, tmp); + coeffs = tmp; + + for (i = 0; i < 4; i++) + { + a1 = coeffs[0] + coeffs[2]; + b1 = coeffs[0] - coeffs[2]; + + temp1 = (coeffs[1] * sinpi8sqrt2 + rounding) >> 16; + temp2 = coeffs[3] + + ((coeffs[3] * cospi8sqrt2minus1 + rounding) >> 16); + c1 = temp1 - temp2; + + temp1 = coeffs[1] + + ((coeffs[1] * cospi8sqrt2minus1 + rounding) >> 16); + temp2 = (coeffs[3] * sinpi8sqrt2 + rounding) >> 16; + d1 = temp1 + temp2; + + recon[0] = CLAMP_255(predict[0] + ((a1 + d1 + 4) >> 3)); + recon[3] = CLAMP_255(predict[3] + ((a1 - d1 + 4) >> 3)); + recon[1] = CLAMP_255(predict[1] + ((b1 + c1 + 4) >> 3)); + recon[2] = CLAMP_255(predict[2] + ((b1 - c1 + 4) >> 3)); + + + +Bankoski, et al. Informational [Page 173] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + coeffs += 4; + recon += stride; + predict += stride; + } + } + + ---- End code block ---------------------------------------- + +20.9. idct_add.h + + ---- Begin code block -------------------------------------- + + /* + * Copyright (c) 2010, 2011, Google Inc. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be + * found in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + #ifndef IDCT_ADD_H + #define IDCT_ADD_H + + void + vp8_dixie_idct_add_init(struct vp8_decoder_ctx *ctx); + + + void + vp8_dixie_idct_add(unsigned char *recon, + const unsigned char *predict, + int stride, + const short *coeffs); + + + void + vp8_dixie_walsh(const short *in, short *out); + + + void + vp8_dixie_idct_add_process_row(struct vp8_decoder_ctx *ctx, + short *coeffs, + unsigned int row, + unsigned int start_col, + unsigned int num_cols); + #endif + + ---- End code block ---------------------------------------- + + + +Bankoski, et al. Informational [Page 174] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +20.10. mem.h + + ---- Begin code block -------------------------------------- + + /* + * Copyright (c) 2010, 2011, Google Inc. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be + * found in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + #ifndef VPX_PORTS_MEM_H + #define VPX_PORTS_MEM_H + #include "vpx_config.h" + #include "vpx_integer.h" + + #if defined(__GNUC__) && __GNUC__ + #define DECLARE_ALIGNED(n,typ,val) typ val __attribute__ \ + ((aligned (n))) + #elif defined(_MSC_VER) + #define DECLARE_ALIGNED(n,typ,val) __declspec(align(n)) typ val + #else + #warning No alignment directives known for this compiler. + #define DECLARE_ALIGNED(n,typ,val) typ val + #endif + #endif + + + /* Declare an aligned array on the stack, for situations where the + * stack pointer may not have the alignment we expect. Creates an + * array with a modified name, then defines val to be a pointer, and + * aligns that pointer within the array. + */ + #define DECLARE_ALIGNED_ARRAY(a,typ,val,n)\ + typ val##_[(n)+(a)/sizeof(typ)+1];\ + typ *val = (typ*)((((intptr_t)val##_)+(a)-1)&((intptr_t)-(a))) + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 175] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /* Indicates that the usage of the specified variable has been + * audited to assure that it's safe to use uninitialized. Silences + * 'may be used uninitialized' warnings on gcc. + */ + #if defined(__GNUC__) && __GNUC__ + #define UNINITIALIZED_IS_SAFE(x) x=x + #else + #define UNINITIALIZED_IS_SAFE(x) x + #endif + + ---- End code block ---------------------------------------- + +20.11. modemv.c + + ---- Begin code block -------------------------------------- + + /* + * Copyright (c) 2010, 2011, Google Inc. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be + * found in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + #include "dixie.h" + #include "modemv_data.h" + #include <stdlib.h> + #include <assert.h> + + + struct mv_clamp_rect + { + int to_left, to_right, to_top, to_bottom; + }; + + + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 176] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static union mv + clamp_mv(union mv raw, const struct mv_clamp_rect *bounds) + { + union mv newmv; + + newmv.d.x = (raw.d.x < bounds->to_left) + ? bounds->to_left : raw.d.x; + newmv.d.x = (raw.d.x > bounds->to_right) + ? bounds->to_right : newmv.d.x; + newmv.d.y = (raw.d.y < bounds->to_top) + ? bounds->to_top : raw.d.y; + newmv.d.y = (raw.d.y > bounds->to_bottom) + ? bounds->to_bottom : newmv.d.y; + return newmv; + } + + + static int + read_segment_id(struct bool_decoder *bool, + struct vp8_segment_hdr *seg) + { + return bool_get(bool, seg->tree_probs[0]) + ? 2 + bool_get(bool, seg->tree_probs[2]) + : bool_get(bool, seg->tree_probs[1]); + } + + + static enum prediction_mode + above_block_mode(const struct mb_info *this, + const struct mb_info *above, + unsigned int b) + { + if (b < 4) + { + switch (above->base.y_mode) + { + case DC_PRED: + return B_DC_PRED; + case V_PRED: + return B_VE_PRED; + case H_PRED: + return B_HE_PRED; + + + + + + + + + +Bankoski, et al. Informational [Page 177] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + case TM_PRED: + return B_TM_PRED; + case B_PRED: + return above->split.modes[b+12]; + default: + assert(0); + } + } + + return this->split.modes[b-4]; + } + + + static enum prediction_mode + left_block_mode(const struct mb_info *this, + const struct mb_info *left, + unsigned int b) + { + if (!(b & 3)) + { + switch (left->base.y_mode) + { + case DC_PRED: + return B_DC_PRED; + case V_PRED: + return B_VE_PRED; + case H_PRED: + return B_HE_PRED; + case TM_PRED: + return B_TM_PRED; + case B_PRED: + return left->split.modes[b+3]; + default: + assert(0); + } + } + + return this->split.modes[b-1]; + } + + + + + + + + + + + + +Bankoski, et al. Informational [Page 178] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static void + decode_kf_mb_mode(struct mb_info *this, + struct mb_info *left, + struct mb_info *above, + struct bool_decoder *bool) + { + int y_mode, uv_mode; + + y_mode = bool_read_tree(bool, kf_y_mode_tree, kf_y_mode_probs); + + if (y_mode == B_PRED) + { + unsigned int i; + + for (i = 0; i < 16; i++) + { + enum prediction_mode a = above_block_mode(this, above, + i); + enum prediction_mode l = left_block_mode(this, left, i); + enum prediction_mode b; + + b = bool_read_tree(bool, b_mode_tree, + kf_b_mode_probs[a][l]); + this->split.modes[i] = b; + } + } + + uv_mode = bool_read_tree(bool, uv_mode_tree, kf_uv_mode_probs); + + this->base.y_mode = y_mode; + this->base.uv_mode = uv_mode; + this->base.mv.raw = 0; + this->base.ref_frame = 0; + } + + static void + decode_intra_mb_mode(struct mb_info *this, + struct vp8_entropy_hdr *hdr, + struct bool_decoder *bool) + { + /* Like decode_kf_mb_mode, but with probabilities transmitted in + * the bitstream and no context on the above/left block mode. + */ + int y_mode, uv_mode; + + y_mode = bool_read_tree(bool, y_mode_tree, hdr->y_mode_probs); + + + + + +Bankoski, et al. Informational [Page 179] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + if (y_mode == B_PRED) + { + unsigned int i; + + for (i = 0; i < 16; i++) + { + enum prediction_mode b; + + b = bool_read_tree(bool, b_mode_tree, + default_b_mode_probs); + this->split.modes[i] = b; + } + } + + uv_mode = bool_read_tree(bool, uv_mode_tree, hdr->uv_mode_probs); + + this->base.y_mode = y_mode; + this->base.uv_mode = uv_mode; + this->base.mv.raw = 0; + this->base.ref_frame = CURRENT_FRAME; + } + + + static int + read_mv_component(struct bool_decoder *bool, + const unsigned char mvc[MV_PROB_CNT]) + { + enum {IS_SHORT, SIGN, SHORT, BITS = SHORT + 8 - 1, + LONG_WIDTH = 10}; + int x = 0; + + if (bool_get(bool, mvc[IS_SHORT])) /* Large */ + { + int i = 0; + + for (i = 0; i < 3; i++) + x += bool_get(bool, mvc[BITS + i]) << i; + + /* Skip bit 3, which is sometimes implicit */ + for (i = LONG_WIDTH - 1; i > 3; i--) + x += bool_get(bool, mvc[BITS + i]) << i; + + if (!(x & 0xFFF0) || bool_get(bool, mvc[BITS + 3])) + x += 8; + } + else /* small */ + x = bool_read_tree(bool, small_mv_tree, mvc + SHORT); + + + + +Bankoski, et al. Informational [Page 180] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + if (x && bool_get(bool, mvc[SIGN])) + x = -x; + + return x << 1; + } + + + static mv_t + above_block_mv(const struct mb_info *this, + const struct mb_info *above, + unsigned int b) + { + if (b < 4) + { + if (above->base.y_mode == SPLITMV) + return above->split.mvs[b+12]; + + return above->base.mv; + } + + return this->split.mvs[b-4]; + } + + + static mv_t + left_block_mv(const struct mb_info *this, + const struct mb_info *left, + unsigned int b) + { + if (!(b & 3)) + { + if (left->base.y_mode == SPLITMV) + return left->split.mvs[b+3]; + + return left->base.mv; + } + + return this->split.mvs[b-1]; + } + + + + + + + + + + + + +Bankoski, et al. Informational [Page 181] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static enum prediction_mode + submv_ref(struct bool_decoder *bool, union mv l, union mv a) + { + enum subblock_mv_ref + { + SUBMVREF_NORMAL, + SUBMVREF_LEFT_ZED, + SUBMVREF_ABOVE_ZED, + SUBMVREF_LEFT_ABOVE_SAME, + SUBMVREF_LEFT_ABOVE_ZED + }; + + int lez = !(l.raw); + int aez = !(a.raw); + int lea = l.raw == a.raw; + enum subblock_mv_ref ctx = SUBMVREF_NORMAL; + + if (lea && lez) + ctx = SUBMVREF_LEFT_ABOVE_ZED; + else if (lea) + ctx = SUBMVREF_LEFT_ABOVE_SAME; + else if (aez) + ctx = SUBMVREF_ABOVE_ZED; + else if (lez) + ctx = SUBMVREF_LEFT_ZED; + + return bool_read_tree(bool, submv_ref_tree, + submv_ref_probs2[ctx]); + } + + + static void + read_mv(struct bool_decoder *bool, + union mv *mv, + mv_component_probs_t mvc[2]) + { + mv->d.y = read_mv_component(bool, mvc[0]); + mv->d.x = read_mv_component(bool, mvc[1]); + } + + + + + + + + + + + + +Bankoski, et al. Informational [Page 182] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static void + mv_bias(const struct mb_info *mb, + const unsigned int sign_bias[3], + enum reference_frame ref_frame, + union mv *mv) + { + if (sign_bias[mb->base.ref_frame] ^ sign_bias[ref_frame]) + { + mv->d.x *= -1; + mv->d.y *= -1; + } + } + + + enum near_mv_v + { + CNT_BEST = 0, + CNT_ZEROZERO = 0, + CNT_NEAREST, + CNT_NEAR, + CNT_SPLITMV + }; + + + static void + find_near_mvs(const struct mb_info *this, + const struct mb_info *left, + const struct mb_info *above, + const unsigned int sign_bias[3], + union mv near_mvs[4], + int cnt[4]) + { + const struct mb_info *aboveleft = above - 1; + union mv *mv = near_mvs; + int *cntx = cnt; + + /* Zero accumulators */ + mv[0].raw = mv[1].raw = mv[2].raw = 0; + cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0; + + + + + + + + + + + + +Bankoski, et al. Informational [Page 183] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /* Process above */ + if (above->base.ref_frame != CURRENT_FRAME) + { + if (above->base.mv.raw) + { + (++mv)->raw = above->base.mv.raw; + mv_bias(above, sign_bias, this->base.ref_frame, mv); + ++cntx; + } + + *cntx += 2; + } + + /* Process left */ + if (left->base.ref_frame != CURRENT_FRAME) + { + if (left->base.mv.raw) + { + union mv this_mv; + + this_mv.raw = left->base.mv.raw; + mv_bias(left, sign_bias, this->base.ref_frame, &this_mv); + + if (this_mv.raw != mv->raw) + { + (++mv)->raw = this_mv.raw; + ++cntx; + } + + *cntx += 2; + } + else + cnt[CNT_ZEROZERO] += 2; + } + + /* Process above left */ + if (aboveleft->base.ref_frame != CURRENT_FRAME) + { + if (aboveleft->base.mv.raw) + { + union mv this_mv; + + this_mv.raw = aboveleft->base.mv.raw; + mv_bias(aboveleft, sign_bias, this->base.ref_frame, + &this_mv); + + + + + + +Bankoski, et al. Informational [Page 184] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + if (this_mv.raw != mv->raw) + { + (++mv)->raw = this_mv.raw; + ++cntx; + } + + *cntx += 1; + } + else + cnt[CNT_ZEROZERO] += 1; + } + + /* If we have three distinct MVs ... */ + + if (cnt[CNT_SPLITMV]) + { + /* See if above-left MV can be merged with NEAREST */ + if (mv->raw == near_mvs[CNT_NEAREST].raw) + cnt[CNT_NEAREST] += 1; + } + + cnt[CNT_SPLITMV] = ((above->base.y_mode == SPLITMV) + + (left->base.y_mode == SPLITMV)) * 2 + + (aboveleft->base.y_mode == SPLITMV); + + /* Swap near and nearest if necessary */ + if (cnt[CNT_NEAR] > cnt[CNT_NEAREST]) + { + int tmp; + tmp = cnt[CNT_NEAREST]; + cnt[CNT_NEAREST] = cnt[CNT_NEAR]; + cnt[CNT_NEAR] = tmp; + tmp = near_mvs[CNT_NEAREST].raw; + near_mvs[CNT_NEAREST].raw = near_mvs[CNT_NEAR].raw; + near_mvs[CNT_NEAR].raw = tmp; + } + + /* Use near_mvs[CNT_BEST] to store the "best" MV. Note that this + * storage shares the same address as near_mvs[CNT_ZEROZERO]. + */ + if (cnt[CNT_NEAREST] >= cnt[CNT_BEST]) + near_mvs[CNT_BEST] = near_mvs[CNT_NEAREST]; + } + + + + + + + + +Bankoski, et al. Informational [Page 185] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static void + decode_split_mv(struct mb_info *this, + const struct mb_info *left, + const struct mb_info *above, + struct vp8_entropy_hdr *hdr, + union mv *best_mv, + struct bool_decoder *bool) + { + const int *partition; + int j, k, mask, partition_id; + + partition_id = bool_read_tree(bool, split_mv_tree, + split_mv_probs); + partition = mv_partitions[partition_id]; + this->base.partitioning = partition_id; + + for (j = 0, mask = 0; mask < 65535; j++) + { + union mv mv, left_mv, above_mv; + enum prediction_mode subblock_mode; + + /* Find the first subblock in this partition. */ + for (k = 0; j != partition[k]; k++); + + /* Decode the next MV */ + left_mv = left_block_mv(this, left, k); + above_mv = above_block_mv(this, above, k); + subblock_mode = submv_ref(bool, left_mv, above_mv); + + switch (subblock_mode) + { + case LEFT4X4: + mv = left_mv; + break; + case ABOVE4X4: + mv = above_mv; + break; + case ZERO4X4: + mv.raw = 0; + break; + case NEW4X4: + read_mv(bool, &mv, hdr->mv_probs); + mv.d.x += best_mv->d.x; + mv.d.y += best_mv->d.y; + break; + default: + assert(0); + } + + + +Bankoski, et al. Informational [Page 186] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /* Fill the MVs for this partition */ + for (; k < 16; k++) + if (j == partition[k]) + { + this->split.mvs[k] = mv; + mask |= 1 << k; + } + } + } + + + static int + need_mc_border(union mv mv, int l, int t, int b_w, int w, int h) + { + int b, r; + + /* Get distance to edge for top-left pixel */ + l += (mv.d.x >> 3); + t += (mv.d.y >> 3); + + /* Get distance to edge for bottom-right pixel */ + r = w - (l + b_w); + b = h - (t + b_w); + + return (l >> 1 < 2 || r >> 1 < 3 || t >> 1 < 2 || b >> 1 < 3); + } + + static void + decode_mvs(struct vp8_decoder_ctx *ctx, + struct mb_info *this, + const struct mb_info *left, + const struct mb_info *above, + const struct mv_clamp_rect *bounds, + struct bool_decoder *bool) + { + struct vp8_entropy_hdr *hdr = &ctx->entropy_hdr; + union mv near_mvs[4]; + union mv clamped_best_mv; + int mv_cnts[4]; + unsigned char probs[4]; + enum {BEST, NEAREST, NEAR}; + int x, y, w, h, b; + + this->base.ref_frame = bool_get(bool, hdr->prob_last) + ? 2 + bool_get(bool, hdr->prob_gf) + : 1; + + + + + +Bankoski, et al. Informational [Page 187] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + find_near_mvs(this, this - 1, above, + ctx->reference_hdr.sign_bias, near_mvs, mv_cnts); + probs[0] = mv_counts_to_probs[mv_cnts[0]][0]; + probs[1] = mv_counts_to_probs[mv_cnts[1]][1]; + probs[2] = mv_counts_to_probs[mv_cnts[2]][2]; + probs[3] = mv_counts_to_probs[mv_cnts[3]][3]; + + this->base.y_mode = bool_read_tree(bool, mv_ref_tree, probs); + this->base.uv_mode = this->base.y_mode; + + this->base.need_mc_border = 0; + x = (-bounds->to_left - 128) >> 3; + y = (-bounds->to_top - 128) >> 3; + w = ctx->mb_cols * 16; + h = ctx->mb_rows * 16; + + switch (this->base.y_mode) + { + case NEARESTMV: + this->base.mv = clamp_mv(near_mvs[NEAREST], bounds); + break; + case NEARMV: + this->base.mv = clamp_mv(near_mvs[NEAR], bounds); + break; + case ZEROMV: + this->base.mv.raw = 0; + return; //skip need_mc_border check + case NEWMV: + clamped_best_mv = clamp_mv(near_mvs[BEST], bounds); + read_mv(bool, &this->base.mv, hdr->mv_probs); + this->base.mv.d.x += clamped_best_mv.d.x; + this->base.mv.d.y += clamped_best_mv.d.y; + break; + case SPLITMV: + { + union mv chroma_mv[4] = {{{0}}}; + + clamped_best_mv = clamp_mv(near_mvs[BEST], bounds); + decode_split_mv(this, left, above, hdr, &clamped_best_mv, + bool); + this->base.mv = this->split.mvs[15]; + + + + + + + + + + +Bankoski, et al. Informational [Page 188] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + for (b = 0; b < 16; b++) + { + chroma_mv[(b>>1&1) + (b>>2&2)].d.x += + this->split.mvs[b].d.x; + chroma_mv[(b>>1&1) + (b>>2&2)].d.y += + this->split.mvs[b].d.y; + + if (need_mc_border(this->split.mvs[b], + x + (b & 3) * 4, y + (b & ~3), 4, w, h)) + { + this->base.need_mc_border = 1; + break; + } + } + + for (b = 0; b < 4; b++) + { + chroma_mv[b].d.x += 4 + 8 * (chroma_mv[b].d.x >> 31); + chroma_mv[b].d.y += 4 + 8 * (chroma_mv[b].d.y >> 31); + chroma_mv[b].d.x /= 4; + chroma_mv[b].d.y /= 4; + + //note we're passing in non-subsampled coordinates + + if (need_mc_border(chroma_mv[b], + x + (b & 1) * 8, y + (b >> 1) * 8, 16, w, h)) + { + this->base.need_mc_border = 1; + break; + } + } + + return; //skip need_mc_border check + } + default: + assert(0); + } + + if (need_mc_border(this->base.mv, x, y, 16, w, h)) + this->base.need_mc_border = 1; + } + + + + + + + + + + +Bankoski, et al. Informational [Page 189] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + void + vp8_dixie_modemv_process_row(struct vp8_decoder_ctx *ctx, + struct bool_decoder *bool, + int row, + int start_col, + int num_cols) + { + struct mb_info *above, *this; + unsigned int col; + struct mv_clamp_rect bounds; + + this = ctx->mb_info_rows[row] + start_col; + above = ctx->mb_info_rows[row - 1] + start_col; + + /* Calculate the eighth-pel MV bounds using a 1 MB border. */ + bounds.to_left = -((start_col + 1) << 7); + bounds.to_right = (ctx->mb_cols - start_col) << 7; + bounds.to_top = -((row + 1) << 7); + bounds.to_bottom = (ctx->mb_rows - row) << 7; + + for (col = start_col; col < start_col + num_cols; col++) + { + if (ctx->segment_hdr.update_map) + this->base.segment_id = read_segment_id(bool, + &ctx->segment_hdr); + + if (ctx->entropy_hdr.coeff_skip_enabled) + this->base.skip_coeff = bool_get(bool, + ctx->entropy_hdr.coeff_skip_prob); + + if (ctx->frame_hdr.is_keyframe) + { + if (!ctx->segment_hdr.update_map) + this->base.segment_id = 0; + + decode_kf_mb_mode(this, this - 1, above, bool); + } + else + { + if (bool_get(bool, ctx->entropy_hdr.prob_inter)) + decode_mvs(ctx, this, this - 1, above, &bounds, + bool); + else + decode_intra_mb_mode(this, &ctx->entropy_hdr, bool); + + bounds.to_left -= 16 << 3; + bounds.to_right -= 16 << 3; + } + + + +Bankoski, et al. Informational [Page 190] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /* Advance to next mb */ + this++; + above++; + } + } + + + void + vp8_dixie_modemv_init(struct vp8_decoder_ctx *ctx) + { + unsigned int mbi_w, mbi_h, i; + struct mb_info *mbi; + + mbi_w = ctx->mb_cols + 1; /* For left border col */ + mbi_h = ctx->mb_rows + 1; /* For above border row */ + + if (ctx->frame_hdr.frame_size_updated) + { + free(ctx->mb_info_storage); + ctx->mb_info_storage = NULL; + free(ctx->mb_info_rows_storage); + ctx->mb_info_rows_storage = NULL; + } + + if (!ctx->mb_info_storage) + ctx->mb_info_storage = calloc(mbi_w * mbi_h, + sizeof(*ctx->mb_info_storage)); + + if (!ctx->mb_info_rows_storage) + + ctx->mb_info_rows_storage = calloc(mbi_h, + sizeof(*ctx->mb_info_rows_storage)); + + /* Set up row pointers */ + mbi = ctx->mb_info_storage + 1; + + for (i = 0; i < mbi_h; i++) + { + ctx->mb_info_rows_storage[i] = mbi; + mbi += mbi_w; + } + + ctx->mb_info_rows = ctx->mb_info_rows_storage + 1; + } + + + + + + + +Bankoski, et al. Informational [Page 191] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + void + vp8_dixie_modemv_destroy(struct vp8_decoder_ctx *ctx) + { + free(ctx->mb_info_storage); + ctx->mb_info_storage = NULL; + free(ctx->mb_info_rows_storage); + ctx->mb_info_rows_storage = NULL; + } + + ---- End code block ---------------------------------------- + +20.12. modemv.h + + ---- Begin code block -------------------------------------- + + /* + * Copyright (c) 2010, 2011, Google Inc. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be + * found in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + #ifndef MODEMV_H + #define MODEMV_H + + void + vp8_dixie_modemv_init(struct vp8_decoder_ctx *ctx); + + + void + vp8_dixie_modemv_destroy(struct vp8_decoder_ctx *ctx); + + + void + vp8_dixie_modemv_process_row(struct vp8_decoder_ctx *ctx, + struct bool_decoder *bool, + int row, + int start_col, + int num_cols); + + #endif + + ---- End code block ---------------------------------------- + + + + + + +Bankoski, et al. Informational [Page 192] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +20.13. modemv_data.h + + ---- Begin code block -------------------------------------- + + /* + * Copyright (c) 2010, 2011, Google Inc. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be + * found in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + static const unsigned char kf_y_mode_probs[] = { 145, 156, 163, 128}; + static const unsigned char kf_uv_mode_probs[] = { 142, 114, 183}; + static const unsigned char kf_b_mode_probs[10][10][9] = + { + { /* above mode 0 */ + { /* left mode 0 */ 231, 120, 48, 89, 115, 113, 120, 152, 112}, + { /* left mode 1 */ 152, 179, 64, 126, 170, 118, 46, 70, 95}, + { /* left mode 2 */ 175, 69, 143, 80, 85, 82, 72, 155, 103}, + { /* left mode 3 */ 56, 58, 10, 171, 218, 189, 17, 13, 152}, + { /* left mode 4 */ 144, 71, 10, 38, 171, 213, 144, 34, 26}, + { /* left mode 5 */ 114, 26, 17, 163, 44, 195, 21, 10, 173}, + { /* left mode 6 */ 121, 24, 80, 195, 26, 62, 44, 64, 85}, + { /* left mode 7 */ 170, 46, 55, 19, 136, 160, 33, 206, 71}, + { /* left mode 8 */ 63, 20, 8, 114, 114, 208, 12, 9, 226}, + { /* left mode 9 */ 81, 40, 11, 96, 182, 84, 29, 16, 36} + }, + { /* above mode 1 */ + { /* left mode 0 */ 134, 183, 89, 137, 98, 101, 106, 165, 148}, + { /* left mode 1 */ 72, 187, 100, 130, 157, 111, 32, 75, 80}, + { /* left mode 2 */ 66, 102, 167, 99, 74, 62, 40, 234, 128}, + { /* left mode 3 */ 41, 53, 9, 178, 241, 141, 26, 8, 107}, + { /* left mode 4 */ 104, 79, 12, 27, 217, 255, 87, 17, 7}, + { /* left mode 5 */ 74, 43, 26, 146, 73, 166, 49, 23, 157}, + { /* left mode 6 */ 65, 38, 105, 160, 51, 52, 31, 115, 128}, + { /* left mode 7 */ 87, 68, 71, 44, 114, 51, 15, 186, 23}, + { /* left mode 8 */ 47, 41, 14, 110, 182, 183, 21, 17, 194}, + { /* left mode 9 */ 66, 45, 25, 102, 197, 189, 23, 18, 22} + }, + { /* above mode 2 */ + { /* left mode 0 */ 88, 88, 147, 150, 42, 46, 45, 196, 205}, + { /* left mode 1 */ 43, 97, 183, 117, 85, 38, 35, 179, 61}, + { /* left mode 2 */ 39, 53, 200, 87, 26, 21, 43, 232, 171}, + { /* left mode 3 */ 56, 34, 51, 104, 114, 102, 29, 93, 77}, + { /* left mode 4 */ 107, 54, 32, 26, 51, 1, 81, 43, 31}, + + + +Bankoski, et al. Informational [Page 193] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + { /* left mode 5 */ 39, 28, 85, 171, 58, 165, 90, 98, 64}, + { /* left mode 6 */ 34, 22, 116, 206, 23, 34, 43, 166, 73}, + { /* left mode 7 */ 68, 25, 106, 22, 64, 171, 36, 225, 114}, + { /* left mode 8 */ 34, 19, 21, 102, 132, 188, 16, 76, 124}, + { /* left mode 9 */ 62, 18, 78, 95, 85, 57, 50, 48, 51} + }, + { /* above mode 3 */ + { /* left mode 0 */ 193, 101, 35, 159, 215, 111, 89, 46, 111}, + { /* left mode 1 */ 60, 148, 31, 172, 219, 228, 21, 18, 111}, + { /* left mode 2 */ 112, 113, 77, 85, 179, 255, 38, 120, 114}, + { /* left mode 3 */ 40, 42, 1, 196, 245, 209, 10, 25, 109}, + { /* left mode 4 */ 100, 80, 8, 43, 154, 1, 51, 26, 71}, + { /* left mode 5 */ 88, 43, 29, 140, 166, 213, 37, 43, 154}, + { /* left mode 6 */ 61, 63, 30, 155, 67, 45, 68, 1, 209}, + { /* left mode 7 */ 142, 78, 78, 16, 255, 128, 34, 197, 171}, + { /* left mode 8 */ 41, 40, 5, 102, 211, 183, 4, 1, 221}, + { /* left mode 9 */ 51, 50, 17, 168, 209, 192, 23, 25, 82} + }, + { /* above mode 4 */ + { /* left mode 0 */ 125, 98, 42, 88, 104, 85, 117, 175, 82}, + { /* left mode 1 */ 95, 84, 53, 89, 128, 100, 113, 101, 45}, + { /* left mode 2 */ 75, 79, 123, 47, 51, 128, 81, 171, 1}, + { /* left mode 3 */ 57, 17, 5, 71, 102, 57, 53, 41, 49}, + { /* left mode 4 */ 115, 21, 2, 10, 102, 255, 166, 23, 6}, + { /* left mode 5 */ 38, 33, 13, 121, 57, 73, 26, 1, 85}, + { /* left mode 6 */ 41, 10, 67, 138, 77, 110, 90, 47, 114}, + { /* left mode 7 */ 101, 29, 16, 10, 85, 128, 101, 196, 26}, + { /* left mode 8 */ 57, 18, 10, 102, 102, 213, 34, 20, 43}, + { /* left mode 9 */ 117, 20, 15, 36, 163, 128, 68, 1, 26} + }, + { /* above mode 5 */ + { /* left mode 0 */ 138, 31, 36, 171, 27, 166, 38, 44, 229}, + { /* left mode 1 */ 67, 87, 58, 169, 82, 115, 26, 59, 179}, + { /* left mode 2 */ 63, 59, 90, 180, 59, 166, 93, 73, 154}, + { /* left mode 3 */ 40, 40, 21, 116, 143, 209, 34, 39, 175}, + { /* left mode 4 */ 57, 46, 22, 24, 128, 1, 54, 17, 37}, + { /* left mode 5 */ 47, 15, 16, 183, 34, 223, 49, 45, 183}, + { /* left mode 6 */ 46, 17, 33, 183, 6, 98, 15, 32, 183}, + { /* left mode 7 */ 65, 32, 73, 115, 28, 128, 23, 128, 205}, + { /* left mode 8 */ 40, 3, 9, 115, 51, 192, 18, 6, 223}, + { /* left mode 9 */ 87, 37, 9, 115, 59, 77, 64, 21, 47} + }, + { /* above mode 6 */ + { /* left mode 0 */ 104, 55, 44, 218, 9, 54, 53, 130, 226}, + { /* left mode 1 */ 64, 90, 70, 205, 40, 41, 23, 26, 57}, + { /* left mode 2 */ 54, 57, 112, 184, 5, 41, 38, 166, 213}, + { /* left mode 3 */ 30, 34, 26, 133, 152, 116, 10, 32, 134}, + { /* left mode 4 */ 75, 32, 12, 51, 192, 255, 160, 43, 51}, + + + +Bankoski, et al. Informational [Page 194] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + { /* left mode 5 */ 39, 19, 53, 221, 26, 114, 32, 73, 255}, + { /* left mode 6 */ 31, 9, 65, 234, 2, 15, 1, 118, 73}, + { /* left mode 7 */ 88, 31, 35, 67, 102, 85, 55, 186, 85}, + { /* left mode 8 */ 56, 21, 23, 111, 59, 205, 45, 37, 192}, + { /* left mode 9 */ 55, 38, 70, 124, 73, 102, 1, 34, 98} + }, + { /* above mode 7 */ + { /* left mode 0 */ 102, 61, 71, 37, 34, 53, 31, 243, 192}, + { /* left mode 1 */ 69, 60, 71, 38, 73, 119, 28, 222, 37}, + { /* left mode 2 */ 68, 45, 128, 34, 1, 47, 11, 245, 171}, + { /* left mode 3 */ 62, 17, 19, 70, 146, 85, 55, 62, 70}, + { /* left mode 4 */ 75, 15, 9, 9, 64, 255, 184, 119, 16}, + { /* left mode 5 */ 37, 43, 37, 154, 100, 163, 85, 160, 1}, + { /* left mode 6 */ 63, 9, 92, 136, 28, 64, 32, 201, 85}, + { /* left mode 7 */ 86, 6, 28, 5, 64, 255, 25, 248, 1}, + { /* left mode 8 */ 56, 8, 17, 132, 137, 255, 55, 116, 128}, + { /* left mode 9 */ 58, 15, 20, 82, 135, 57, 26, 121, 40} + }, + { /* above mode 8 */ + { /* left mode 0 */ 164, 50, 31, 137, 154, 133, 25, 35, 218}, + { /* left mode 1 */ 51, 103, 44, 131, 131, 123, 31, 6, 158}, + { /* left mode 2 */ 86, 40, 64, 135, 148, 224, 45, 183, 128}, + { /* left mode 3 */ 22, 26, 17, 131, 240, 154, 14, 1, 209}, + { /* left mode 4 */ 83, 12, 13, 54, 192, 255, 68, 47, 28}, + { /* left mode 5 */ 45, 16, 21, 91, 64, 222, 7, 1, 197}, + { /* left mode 6 */ 56, 21, 39, 155, 60, 138, 23, 102, 213}, + { /* left mode 7 */ 85, 26, 85, 85, 128, 128, 32, 146, 171}, + { /* left mode 8 */ 18, 11, 7, 63, 144, 171, 4, 4, 246}, + { /* left mode 9 */ 35, 27, 10, 146, 174, 171, 12, 26, 128} + }, + { /* above mode 9 */ + { /* left mode 0 */ 190, 80, 35, 99, 180, 80, 126, 54, 45}, + { /* left mode 1 */ 85, 126, 47, 87, 176, 51, 41, 20, 32}, + { /* left mode 2 */ 101, 75, 128, 139, 118, 146, 116, 128, 85}, + { /* left mode 3 */ 56, 41, 15, 176, 236, 85, 37, 9, 62}, + { /* left mode 4 */ 146, 36, 19, 30, 171, 255, 97, 27, 20}, + { /* left mode 5 */ 71, 30, 17, 119, 118, 255, 17, 18, 138}, + { /* left mode 6 */ 101, 38, 60, 138, 55, 70, 43, 26, 142}, + { /* left mode 7 */ 138, 45, 61, 62, 219, 1, 81, 188, 64}, + { /* left mode 8 */ 32, 41, 20, 117, 151, 142, 20, 21, 163}, + { /* left mode 9 */ 112, 19, 12, 61, 195, 128, 48, 4, 24} + } + }; + + + + + + + + +Bankoski, et al. Informational [Page 195] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static const int kf_y_mode_tree[] = + { + -B_PRED, 2, + 4, 6, + -DC_PRED, -V_PRED, + -H_PRED, -TM_PRED + }; + static const int y_mode_tree[] = + { + -DC_PRED, 2, + 4, 6, + -V_PRED, -H_PRED, + -TM_PRED, -B_PRED + }; + static const int uv_mode_tree[6] = + { + -DC_PRED, 2, + -V_PRED, 4, + -H_PRED, -TM_PRED + }; + static const int b_mode_tree[18] = + { + -B_DC_PRED, 2, /* 0 = DC_NODE */ + -B_TM_PRED, 4, /* 1 = TM_NODE */ + -B_VE_PRED, 6, /* 2 = VE_NODE */ + 8, 12, /* 3 = COM_NODE */ + -B_HE_PRED, 10, /* 4 = HE_NODE */ + -B_RD_PRED, -B_VR_PRED, /* 5 = RD_NODE */ + -B_LD_PRED, 14, /* 6 = LD_NODE */ + -B_VL_PRED, 16, /* 7 = VL_NODE */ + -B_HD_PRED, -B_HU_PRED /* 8 = HD_NODE */ + }; + static const int small_mv_tree[14] = + { + 2, 8, + 4, 6, + -0, -1, + -2, -3, + 10, 12, + -4, -5, + -6, -7 + }; + + + + + + + + + +Bankoski, et al. Informational [Page 196] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static const int mv_ref_tree[8] = + { + -ZEROMV, 2, + -NEARESTMV, 4, + -NEARMV, 6, + -NEWMV, -SPLITMV + }; + static const int submv_ref_tree[6] = + { + -LEFT4X4, 2, + -ABOVE4X4, 4, + -ZERO4X4, -NEW4X4 + }; + static const int split_mv_tree[6] = + { + -3, 2, + -2, 4, + -0, -1 + }; + static const unsigned char default_b_mode_probs[] = + { 120, 90, 79, 133, 87, 85, 80, 111, 151}; + static const unsigned char mv_counts_to_probs[6][4] = + { + { 7, 1, 1, 143 }, + { 14, 18, 14, 107 }, + { 135, 64, 57, 68 }, + { 60, 56, 128, 65 }, + { 159, 134, 128, 34 }, + { 234, 188, 128, 28 } + + }; + static const unsigned char split_mv_probs[3] = + { 110, 111, 150}; + + static const unsigned char submv_ref_probs2[5][3] = + { + { 147, 136, 18 }, + { 106, 145, 1 }, + { 179, 121, 1 }, + { 223, 1, 34 }, + { 208, 1, 1 } + }; + + + + + + + + + +Bankoski, et al. Informational [Page 197] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + const static int mv_partitions[4][16] = + { + {0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1 }, + {0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1 }, + {0, 0, 1, 1, 0, 0, 1, 1, 2, 2, 3, 3, 2, 2, 3, 3 }, + {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } + }; + + ---- End code block ---------------------------------------- + +20.14. predict.c + + ---- Begin code block -------------------------------------- + + /* + * Copyright (c) 2010, 2011, Google Inc. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be + * found in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + #include "dixie.h" + #include "predict.h" + #include "idct_add.h" + #include "mem.h" + #include <assert.h> + #include <string.h> + + enum + { + BORDER_PIXELS = 16, + }; + + + static const filter_t sixtap_filters[8] = + { + { 0, 0, 128, 0, 0, 0 }, + { 0, -6, 123, 12, -1, 0 }, + { 2, -11, 108, 36, -8, 1 }, + { 0, -9, 93, 50, -6, 0 }, + { 3, -16, 77, 77, -16, 3 }, + { 0, -6, 50, 93, -9, 0 }, + { 1, -8, 36, 108, -11, 2 }, + { 0, -1, 12, 123, -6, 0 } + }; + + + + +Bankoski, et al. Informational [Page 198] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static const filter_t bilinear_filters[8] = + { + { 0, 0, 128, 0, 0, 0 }, + { 0, 0, 112, 16, 0, 0 }, + { 0, 0, 96, 32, 0, 0 }, + { 0, 0, 80, 48, 0, 0 }, + { 0, 0, 64, 64, 0, 0 }, + { 0, 0, 48, 80, 0, 0 }, + { 0, 0, 32, 96, 0, 0 }, + { 0, 0, 16, 112, 0, 0 } + }; + + + static void + predict_h_nxn(unsigned char *predict, + int stride, + int n) + { + unsigned char *left = predict - 1; + int i, j; + + for (i = 0; i < n; i++) + for (j = 0; j < n; j++) + predict[i *stride + j] = left[i * stride]; + } + + + static void + predict_v_nxn(unsigned char *predict, + int stride, + int n) + { + unsigned char *above = predict - stride; + int i, j; + + for (i = 0; i < n; i++) + for (j = 0; j < n; j++) + predict[i *stride + j] = above[j]; + } + + + + + + + + + + + + +Bankoski, et al. Informational [Page 199] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static void + predict_tm_nxn(unsigned char *predict, + int stride, + int n) + { + /* Transposes the left column to the top row for later + * consumption by the idct/recon stage + */ + unsigned char *left = predict - 1; + unsigned char *above = predict - stride; + unsigned char p = above[-1]; + int i, j; + + for (j = 0; j < n; j++) + { + for (i = 0; i < n; i++) + predict[i] = CLAMP_255(*left + above[i] - p); + + predict += stride; + left += stride; + } + } + + static void + predict_dc_nxn(unsigned char *predict, + int stride, + int n) + { + unsigned char *left = predict - 1; + unsigned char *above = predict - stride; + int i, j, dc = 0; + + for (i = 0; i < n; i++) + { + dc += *left + above[i]; + left += stride; + } + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 200] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + switch (n) + { + case 16: + dc = (dc + 16) >> 5; + break; + case 8: + dc = (dc + 8) >> 4; + break; + case 4: + dc = (dc + 4) >> 3; + break; + } + + for (i = 0; i < n; i++) + for (j = 0; j < n; j++) + predict[i *stride + j] = dc; + } + + + static void + predict_ve_4x4(unsigned char *predict, + int stride) + { + unsigned char *above = predict - stride; + int i, j; + + predict[0] = (above[-1] + 2 * above[0] + above[1] + 2) >> 2; + predict[1] = (above[ 0] + 2 * above[1] + above[2] + 2) >> 2; + predict[2] = (above[ 1] + 2 * above[2] + above[3] + 2) >> 2; + predict[3] = (above[ 2] + 2 * above[3] + above[4] + 2) >> 2; + + for (i = 1; i < 4; i++) + for (j = 0; j < 4; j++) + predict[i *stride + j] = predict[j]; + } + + + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 201] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static void + predict_he_4x4(unsigned char *predict, + int stride) + { + unsigned char *left = predict - 1; + + predict[0] = + predict[1] = + predict[2] = + predict[3] = (left[-stride] + 2 * left[0] + + left[stride] + 2) >> 2; + predict += stride; + left += stride; + + predict[0] = + predict[1] = + predict[2] = + predict[3] = (left[-stride] + 2 * left[0] + + left[stride] + 2) >> 2; + predict += stride; + left += stride; + + predict[0] = + predict[1] = + predict[2] = + predict[3] = (left[-stride] + 2 * left[0] + + left[stride] + 2) >> 2; + predict += stride; + left += stride; + + predict[0] = + predict[1] = + predict[2] = + predict[3] = (left[-stride] + 2 * left[0] + left[0] + 2) >> 2; + } + + + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 202] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static void + predict_ld_4x4(unsigned char *predict, + int stride) + { + unsigned char *above = predict - stride; + int pred0, pred1, pred2, pred3, pred4, pred5, pred6; + + predict[0] = pred0 = (above[0] + 2 * above[1] + + above[2] + 2) >> 2; + predict[1] = pred1 = (above[1] + 2 * above[2] + + above[3] + 2) >> 2; + predict[2] = pred2 = (above[2] + 2 * above[3] + + above[4] + 2) >> 2; + predict[3] = pred3 = (above[3] + 2 * above[4] + + above[5] + 2) >> 2; + predict += stride; + + predict[0] = pred1; + predict[1] = pred2; + predict[2] = pred3; + predict[3] = pred4 = (above[4] + 2 * above[5] + + above[6] + 2) >> 2; + predict += stride; + + predict[0] = pred2; + predict[1] = pred3; + predict[2] = pred4; + predict[3] = pred5 = (above[5] + 2 * above[6] + + above[7] + 2) >> 2; + predict += stride; + + predict[0] = pred3; + predict[1] = pred4; + predict[2] = pred5; + predict[3] = pred6 = (above[6] + 2 * above[7] + + above[7] + 2) >> 2; + } + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 203] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static void + predict_rd_4x4(unsigned char *predict, + int stride) + { + unsigned char *left = predict - 1; + unsigned char *above = predict - stride; + int pred0, pred1, pred2, pred3, pred4, pred5, pred6; + + predict[0] = pred0 = + (left[ 0] + 2 * above[-1] + above[0] + 2) >> 2; + predict[1] = pred1 = + (above[-1] + 2 * above[ 0] + above[1] + 2) >> 2; + predict[2] = pred2 = + (above[ 0] + 2 * above[ 1] + above[2] + 2) >> 2; + predict[3] = pred3 = + (above[ 1] + 2 * above[ 2] + above[3] + 2) >> 2; + predict += stride; + + predict[0] = pred4 = + (left[stride] + 2 * left[0] + above[-1] + 2) >> 2; + predict[1] = pred0; + predict[2] = pred1; + predict[3] = pred2; + predict += stride; + + predict[0] = pred5 = + (left[stride*2] + 2 * left[stride] + left[0] + 2) >> 2; + predict[1] = pred4; + predict[2] = pred0; + predict[3] = pred1; + predict += stride; + + predict[0] = pred6 = (left[stride*3] + 2 * left[stride*2] + + left[stride] + 2) >> 2; + predict[1] = pred5; + predict[2] = pred4; + predict[3] = pred0; + } + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 204] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static void + predict_vr_4x4(unsigned char *predict, + int stride) + { + unsigned char *left = predict - 1; + unsigned char *above = predict - stride; + int pred0, pred1, pred2, pred3, pred4, pred5, pred6, + pred7, pred8, pred9; + + predict[0] = pred0 = (above[-1] + above[0] + 1) >> 1; + predict[1] = pred1 = (above[ 0] + above[1] + 1) >> 1; + predict[2] = pred2 = (above[ 1] + above[2] + 1) >> 1; + predict[3] = pred3 = (above[ 2] + above[3] + 1) >> 1; + predict += stride; + + predict[0] = pred4 = (left[ 0] + 2 * above[-1] + + above[0] + 2) >> 2; + predict[1] = pred5 = (above[-1] + 2 * above[ 0] + + above[1] + 2) >> 2; + predict[2] = pred6 = (above[ 0] + 2 * above[ 1] + + above[2] + 2) >> 2; + predict[3] = pred7 = (above[ 1] + 2 * above[ 2] + + above[3] + 2) >> 2; + predict += stride; + + predict[0] = pred8 = + (left[stride] + 2 * left[0] + above[-1] + 2) >> 2; + predict[1] = pred0; + predict[2] = pred1; + predict[3] = pred2; + predict += stride; + + predict[0] = pred9 = + (left[stride*2] + 2 * left[stride] + left[0] + 2) >> 2; + predict[1] = pred4; + predict[2] = pred5; + predict[3] = pred6; + } + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 205] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static void + predict_vl_4x4(unsigned char *predict, + int stride) + { + unsigned char *above = predict - stride; + int pred0, pred1, pred2, pred3, pred4, pred5, pred6, + pred7, pred8, pred9; + + predict[0] = pred0 = (above[0] + above[1] + 1) >> 1; + predict[1] = pred1 = (above[1] + above[2] + 1) >> 1; + predict[2] = pred2 = (above[2] + above[3] + 1) >> 1; + predict[3] = pred3 = (above[3] + above[4] + 1) >> 1; + predict += stride; + + predict[0] = pred4 = (above[0] + 2 * above[1] + + above[2] + 2) >> 2; + predict[1] = pred5 = (above[1] + 2 * above[2] + + above[3] + 2) >> 2; + predict[2] = pred6 = (above[2] + 2 * above[3] + + above[4] + 2) >> 2; + predict[3] = pred7 = (above[3] + 2 * above[4] + + above[5] + 2) >> 2; + predict += stride; + + predict[0] = pred1; + predict[1] = pred2; + predict[2] = pred3; + predict[3] = pred8 = (above[4] + 2 * above[5] + + above[6] + 2) >> 2; + predict += stride; + + predict[0] = pred5; + predict[1] = pred6; + predict[2] = pred7; + predict[3] = pred9 = (above[5] + 2 * above[6] + + above[7] + 2) >> 2; + } + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 206] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static void + predict_hd_4x4(unsigned char *predict, + int stride) + { + unsigned char *left = predict - 1; + unsigned char *above = predict - stride; + int pred0, pred1, pred2, pred3, pred4, pred5, pred6, + pred7, pred8, pred9; + + predict[0] = pred0 = (left[ 0] + above[-1] + 1) >> 1; + predict[1] = pred1 = (left[ 0] + 2 * above[-1] + + above[0] + 2) >> 2; + predict[2] = pred2 = (above[-1] + 2 * above[ 0] + + above[1] + 2) >> 2; + predict[3] = pred3 = (above[ 0] + 2 * above[ 1] + + above[2] + 2) >> 2; + predict += stride; + + predict[0] = pred4 = (left[stride] + left[0] + 1) >> 1; + predict[1] = pred5 = (left[stride] + 2 * left[0] + + above[-1] + 2) >> 2; + predict[2] = pred0; + predict[3] = pred1; + predict += stride; + + predict[0] = pred6 = (left[stride*2] + left[stride] + 1) >> 1; + predict[1] = pred7 = (left[stride*2] + 2 * left[stride] + + left[0] + 2) >> 2; + predict[2] = pred4; + predict[3] = pred5; + predict += stride; + + predict[0] = pred8 = (left[stride*3] + left[stride*2] + 1) >> 1; + predict[1] = pred9 = (left[stride*3] + 2 * left[stride*2] + + left[stride] + 2) >> 2; + predict[2] = pred6; + predict[3] = pred7; + } + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 207] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static void + predict_hu_4x4(unsigned char *predict, + int stride) + { + unsigned char *left = predict - 1; + int pred0, pred1, pred2, pred3, pred4, pred5, pred6; + + predict[0] = pred0 = (left[stride*0] + + left[stride*1] + 1) >> 1; + predict[1] = pred1 = (left[stride*0] + 2 * left[stride*1] + + left[stride*2] + 2) >> 2; + predict[2] = pred2 = (left[stride*1] + left[stride*2] + 1) >> 1; + predict[3] = pred3 = (left[stride*1] + 2 * left[stride*2] + + left[stride*3] + 2) >> 2; + predict += stride; + + predict[0] = pred2; + predict[1] = pred3; + predict[2] = pred4 = (left[stride*2] + left[stride*3] + 1) >> 1; + predict[3] = pred5 = (left[stride*2] + 2 * left[stride*3] + + left[stride*3] + 2) >> 2; + predict += stride; + + predict[0] = pred4; + predict[1] = pred5; + predict[2] = pred6 = left[stride*3]; + predict[3] = pred6; + predict += stride; + + predict[0] = pred6; + predict[1] = pred6; + predict[2] = pred6; + predict[3] = pred6; + } + + + static void + predict_h_16x16(unsigned char *predict, int stride) + { + predict_h_nxn(predict, stride, 16); + } + + + static void + predict_v_16x16(unsigned char *predict, int stride) + { + predict_v_nxn(predict, stride, 16); + } + + + +Bankoski, et al. Informational [Page 208] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static void + predict_tm_16x16(unsigned char *predict, int stride) + { + predict_tm_nxn(predict, stride, 16); + } + + + static void + predict_h_8x8(unsigned char *predict, int stride) + { + predict_h_nxn(predict, stride, 8); + } + + + static void + predict_v_8x8(unsigned char *predict, int stride) + { + predict_v_nxn(predict, stride, 8); + } + + static void + predict_tm_8x8(unsigned char *predict, int stride) + { + predict_tm_nxn(predict, stride, 8); + } + + + static void + predict_tm_4x4(unsigned char *predict, int stride) + { + predict_tm_nxn(predict, stride, 4); + } + + + static void + copy_down(unsigned char *recon, + int stride) + { + /* Copy the four pixels above-right of subblock 3 to + * above-right of subblocks 7, 11, and 15 + */ + uint32_t tmp, *copy = (void *)(recon + 16 - stride); + + + + + + + + + +Bankoski, et al. Informational [Page 209] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + stride = stride / sizeof(unsigned int); + tmp = *copy; + copy += stride * 4; + *copy = tmp; + copy += stride * 4; + *copy = tmp; + copy += stride * 4; + *copy = tmp; + } + + + static void + b_pred(unsigned char *predict, + int stride, + struct mb_info *mbi, + short *coeffs) + { + int i; + + copy_down(predict, stride); + + for (i = 0; i < 16; i++) + { + unsigned char *b_predict = predict + (i & 3) * 4; + + switch (mbi->split.modes[i]) + { + case B_DC_PRED: + predict_dc_nxn(b_predict, stride, 4); + break; + case B_TM_PRED: + predict_tm_4x4(b_predict, stride); + break; + case B_VE_PRED: + predict_ve_4x4(b_predict, stride); + break; + case B_HE_PRED: + predict_he_4x4(b_predict, stride); + break; + case B_LD_PRED: + predict_ld_4x4(b_predict, stride); + break; + case B_RD_PRED: + predict_rd_4x4(b_predict, stride); + break; + case B_VR_PRED: + predict_vr_4x4(b_predict, stride); + break; + + + +Bankoski, et al. Informational [Page 210] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + case B_VL_PRED: + predict_vl_4x4(b_predict, stride); + break; + case B_HD_PRED: + predict_hd_4x4(b_predict, stride); + break; + case B_HU_PRED: + predict_hu_4x4(b_predict, stride); + break; + default: + assert(0); + } + + vp8_dixie_idct_add(b_predict, b_predict, stride, coeffs); + coeffs += 16; + + if ((i & 3) == 3) + { + predict += stride * 4; + } + } + } + + + static void + + fixup_dc_coeffs(struct mb_info *mbi, + short *coeffs) + { + short y2[16]; + int i; + + vp8_dixie_walsh(coeffs + 24 * 16, y2); + + for (i = 0; i < 16; i++) + coeffs[i*16] = y2[i]; + } + + + static void + predict_intra_luma(unsigned char *predict, + int stride, + struct mb_info *mbi, + short *coeffs) + { + if (mbi->base.y_mode == B_PRED) + b_pred(predict, stride, mbi, coeffs); + else + + + +Bankoski, et al. Informational [Page 211] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + { + int i; + + switch (mbi->base.y_mode) + { + case DC_PRED: + predict_dc_nxn(predict, stride, 16); + break; + case V_PRED: + predict_v_16x16(predict, stride); + break; + case H_PRED: + predict_h_16x16(predict, stride); + break; + case TM_PRED: + predict_tm_16x16(predict, stride); + break; + default: + assert(0); + } + + fixup_dc_coeffs(mbi, coeffs); + + for (i = 0; i < 16; i++) + { + vp8_dixie_idct_add(predict, predict, stride, coeffs); + coeffs += 16; + predict += 4; + + if ((i & 3) == 3) + predict += stride * 4 - 16; + } + } + } + + + static void + predict_intra_chroma(unsigned char *predict_u, + unsigned char *predict_v, + int stride, + struct mb_info *mbi, + short *coeffs) + { + int i; + + + + + + + +Bankoski, et al. Informational [Page 212] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + switch (mbi->base.uv_mode) + { + case DC_PRED: + predict_dc_nxn(predict_u, stride, 8); + predict_dc_nxn(predict_v, stride, 8); + break; + case V_PRED: + predict_v_8x8(predict_u, stride); + predict_v_8x8(predict_v, stride); + break; + case H_PRED: + predict_h_8x8(predict_u, stride); + predict_h_8x8(predict_v, stride); + break; + case TM_PRED: + predict_tm_8x8(predict_u, stride); + predict_tm_8x8(predict_v, stride); + break; + default: + assert(0); + } + + coeffs += 16 * 16; + + for (i = 16; i < 20; i++) + { + vp8_dixie_idct_add(predict_u, predict_u, stride, coeffs); + coeffs += 16; + predict_u += 4; + + if (i & 1) + predict_u += stride * 4 - 8; + } + + for (i = 20; i < 24; i++) + { + vp8_dixie_idct_add(predict_v, predict_v, stride, coeffs); + coeffs += 16; + predict_v += 4; + + if (i & 1) + predict_v += stride * 4 - 8; + } + } + + + + + + + +Bankoski, et al. Informational [Page 213] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static void + sixtap_horiz(unsigned char *output, + int output_stride, + const unsigned char *reference, + int reference_stride, + int cols, + int rows, + const filter_t filter + ) + { + int r, c, temp; + + for (r = 0; r < rows; r++) + { + for (c = 0; c < cols; c++) + { + temp = (reference[-2] * filter[0]) + + (reference[-1] * filter[1]) + + (reference[ 0] * filter[2]) + + (reference[ 1] * filter[3]) + + (reference[ 2] * filter[4]) + + (reference[ 3] * filter[5]) + + 64; + temp >>= 7; + output[c] = CLAMP_255(temp); + reference++; + } + + reference += reference_stride - cols; + output += output_stride; + } + } + + + static void + sixtap_vert(unsigned char *output, + int output_stride, + const unsigned char *reference, + int reference_stride, + int cols, + int rows, + const filter_t filter + ) + { + int r, c, temp; + + for (r = 0; r < rows; r++) + { + + + +Bankoski, et al. Informational [Page 214] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + for (c = 0; c < cols; c++) + { + temp = (reference[-2*reference_stride] * filter[0]) + + (reference[-1*reference_stride] * filter[1]) + + (reference[ 0*reference_stride] * filter[2]) + + (reference[ 1*reference_stride] * filter[3]) + + (reference[ 2*reference_stride] * filter[4]) + + (reference[ 3*reference_stride] * filter[5]) + + 64; + temp >>= 7; + output[c] = CLAMP_255(temp); + reference++; + } + + reference += reference_stride - cols; + output += output_stride; + } + } + + + static void + sixtap_2d(unsigned char *output, + int output_stride, + const unsigned char *reference, + int reference_stride, + int cols, + int rows, + int mx, + int my, + const filter_t filters[8] + ) + { + DECLARE_ALIGNED(16, unsigned char, temp[16*(16+5)]); + + sixtap_horiz(temp, 16, + reference - 2 * reference_stride, reference_stride, + cols, rows + 5, filters[mx]); + sixtap_vert(output, output_stride, + temp + 2 * 16, 16, + cols, rows, filters[my]); + } + + + struct img_index + { + unsigned char *y, *u, *v; + int stride, uv_stride; + }; + + + +Bankoski, et al. Informational [Page 215] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static const unsigned char * + filter_block(unsigned char *output, + const unsigned char *reference, + int stride, + const union mv *mv, + const filter_t filters[8]) + { + int mx, my; + + /* Handle 0,0 as a special case. TODO: Does this make it any + * faster? + */ + if (!mv->raw) + return reference; + + mx = mv->d.x & 7; + my = mv->d.y & 7; + reference += ((mv->d.y >> 3) * stride) + (mv->d.x >> 3); + + if (mx | my) + { + sixtap_2d(output, stride, reference, stride, 4, 4, mx, my, + filters); + reference = output; + } + + return reference; + } + + + static void + recon_1_block(unsigned char *output, + const unsigned char *reference, + int stride, + const union mv *mv, + const filter_t filters[8], + short *coeffs, + struct mb_info *mbi, + int b + ) + { + const unsigned char *predict; + + predict = filter_block(output, reference, stride, mv, filters); + vp8_dixie_idct_add(output, predict, stride, coeffs + 16 * b); + } + + + + + +Bankoski, et al. Informational [Page 216] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static mv_t + calculate_chroma_splitmv(struct mb_info *mbi, + int b, + int full_pixel) + { + int temp; + union mv mv; + + temp = mbi->split.mvs[b].d.x + + mbi->split.mvs[b+1].d.x + + mbi->split.mvs[b+4].d.x + + mbi->split.mvs[b+5].d.x; + + if (temp < 0) + temp -= 4; + else + temp += 4; + + mv.d.x = temp / 8; + + temp = mbi->split.mvs[b].d.y + + mbi->split.mvs[b+1].d.y + + mbi->split.mvs[b+4].d.y + + mbi->split.mvs[b+5].d.y; + + if (temp < 0) + temp -= 4; + else + temp += 4; + + mv.d.y = temp / 8; + + if (full_pixel) + { + mv.d.x &= ~7; + mv.d.y &= ~7; + } + + return mv; + } + + + + + + + + + + + +Bankoski, et al. Informational [Page 217] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /* Note: We rely on the reconstructed border having the same stride + * as the reference buffer because the filter_block can't adjust the + * stride with its return value, only the reference pointer. + */ + static void + build_mc_border(unsigned char *dst, + const unsigned char *src, + int stride, + int x, + int y, + int b_w, + int b_h, + int w, + int h + ) + { + const unsigned char *ref_row; + + + /* Get a pointer to the start of the real data for this row */ + ref_row = src - x - y * stride; + + if (y >= h) + ref_row += (h - 1) * stride; + else if (y > 0) + ref_row += y * stride; + + do + { + int left, right = 0, copy; + + left = x < 0 ? -x : 0; + + if (left > b_w) + left = b_w; + + if (x + b_w > w) + right = x + b_w - w; + + if (right > b_w) + right = b_w; + + + + + + + + + + +Bankoski, et al. Informational [Page 218] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + copy = b_w - left - right; + + if (left) + memset(dst, ref_row[0], left); + + if (copy) + memcpy(dst + left, ref_row + x + left, copy); + + if (right) + memset(dst + left + copy, ref_row[w-1], right); + + dst += stride; + y++; + + if (y < h && y > 0) + ref_row += stride; + } + while (--b_h); + } + + + static void + recon_1_edge_block(unsigned char *output, + unsigned char *emul_block, + const unsigned char *reference, + int stride, + const union mv *mv, + const filter_t filters[8], + short *coeffs, + struct mb_info *mbi, + int x, + int y, + int w, + int h, + int start_b + ) + { + const unsigned char *predict; + int b = start_b; + const int b_w = 4; + const int b_h = 4; + + x += mv->d.x >> 3; + y += mv->d.y >> 3; + + + + + + + +Bankoski, et al. Informational [Page 219] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /* Need two pixels left/above, 3 right/below for 6-tap */ + if (x < 2 || x + b_w - 1 + 3 >= w || y < 2 || + y + b_h - 1 + 3 >= h) + { + reference += (mv->d.x >> 3) + (mv->d.y >> 3) * stride; + build_mc_border(emul_block, + reference - 2 - 2 * stride, stride, + x - 2, y - 2, b_w + 5, b_h + 5, w, h); + reference = emul_block + 2 * stride + 2; + reference -= (mv->d.x >> 3) + (mv->d.y >> 3) * stride; + } + + predict = filter_block(output, reference, stride, mv, filters); + vp8_dixie_idct_add(output, predict, stride, coeffs + 16 * b); + } + + + static void + predict_inter_emulated_edge(struct vp8_decoder_ctx *ctx, + struct img_index *img, + short *coeffs, + struct mb_info *mbi, + int mb_col, + int mb_row) + { + /* TODO: Move this into its own buffer. This only works because + * we still have a border allocated. + */ + unsigned char *emul_block = ctx->frame_strg[0].img.img_data; + unsigned char *reference; + unsigned char *output; + ptrdiff_t reference_offset; + int w, h, x, y, b; + union mv chroma_mv[4]; + unsigned char *u = img->u, *v = img->v; + int full_pixel = ctx->frame_hdr.version == 3; + + + x = mb_col * 16; + y = mb_row * 16; + w = ctx->mb_cols * 16; + h = ctx->mb_rows * 16; + + output = img->y; + reference_offset = ctx->ref_frame_offsets[mbi->base.ref_frame]; + reference = output + reference_offset; + + + + + +Bankoski, et al. Informational [Page 220] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + if (mbi->base.y_mode != SPLITMV) + { + union mv uvmv; + + uvmv = mbi->base.mv; + uvmv.d.x = (uvmv.d.x + 1 + (uvmv.d.x >> 31) * 2) / 2; + uvmv.d.y = (uvmv.d.y + 1 + (uvmv.d.y >> 31) * 2) / 2; + + if (full_pixel) + { + uvmv.d.x &= ~7; + uvmv.d.y &= ~7; + } + + chroma_mv[0] = uvmv; + chroma_mv[1] = uvmv; + chroma_mv[2] = uvmv; + chroma_mv[3] = uvmv; + } + else + { + chroma_mv[0] = calculate_chroma_splitmv(mbi, 0, full_pixel); + chroma_mv[1] = calculate_chroma_splitmv(mbi, 2, full_pixel); + chroma_mv[2] = calculate_chroma_splitmv(mbi, 8, full_pixel); + chroma_mv[3] = calculate_chroma_splitmv(mbi, 10, full_pixel); + } + + + /* Luma */ + for (b = 0; b < 16; b++) + { + union mv *ymv; + + if (mbi->base.y_mode != SPLITMV) + ymv = &mbi->base.mv; + else + ymv = mbi->split.mvs + b; + + recon_1_edge_block(output, emul_block, reference, + img->stride, ymv, ctx->subpixel_filters, coeffs, + mbi, x, y, w, h, b); + + x += 4; + output += 4; + reference += 4; + + + + + + +Bankoski, et al. Informational [Page 221] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + if ((b & 3) == 3) + { + x -= 16; + y += 4; + output += 4 * img->stride - 16; + reference += 4 * img->stride - 16; + } + } + + x = mb_col * 16; + y = mb_row * 16; + + /* Chroma */ + x >>= 1; + y >>= 1; + w >>= 1; + h >>= 1; + + for (b = 0; b < 4; b++) + { + recon_1_edge_block(u, emul_block, u + reference_offset, + img->uv_stride, + &chroma_mv[b], ctx->subpixel_filters, + coeffs, mbi, x, y, w, h, b + 16); + recon_1_edge_block(v, emul_block, v + reference_offset, + img->uv_stride, + &chroma_mv[b], ctx->subpixel_filters, + coeffs, mbi, x, y, w, h, b + 20); + u += 4; + v += 4; + x += 4; + + if (b & 1) + { + x -= 8; + y += 4; + u += 4 * img->uv_stride - 8; + v += 4 * img->uv_stride - 8; + } + } + + } + + static void + predict_inter(struct vp8_decoder_ctx *ctx, + struct img_index *img, + short *coeffs, + struct mb_info *mbi) + + + +Bankoski, et al. Informational [Page 222] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + { + unsigned char *y = img->y; + unsigned char *u = img->u; + unsigned char *v = img->v; + ptrdiff_t reference_offset; + union mv chroma_mv[4]; + int full_pixel = ctx->frame_hdr.version == 3; + int b; + + if (mbi->base.y_mode != SPLITMV) + { + union mv uvmv; + + uvmv = mbi->base.mv; + uvmv.d.x = (uvmv.d.x + 1 + (uvmv.d.x >> 31) * 2) / 2; + uvmv.d.y = (uvmv.d.y + 1 + (uvmv.d.y >> 31) * 2) / 2; + + if (full_pixel) + { + uvmv.d.x &= ~7; + uvmv.d.y &= ~7; + } + + chroma_mv[0] = + chroma_mv[1] = + chroma_mv[2] = + chroma_mv[3] = uvmv; + } + else + { + chroma_mv[0] = calculate_chroma_splitmv(mbi, 0, full_pixel); + chroma_mv[1] = calculate_chroma_splitmv(mbi, 2, full_pixel); + chroma_mv[2] = calculate_chroma_splitmv(mbi, 8, full_pixel); + chroma_mv[3] = calculate_chroma_splitmv(mbi, 10, full_pixel); + } + + reference_offset = ctx->ref_frame_offsets[mbi->base.ref_frame]; + + for (b = 0; b < 16; b++) + { + union mv *ymv; + + if (mbi->base.y_mode != SPLITMV) + ymv = &mbi->base.mv; + else + ymv = mbi->split.mvs + b; + recon_1_block(y, y + reference_offset, img->stride, + ymv, ctx->subpixel_filters, coeffs, mbi, b); + + + +Bankoski, et al. Informational [Page 223] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + y += 4; + + if ((b & 3) == 3) + y += 4 * img->stride - 16; + } + + for (b = 0; b < 4; b++) + { + recon_1_block(u, u + reference_offset, + img->uv_stride, &chroma_mv[b], + ctx->subpixel_filters, coeffs, mbi, b + 16); + recon_1_block(v, v + reference_offset, + img->uv_stride, &chroma_mv[b], + ctx->subpixel_filters, coeffs, mbi, b + 20); + u += 4; + v += 4; + + if (b & 1) + { + u += 4 * img->uv_stride - 8; + v += 4 * img->uv_stride - 8; + } + } + } + + + void + vp8_dixie_release_ref_frame(struct ref_cnt_img *rcimg) + { + if (rcimg) + { + assert(rcimg->ref_cnt); + rcimg->ref_cnt--; + } + } + + + struct ref_cnt_img * + vp8_dixie_ref_frame(struct ref_cnt_img *rcimg) + { + rcimg->ref_cnt++; + return rcimg; + } + + + + + + + + +Bankoski, et al. Informational [Page 224] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + struct ref_cnt_img * + vp8_dixie_find_free_ref_frame(struct ref_cnt_img *frames) + { + int i; + + for (i = 0; i < NUM_REF_FRAMES; i++) + if (frames[i].ref_cnt == 0) + { + frames[i].ref_cnt = 1; + return &frames[i]; + } + + assert(0); + return NULL; + } + + + static void + fixup_left(unsigned char *predict, + int width, + int stride, + unsigned int row, + enum prediction_mode mode) + { + /* The left column of out-of-frame pixels is taken to be 129, + * unless we're doing DC_PRED, in which case we duplicate the + * above row, unless this is also row 0, in which case we use + * 129. + */ + unsigned char *left = predict - 1; + int i; + + if (mode == DC_PRED && row) + { + unsigned char *above = predict - stride; + + for (i = 0; i < width; i++) + { + *left = above[i]; + left += stride; + } + } + else + { + /* Need to re-set the above row, in case the above MB was + * DC_PRED. + */ + left -= stride; + + + +Bankoski, et al. Informational [Page 225] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + for (i = -1; i < width; i++) + { + *left = 129; + left += stride; + } + } + } + + + static void + fixup_above(unsigned char *predict, + int width, + int stride, + unsigned int col, + enum prediction_mode mode) + { + /* The above row of out-of-frame pixels is taken to be 127, + * unless we're doing DC_PRED, in which case we duplicate the + * left col, unless this is also col 0, in which case we use + * 127. + */ + unsigned char *above = predict - stride; + int i; + + if (mode == DC_PRED && col) + { + unsigned char *left = predict - 1; + + for (i = 0; i < width; i++) + { + above[i] = *left; + left += stride; + } + } + else + /* Need to re-set the left col, in case the last MB was + * DC_PRED. + */ + memset(above - 1, 127, width + 1); + + memset(above + width, 127, 4); // for above-right subblock modes + } + + + + + + + + + +Bankoski, et al. Informational [Page 226] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + void + vp8_dixie_predict_init(struct vp8_decoder_ctx *ctx) + { + + int i; + unsigned char *this_frame_base; + + if (ctx->frame_hdr.frame_size_updated) + { + for (i = 0; i < NUM_REF_FRAMES; i++) + { + unsigned int w = ctx->mb_cols * 16 + BORDER_PIXELS * 2; + unsigned int h = ctx->mb_rows * 16 + BORDER_PIXELS * 2; + + vpx_img_free(&ctx->frame_strg[i].img); + ctx->frame_strg[i].ref_cnt = 0; + ctx->ref_frames[i] = NULL; + + if (!vpx_img_alloc(&ctx->frame_strg[i].img, + IMG_FMT_I420, w, h, 16)) + vpx_internal_error(&ctx->error, VPX_CODEC_MEM_ERROR, + "Failed to allocate %dx%d" + " framebuffer", + w, h); + + vpx_img_set_rect(&ctx->frame_strg[i].img, BORDER_PIXELS, + BORDER_PIXELS, ctx->frame_hdr.kf.w, + ctx->frame_hdr.kf.h); + + } + + if (ctx->frame_hdr.version) + ctx->subpixel_filters = bilinear_filters; + else + ctx->subpixel_filters = sixtap_filters; + } + + /* Find a free framebuffer to predict into */ + if (ctx->ref_frames[CURRENT_FRAME]) + vp8_dixie_release_ref_frame(ctx->ref_frames[CURRENT_FRAME]); + + ctx->ref_frames[CURRENT_FRAME] = + vp8_dixie_find_free_ref_frame(ctx->frame_strg); + this_frame_base = ctx->ref_frames[CURRENT_FRAME]->img.img_data; + + + + + + + +Bankoski, et al. Informational [Page 227] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /* Calculate offsets to the other reference frames */ + for (i = 0; i < NUM_REF_FRAMES; i++) + { + struct ref_cnt_img *ref = ctx->ref_frames[i]; + + ctx->ref_frame_offsets[i] = + ref ? ref->img.img_data - this_frame_base : 0; + } + + /* TODO: No need to do this on every frame... */ + } + + + void + vp8_dixie_predict_destroy(struct vp8_decoder_ctx *ctx) + { + int i; + + for (i = 0; i < NUM_REF_FRAMES; i++) + { + vpx_img_free(&ctx->frame_strg[i].img); + ctx->frame_strg[i].ref_cnt = 0; + ctx->ref_frames[i] = NULL; + } + } + + + void + vp8_dixie_predict_process_row(struct vp8_decoder_ctx *ctx, + unsigned int row, + unsigned int start_col, + unsigned int num_cols) + { + struct img_index img; + struct mb_info *mbi; + unsigned int col; + short *coeffs; + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 228] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /* Adjust pointers based on row, start_col */ + img.stride = + ctx->ref_frames[CURRENT_FRAME]->img.stride[PLANE_Y]; + img.uv_stride = + ctx->ref_frames[CURRENT_FRAME]->img.stride[PLANE_U]; + img.y = ctx->ref_frames[CURRENT_FRAME]->img.planes[PLANE_Y]; + img.u = ctx->ref_frames[CURRENT_FRAME]->img.planes[PLANE_U]; + img.v = ctx->ref_frames[CURRENT_FRAME]->img.planes[PLANE_V]; + img.y += (img.stride * row + start_col) * 16; + img.u += (img.uv_stride * row + start_col) * 8; + img.v += (img.uv_stride * row + start_col) * 8; + mbi = ctx->mb_info_rows[row] + start_col; + coeffs = ctx->tokens[row & + (ctx->token_hdr.partitions - 1)].coeffs + + 25 * 16 * start_col; + + /* Fix up the out-of-frame pixels */ + + if (start_col == 0) + { + fixup_left(img.y, 16, img.stride, row, mbi->base.y_mode); + fixup_left(img.u, 8, img.uv_stride, row, mbi->base.uv_mode); + fixup_left(img.v, 8, img.uv_stride, row, mbi->base.uv_mode); + + if (row == 0) + *(img.y - img.stride - 1) = 127; + } + + for (col = start_col; col < start_col + num_cols; col++) + { + if (row == 0) + { + fixup_above(img.y, 16, img.stride, col, + mbi->base.y_mode); + fixup_above(img.u, 8, img.uv_stride, col, + mbi->base.uv_mode); + fixup_above(img.v, 8, img.uv_stride, col, + mbi->base.uv_mode); + } + + if (mbi->base.y_mode <= B_PRED) + { + predict_intra_luma(img.y, img.stride, mbi, coeffs); + predict_intra_chroma(img.u, img.v, img.uv_stride, mbi, + coeffs); + } + + + + + +Bankoski, et al. Informational [Page 229] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + else + { + if (mbi->base.y_mode != SPLITMV) // && != BPRED + fixup_dc_coeffs(mbi, coeffs); + + if (mbi->base.need_mc_border) + predict_inter_emulated_edge(ctx, &img, coeffs, mbi, + col, row); + else + predict_inter(ctx, &img, coeffs, mbi); + } + + /* Advance to the next macroblock */ + mbi++; + img.y += 16; + img.u += 8; + img.v += 8; + coeffs += 25 * 16; + } + + if (col == ctx->mb_cols) + { + /* Extend the last row by four pixels for intra-prediction. + * This will be propagated later by copy_down. + */ + uint32_t *extend = (uint32_t *)(img.y + 15 * img.stride); + uint32_t val = 0x01010101 * img.y[-1 + 15 * img.stride]; + *extend = val; + } + } + + ---- End code block ---------------------------------------- + + + + + + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 230] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +20.15. predict.h + + ---- Begin code block -------------------------------------- + + /* + * Copyright (c) 2010, 2011, Google Inc. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be + * found in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + #ifndef PREDICT_H + #define PREDICT_H + + void + vp8_dixie_predict_init(struct vp8_decoder_ctx *ctx); + + + void + vp8_dixie_predict_destroy(struct vp8_decoder_ctx *ctx); + + + void + vp8_dixie_predict_process_row(struct vp8_decoder_ctx *ctx, + unsigned int row, + unsigned int start_col, + unsigned int num_cols); + + void + vp8_dixie_release_ref_frame(struct ref_cnt_img *rcimg); + + struct ref_cnt_img * + vp8_dixie_ref_frame(struct ref_cnt_img *rcimg); + + struct ref_cnt_img * + vp8_dixie_find_free_ref_frame(struct ref_cnt_img *frames); + + #endif + + ---- End code block ---------------------------------------- + + + + + + + + + +Bankoski, et al. Informational [Page 231] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +20.16. tokens.c + + ---- Begin code block -------------------------------------- + + /* + * Copyright (c) 2010, 2011, Google Inc. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be + * found in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + #include "vpx_codec_internal.h" + #include "dixie.h" + #include "tokens.h" + #include <stdlib.h> + #include <string.h> + #include <malloc.h> + + + enum + { + EOB_CONTEXT_NODE, + ZERO_CONTEXT_NODE, + ONE_CONTEXT_NODE, + LOW_VAL_CONTEXT_NODE, + TWO_CONTEXT_NODE, + THREE_CONTEXT_NODE, + HIGH_LOW_CONTEXT_NODE, + CAT_ONE_CONTEXT_NODE, + CAT_THREEFOUR_CONTEXT_NODE, + CAT_THREE_CONTEXT_NODE, + CAT_FIVE_CONTEXT_NODE + }; + enum + { + ZERO_TOKEN, + ONE_TOKEN, + TWO_TOKEN, + THREE_TOKEN, + FOUR_TOKEN, + DCT_VAL_CATEGORY1, + DCT_VAL_CATEGORY2, + DCT_VAL_CATEGORY3, + + + + + + +Bankoski, et al. Informational [Page 232] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + DCT_VAL_CATEGORY4, + DCT_VAL_CATEGORY5, + DCT_VAL_CATEGORY6, + DCT_EOB_TOKEN, + MAX_ENTROPY_TOKENS + }; + struct extrabits + { + short min_val; + short length; + unsigned char probs[12]; + }; + static const unsigned int left_context_index[25] = + { + 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, + 4, 4, 5, 5, 6, 6, 7, 7, 8 + }; + static const unsigned int above_context_index[25] = + { + 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, + 4, 5, 4, 5, 6, 7, 6, 7, 8 + }; + #define X(n) ((n) * PREV_COEFF_CONTEXTS * ENTROPY_NODES) + static const unsigned int bands_x[16] = + { + X(0), X(1), X(2), X(3), X(6), X(4), X(5), X(6), + X(6), X(6), X(6), X(6), X(6), X(6), X(6), X(7) + }; + #undef X + static const struct extrabits extrabits[MAX_ENTROPY_TOKENS] = + { + { 0, -1, { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 } }, //ZERO_TOKEN + { 1, 0, { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 } }, //ONE_TOKEN + { 2, 0, { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 } }, //TWO_TOKEN + { 3, 0, { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 } }, //THREE_TOKEN + { 4, 0, { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 } }, //FOUR_TOKEN + { 5, 0, {159, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 } }, //DCT_VAL_CATEGORY1 + { 7, 1, {145, 165, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 } }, //DCT_VAL_CATEGORY2 + {11, 2, {140, 148, 173, 0, 0, 0, + 0, 0, 0, 0, 0, 0 } }, //DCT_VAL_CATEGORY3 + + + + +Bankoski, et al. Informational [Page 233] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + {19, 3, {135, 140, 155, 176, 0, 0, + 0, 0, 0, 0, 0, 0 } }, //DCT_VAL_CATEGORY4 + {35, 4, {130, 134, 141, 157, 180, 0, + 0, 0, 0, 0, 0, 0 } }, //DCT_VAL_CATEGORY5 + {67, 10, {129, 130, 133, 140, 153, 177, + 196, 230, 243, 254, 254, 0 } }, //DCT_VAL_CATEGORY6 + { 0, -1, { 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0 } }, // EOB TOKEN + }; + + static const unsigned int zigzag[16] = + { + 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 + }; + + #define DECODE_AND_APPLYSIGN(value_to_sign) \ + v = (bool_get_bit(bool) ? -value_to_sign \ + : value_to_sign) * dqf[!!c]; + + #define DECODE_AND_BRANCH_IF_ZERO(probability,branch) \ + if (!bool_get(bool, probability)) goto branch; + + #define DECODE_AND_LOOP_IF_ZERO(probability,branch) \ + if (!bool_get(bool, probability)) \ + { \ + prob = type_probs; \ + if (c<15) {\ + ++c; \ + prob += bands_x[c]; \ + goto branch; \ + }\ + else \ + goto BLOCK_FINISHED; /* for malformed input */\ + } + + #define DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val) \ + DECODE_AND_APPLYSIGN(val) \ + prob = type_probs + (ENTROPY_NODES*2); \ + if (c < 15){\ + b_tokens[zigzag[c]] = v; \ + ++c; \ + goto DO_WHILE; }\ + b_tokens[zigzag[15]] = v; \ + goto BLOCK_FINISHED; + + + + + + + +Bankoski, et al. Informational [Page 234] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + #define DECODE_EXTRABIT_AND_ADJUST_VAL(t,bits_count)\ + val += bool_get(bool, extrabits[t].probs[bits_count]) << \ + bits_count; + + + static int + decode_mb_tokens(struct bool_decoder *bool, + token_entropy_ctx_t left, + token_entropy_ctx_t above, + short *tokens, + enum prediction_mode mode, + coeff_probs_table_t probs, + short factor[TOKEN_BLOCK_TYPES][2]) + { + int i, stop, type; + int c, t, v; + int val, bits_count; + int eob_mask; + short *b_tokens; // tokens for this block + unsigned char *type_probs; // probabilities for this block type + unsigned char *prob; + short *dqf; + + eob_mask = 0; + + if (mode != B_PRED && mode != SPLITMV) + { + i = 24; + stop = 24; + type = 1; + b_tokens = tokens + 24 * 16; + dqf = factor[TOKEN_BLOCK_Y2]; + } + else + { + i = 0; + stop = 16; + type = 3; + b_tokens = tokens; + dqf = factor[TOKEN_BLOCK_Y1]; + } + + /* Save a pointer to the coefficient probs for the current type. + * Need to repeat this whenever type changes. + */ + type_probs = probs[type][0][0]; + + + + + +Bankoski, et al. Informational [Page 235] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + BLOCK_LOOP: + t = left[left_context_index[i]] + above[above_context_index[i]]; + c = !type; /* all blocks start at 0 except type 0, which starts + * at 1. */ + + prob = type_probs; + prob += t * ENTROPY_NODES; + + DO_WHILE: + prob += bands_x[c]; + DECODE_AND_BRANCH_IF_ZERO(prob[EOB_CONTEXT_NODE], + BLOCK_FINISHED); + + CHECK_0_: + DECODE_AND_LOOP_IF_ZERO(prob[ZERO_CONTEXT_NODE], CHECK_0_); + DECODE_AND_BRANCH_IF_ZERO(prob[ONE_CONTEXT_NODE], + ONE_CONTEXT_NODE_0_); + DECODE_AND_BRANCH_IF_ZERO(prob[LOW_VAL_CONTEXT_NODE], + LOW_VAL_CONTEXT_NODE_0_); + DECODE_AND_BRANCH_IF_ZERO(prob[HIGH_LOW_CONTEXT_NODE], + HIGH_LOW_CONTEXT_NODE_0_); + DECODE_AND_BRANCH_IF_ZERO(prob[CAT_THREEFOUR_CONTEXT_NODE], + CAT_THREEFOUR_CONTEXT_NODE_0_); + DECODE_AND_BRANCH_IF_ZERO(prob[CAT_FIVE_CONTEXT_NODE], + CAT_FIVE_CONTEXT_NODE_0_); + val = extrabits[DCT_VAL_CATEGORY6].min_val; + bits_count = extrabits[DCT_VAL_CATEGORY6].length; + + do + { + DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY6, + bits_count); + bits_count --; + } + while (bits_count >= 0); + + DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val); + + CAT_FIVE_CONTEXT_NODE_0_: + val = extrabits[DCT_VAL_CATEGORY5].min_val; + DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY5, 4); + DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY5, 3); + DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY5, 2); + DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY5, 1); + DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY5, 0); + DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val); + + + + + +Bankoski, et al. Informational [Page 236] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + CAT_THREEFOUR_CONTEXT_NODE_0_: + DECODE_AND_BRANCH_IF_ZERO(prob[CAT_THREE_CONTEXT_NODE], + CAT_THREE_CONTEXT_NODE_0_); + val = extrabits[DCT_VAL_CATEGORY4].min_val; + DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY4, 3); + DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY4, 2); + DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY4, 1); + DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY4, 0); + DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val); + + CAT_THREE_CONTEXT_NODE_0_: + val = extrabits[DCT_VAL_CATEGORY3].min_val; + DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY3, 2); + DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY3, 1); + DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY3, 0); + DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val); + + HIGH_LOW_CONTEXT_NODE_0_: + DECODE_AND_BRANCH_IF_ZERO(prob[CAT_ONE_CONTEXT_NODE], + CAT_ONE_CONTEXT_NODE_0_); + + val = extrabits[DCT_VAL_CATEGORY2].min_val; + DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY2, 1); + DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY2, 0); + DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val); + + CAT_ONE_CONTEXT_NODE_0_: + val = extrabits[DCT_VAL_CATEGORY1].min_val; + DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY1, 0); + DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val); + + LOW_VAL_CONTEXT_NODE_0_: + DECODE_AND_BRANCH_IF_ZERO(prob[TWO_CONTEXT_NODE], + TWO_CONTEXT_NODE_0_); + DECODE_AND_BRANCH_IF_ZERO(prob[THREE_CONTEXT_NODE], + THREE_CONTEXT_NODE_0_); + DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(4); + + THREE_CONTEXT_NODE_0_: + DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(3); + + TWO_CONTEXT_NODE_0_: + DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(2); + + ONE_CONTEXT_NODE_0_: + DECODE_AND_APPLYSIGN(1); + prob = type_probs + ENTROPY_NODES; + + + + +Bankoski, et al. Informational [Page 237] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + if (c < 15) + { + b_tokens[zigzag[c]] = v; + ++c; + goto DO_WHILE; + } + + b_tokens[zigzag[15]] = v; + BLOCK_FINISHED: + eob_mask |= (c > 1) << i; + t = (c != !type); // any non-zero data? + eob_mask |= t << 31; + + left[left_context_index[i]] = above[above_context_index[i]] = t; + b_tokens += 16; + + i++; + + if (i < stop) + goto BLOCK_LOOP; + + if (i == 25) + { + type = 0; + i = 0; + stop = 16; + type_probs = probs[type][0][0]; + b_tokens = tokens; + dqf = factor[TOKEN_BLOCK_Y1]; + goto BLOCK_LOOP; + } + + if (i == 16) + { + type = 2; + type_probs = probs[type][0][0]; + stop = 24; + dqf = factor[TOKEN_BLOCK_UV]; + goto BLOCK_LOOP; + } + + return eob_mask; + } + + + + + + + + +Bankoski, et al. Informational [Page 238] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + static void + reset_row_context(token_entropy_ctx_t *left) + { + memset(left, 0, sizeof(*left)); + } + + + static void + reset_above_context(token_entropy_ctx_t *above, unsigned int cols) + { + memset(above, 0, cols * sizeof(*above)); + } + + + static void + reset_mb_context(token_entropy_ctx_t *left, + token_entropy_ctx_t *above, + enum prediction_mode mode) + { + /* Reset the macroblock context on the left and right. We have + * to preserve the context of the second order block if this mode + * would not have updated it. + */ + memset(left, 0, sizeof((*left)[0]) * 8); + memset(above, 0, sizeof((*above)[0]) * 8); + + if (mode != B_PRED && mode != SPLITMV) + { + (*left)[8] = 0; + (*above)[8] = 0; + } + } + + + void + vp8_dixie_tokens_process_row(struct vp8_decoder_ctx *ctx, + unsigned int partition, + unsigned int row, + unsigned int start_col, + unsigned int num_cols) + { + struct token_decoder *tokens = &ctx->tokens[partition]; + short coeffs = tokens->coeffs + 25 * 16 * start_col; + unsigned int col; + token_entropy_ctx_t *above = ctx->above_token_entropy_ctx + + start_col; + token_entropy_ctx_t *left = &tokens->left_token_entropy_ctx; + struct mb_info *mbi = ctx->mb_info_rows[row] + start_col; + + + +Bankoski, et al. Informational [Page 239] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + if (row == 0) + reset_above_context(above, num_cols); + + if (start_col == 0) + reset_row_context(left); + + for (col = start_col; col < start_col + num_cols; col++) + { + memset(coeffs, 0, 25 * 16 * sizeof(short)); + + if (mbi->base.skip_coeff) + { + reset_mb_context(left, above, mbi->base.y_mode); + mbi->base.eob_mask = 0; + } + else + { + struct dequant_factors *dqf; + + dqf = ctx->dequant_factors + mbi->base.segment_id; + mbi->base.eob_mask = + decode_mb_tokens(&tokens->bool, + *left, *above, + coeffs, + mbi->base.y_mode, + ctx->entropy_hdr.coeff_probs, + dqf->factor); + } + + above++; + mbi++; + coeffs += 25 * 16; + } + } + + + void + vp8_dixie_tokens_init(struct vp8_decoder_ctx *ctx) + { + unsigned int partitions = ctx->token_hdr.partitions; + + if (ctx->frame_hdr.frame_size_updated) + { + unsigned int i; + unsigned int coeff_row_sz = + ctx->mb_cols * 25 * 16 * sizeof(short); + + + + + +Bankoski, et al. Informational [Page 240] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + for (i = 0; i < partitions; i++) + { + free(ctx->tokens[i].coeffs); + ctx->tokens[i].coeffs = memalign(16, coeff_row_sz); + + if (!ctx->tokens[i].coeffs) + vpx_internal_error(&ctx->error, VPX_CODEC_MEM_ERROR, + NULL); + } + + free(ctx->above_token_entropy_ctx); + ctx->above_token_entropy_ctx = + calloc(ctx->mb_cols, + sizeof(*ctx->above_token_entropy_ctx)); + + if (!ctx->above_token_entropy_ctx) + vpx_internal_error(&ctx->error, + VPX_CODEC_MEM_ERROR, NULL); + } + } + + + void + vp8_dixie_tokens_destroy(struct vp8_decoder_ctx *ctx) + { + int i; + + for (i = 0; i < MAX_PARTITIONS; i++) + free(ctx->tokens[i].coeffs); + + free(ctx->above_token_entropy_ctx); + } + + ---- End code block ---------------------------------------- + + + + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 241] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +20.17. tokens.h + + ---- Begin code block -------------------------------------- + + /* + * Copyright (c) 2010, 2011, Google Inc. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be + * found in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + #ifndef TOKENS_H + #define TOKENS_H + + void + vp8_dixie_tokens_init(struct vp8_decoder_ctx *ctx); + + + void + vp8_dixie_tokens_destroy(struct vp8_decoder_ctx *ctx); + + + void + vp8_dixie_tokens_process_row(struct vp8_decoder_ctx *ctx, + unsigned int partition, + unsigned int row, + unsigned int start_col, + unsigned int num_cols); + + #endif + + ---- End code block ---------------------------------------- + + + + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 242] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +20.18. vp8_prob_data.h + + ---- Begin code block -------------------------------------- + + /* + * Copyright (c) 2010, 2011, Google Inc. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be + * found in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + static const + unsigned char k_coeff_entropy_update_probs[BLOCK_TYPES][COEFF_BANDS] + [PREV_COEFF_CONTEXTS] + [ENTROPY_NODES] = + { + { + { + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + { + {176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {223, 241, 252, 255, 255, 255, 255, 255, 255, 255, 255}, + {249, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + { + {255, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255}, + {234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + {253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + { + {255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + {239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + {254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + { + {255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + {251, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + + + + + + +Bankoski, et al. Informational [Page 243] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + { + {255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + {251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + {254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + { + {255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255}, + {250, 255, 254, 255, 254, 255, 255, 255, 255, 255, 255}, + {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + { + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + }, + { + { + {217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255}, + {234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255}, + }, + { + {255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + {238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255}, + }, + { + {255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + {249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + { + {255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + { + {255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + {252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + { + {255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + {253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + + + + +Bankoski, et al. Informational [Page 244] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + { + {255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255}, + {250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + { + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + }, + { + { + {186, 251, 250, 255, 255, 255, 255, 255, 255, 255, 255}, + {234, 251, 244, 254, 255, 255, 255, 255, 255, 255, 255}, + {251, 251, 243, 253, 254, 255, 254, 255, 255, 255, 255}, + }, + { + {255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + {236, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + {251, 253, 253, 254, 254, 255, 255, 255, 255, 255, 255}, + }, + { + {255, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + {254, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + { + {255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + { + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + { + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + { + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + + + + +Bankoski, et al. Informational [Page 245] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + { + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + }, + { + { + {248, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {250, 254, 252, 254, 255, 255, 255, 255, 255, 255, 255}, + {248, 254, 249, 253, 255, 255, 255, 255, 255, 255, 255}, + }, + { + {255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255}, + {246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255}, + {252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255}, + }, + { + {255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255}, + {248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255}, + {253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255}, + }, + { + {255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + {245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + {253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + { + {255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255}, + {252, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + {255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + { + {255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {249, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + {255, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + { + {255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255}, + {250, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + + + + + + + + + +Bankoski, et al. Informational [Page 246] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + { + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, + }, + }, + }; + + + static const + unsigned char k_default_y_mode_probs [] = + { 112, 86, 140, 37}; + + + static const + unsigned char k_default_uv_mode_probs [] = + { 162, 101, 204}; + + + static const + unsigned char k_default_coeff_probs [BLOCK_TYPES][COEFF_BANDS] + [PREV_COEFF_CONTEXTS][ENTROPY_NODES] = + { + { /* block type 0 */ + { /* coeff band 0 */ + { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, + { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, + { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128} + }, + { /* coeff band 1 */ + { 253, 136, 254, 255, 228, 219, 128, 128, 128, 128, 128}, + { 189, 129, 242, 255, 227, 213, 255, 219, 128, 128, 128}, + { 106, 126, 227, 252, 214, 209, 255, 255, 128, 128, 128} + }, + { /* coeff band 2 */ + { 1, 98, 248, 255, 236, 226, 255, 255, 128, 128, 128}, + { 181, 133, 238, 254, 221, 234, 255, 154, 128, 128, 128}, + { 78, 134, 202, 247, 198, 180, 255, 219, 128, 128, 128} + }, + { /* coeff band 3 */ + { 1, 185, 249, 255, 243, 255, 128, 128, 128, 128, 128}, + { 184, 150, 247, 255, 236, 224, 128, 128, 128, 128, 128}, + { 77, 110, 216, 255, 236, 230, 128, 128, 128, 128, 128} + }, + + + + + + + +Bankoski, et al. Informational [Page 247] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + { /* coeff band 4 */ + { 1, 101, 251, 255, 241, 255, 128, 128, 128, 128, 128}, + { 170, 139, 241, 252, 236, 209, 255, 255, 128, 128, 128}, + { 37, 116, 196, 243, 228, 255, 255, 255, 128, 128, 128} + }, + { /* coeff band 5 */ + { 1, 204, 254, 255, 245, 255, 128, 128, 128, 128, 128}, + { 207, 160, 250, 255, 238, 128, 128, 128, 128, 128, 128}, + { 102, 103, 231, 255, 211, 171, 128, 128, 128, 128, 128} + }, + { /* coeff band 6 */ + { 1, 152, 252, 255, 240, 255, 128, 128, 128, 128, 128}, + { 177, 135, 243, 255, 234, 225, 128, 128, 128, 128, 128}, + { 80, 129, 211, 255, 194, 224, 128, 128, 128, 128, 128} + }, + { /* coeff band 7 */ + { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, + { 246, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, + { 255, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128} + } + }, + { /* block type 1 */ + { /* coeff band 0 */ + { 198, 35, 237, 223, 193, 187, 162, 160, 145, 155, 62}, + { 131, 45, 198, 221, 172, 176, 220, 157, 252, 221, 1}, + { 68, 47, 146, 208, 149, 167, 221, 162, 255, 223, 128} + }, + { /* coeff band 1 */ + { 1, 149, 241, 255, 221, 224, 255, 255, 128, 128, 128}, + { 184, 141, 234, 253, 222, 220, 255, 199, 128, 128, 128}, + { 81, 99, 181, 242, 176, 190, 249, 202, 255, 255, 128} + }, + { /* coeff band 2 */ + { 1, 129, 232, 253, 214, 197, 242, 196, 255, 255, 128}, + { 99, 121, 210, 250, 201, 198, 255, 202, 128, 128, 128}, + { 23, 91, 163, 242, 170, 187, 247, 210, 255, 255, 128} + }, + { /* coeff band 3 */ + { 1, 200, 246, 255, 234, 255, 128, 128, 128, 128, 128}, + { 109, 178, 241, 255, 231, 245, 255, 255, 128, 128, 128}, + { 44, 130, 201, 253, 205, 192, 255, 255, 128, 128, 128} + }, + { /* coeff band 4 */ + { 1, 132, 239, 251, 219, 209, 255, 165, 128, 128, 128}, + { 94, 136, 225, 251, 218, 190, 255, 255, 128, 128, 128}, + { 22, 100, 174, 245, 186, 161, 255, 199, 128, 128, 128} + }, + + + + +Bankoski, et al. Informational [Page 248] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + { /* coeff band 5 */ + { 1, 182, 249, 255, 232, 235, 128, 128, 128, 128, 128}, + { 124, 143, 241, 255, 227, 234, 128, 128, 128, 128, 128}, + { 35, 77, 181, 251, 193, 211, 255, 205, 128, 128, 128} + }, + { /* coeff band 6 */ + { 1, 157, 247, 255, 236, 231, 255, 255, 128, 128, 128}, + { 121, 141, 235, 255, 225, 227, 255, 255, 128, 128, 128}, + { 45, 99, 188, 251, 195, 217, 255, 224, 128, 128, 128} + }, + { /* coeff band 7 */ + { 1, 1, 251, 255, 213, 255, 128, 128, 128, 128, 128}, + { 203, 1, 248, 255, 255, 128, 128, 128, 128, 128, 128}, + { 137, 1, 177, 255, 224, 255, 128, 128, 128, 128, 128} + } + }, + { /* block type 2 */ + { /* coeff band 0 */ + { 253, 9, 248, 251, 207, 208, 255, 192, 128, 128, 128}, + { 175, 13, 224, 243, 193, 185, 249, 198, 255, 255, 128}, + { 73, 17, 171, 221, 161, 179, 236, 167, 255, 234, 128} + }, + { /* coeff band 1 */ + { 1, 95, 247, 253, 212, 183, 255, 255, 128, 128, 128}, + { 239, 90, 244, 250, 211, 209, 255, 255, 128, 128, 128}, + { 155, 77, 195, 248, 188, 195, 255, 255, 128, 128, 128} + }, + { /* coeff band 2 */ + { 1, 24, 239, 251, 218, 219, 255, 205, 128, 128, 128}, + { 201, 51, 219, 255, 196, 186, 128, 128, 128, 128, 128}, + { 69, 46, 190, 239, 201, 218, 255, 228, 128, 128, 128} + }, + { /* coeff band 3 */ + { 1, 191, 251, 255, 255, 128, 128, 128, 128, 128, 128}, + { 223, 165, 249, 255, 213, 255, 128, 128, 128, 128, 128}, + { 141, 124, 248, 255, 255, 128, 128, 128, 128, 128, 128} + }, + { /* coeff band 4 */ + { 1, 16, 248, 255, 255, 128, 128, 128, 128, 128, 128}, + { 190, 36, 230, 255, 236, 255, 128, 128, 128, 128, 128}, + { 149, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128} + }, + { /* coeff band 5 */ + { 1, 226, 255, 128, 128, 128, 128, 128, 128, 128, 128}, + { 247, 192, 255, 128, 128, 128, 128, 128, 128, 128, 128}, + { 240, 128, 255, 128, 128, 128, 128, 128, 128, 128, 128} + }, + + + + +Bankoski, et al. Informational [Page 249] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + { /* coeff band 6 */ + { 1, 134, 252, 255, 255, 128, 128, 128, 128, 128, 128}, + { 213, 62, 250, 255, 255, 128, 128, 128, 128, 128, 128}, + { 55, 93, 255, 128, 128, 128, 128, 128, 128, 128, 128} + }, + { /* coeff band 7 */ + { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, + { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128}, + { 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128} + } + }, + { /* block type 3 */ + { /* coeff band 0 */ + { 202, 24, 213, 235, 186, 191, 220, 160, 240, 175, 255}, + { 126, 38, 182, 232, 169, 184, 228, 174, 255, 187, 128}, + { 61, 46, 138, 219, 151, 178, 240, 170, 255, 216, 128} + }, + { /* coeff band 1 */ + { 1, 112, 230, 250, 199, 191, 247, 159, 255, 255, 128}, + { 166, 109, 228, 252, 211, 215, 255, 174, 128, 128, 128}, + { 39, 77, 162, 232, 172, 180, 245, 178, 255, 255, 128} + }, + { /* coeff band 2 */ + { 1, 52, 220, 246, 198, 199, 249, 220, 255, 255, 128}, + { 124, 74, 191, 243, 183, 193, 250, 221, 255, 255, 128}, + { 24, 71, 130, 219, 154, 170, 243, 182, 255, 255, 128} + }, + { /* coeff band 3 */ + { 1, 182, 225, 249, 219, 240, 255, 224, 128, 128, 128}, + { 149, 150, 226, 252, 216, 205, 255, 171, 128, 128, 128}, + { 28, 108, 170, 242, 183, 194, 254, 223, 255, 255, 128} + }, + { /* coeff band 4 */ + { 1, 81, 230, 252, 204, 203, 255, 192, 128, 128, 128}, + { 123, 102, 209, 247, 188, 196, 255, 233, 128, 128, 128}, + { 20, 95, 153, 243, 164, 173, 255, 203, 128, 128, 128} + }, + { /* coeff band 5 */ + { 1, 222, 248, 255, 216, 213, 128, 128, 128, 128, 128}, + { 168, 175, 246, 252, 235, 205, 255, 255, 128, 128, 128}, + { 47, 116, 215, 255, 211, 212, 255, 255, 128, 128, 128} + }, + { /* coeff band 6 */ + { 1, 121, 236, 253, 212, 214, 255, 255, 128, 128, 128}, + { 141, 84, 213, 252, 201, 202, 255, 219, 128, 128, 128}, + { 42, 80, 160, 240, 162, 185, 255, 205, 128, 128, 128} + }, + + + + +Bankoski, et al. Informational [Page 250] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + { /* coeff band 7 */ + { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, + { 244, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, + { 238, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128} + } + } + }; + + + static const + unsigned char k_mv_entropy_update_probs[2][MV_PROB_CNT] = + { + { + 237, + 246, + 253, 253, 254, 254, 254, 254, 254, + 254, 254, 254, 254, 254, 250, 250, 252, 254, 254 + }, + { + 231, + 243, + 245, 253, 254, 254, 254, 254, 254, + 254, 254, 254, 254, 254, 251, 251, 254, 254, 254 + } + }; + + + static const + unsigned char k_default_mv_probs[2][MV_PROB_CNT] = + { + { // row + 162, // is short + 128, // sign + 225, 146, 172, 147, 214, 39, 156, // short tree + 128, 129, 132, 75, 145, 178, 206, 239, 254, 254 // long bits + }, + { + 164, + 128, + 204, 170, 119, 235, 140, 230, 228, + 128, 130, 130, 74, 148, 180, 203, 236, 254, 254 + + } + }; + + ---- End code block ---------------------------------------- + + + + + +Bankoski, et al. Informational [Page 251] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +20.19. vpx_codec_internal.h + + ---- Begin code block -------------------------------------- + + /* + * Copyright (c) 2010, 2011, Google Inc. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be + * found in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + + /*!\file vpx_codec_internal.h + * \brief Describes the decoder algorithm interface for algorithm + * implementations. + * + * This file defines the private structures and data types that are + * only relevant to implementing an algorithm, as opposed to using + * it. + * + * To create a decoder algorithm class, an interface structure is put + * into the global namespace: + * <pre> + * my_codec.c: + * vpx_codec_iface_t my_codec = { + * "My Codec v1.0", + * VPX_CODEC_ALG_ABI_VERSION, + * ... + * }; + * </pre> + * + * An application instantiates a specific decoder instance by using + * vpx_codec_init() and a pointer to the algorithm's interface + * structure: + * <pre> + * my_app.c: + * extern vpx_codec_iface_t my_codec; + * { + * vpx_codec_ctx_t algo; + * res = vpx_codec_init(&algo, &my_codec); + * } + * </pre> + * + + + + + +Bankoski, et al. Informational [Page 252] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + * Once initialized, the instance is managed using other functions + * from the vpx_codec_* family. + */ + #ifndef VPX_CODEC_INTERNAL_H + #define VPX_CODEC_INTERNAL_H + #include "vpx_decoder.h" + #include <stdarg.h> + + + /*!\brief Current ABI version number + * + * \internal + * If this file is altered in any way that changes the Application + * Binary Interface (ABI), this value must be bumped. Examples + * include, but are not limited to, changing types, removing or + * reassigning enums, adding/removing/rearranging fields to + * structures. + */ + #define VPX_CODEC_INTERNAL_ABI_VERSION (3) + + typedef struct vpx_codec_alg_priv vpx_codec_alg_priv_t; + + /*!\brief init function pointer prototype + * + * Performs algorithm-specific initialization of the decoder context. + * This function is called by the generic vpx_codec_init() wrapper + * function, so plugins implementing this interface may trust the + * input parameters to be properly initialized. + * + * \param[in] ctx Pointer to this instance's context + * \retval #VPX_CODEC_OK + * The input stream was recognized and decoder initialized. + * \retval #VPX_CODEC_MEM_ERROR + * Memory operation failed. + */ + typedef vpx_codec_err_t (*vpx_codec_init_fn_t)(vpx_codec_ctx_t *ctx); + + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 253] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /*!\brief destroy function pointer prototype + * + * Performs algorithm-specific destruction of the decoder context. + * This function is called by the generic vpx_codec_destroy() wrapper + * function, so plugins implementing this interface may trust the + * input parameters to be properly initialized. + * + * \param[in] ctx Pointer to this instance's context + * \retval #VPX_CODEC_OK + * The input stream was recognized and decoder initialized. + * \retval #VPX_CODEC_MEM_ERROR + * Memory operation failed. + */ + typedef vpx_codec_err_t (*vpx_codec_destroy_fn_t)( + vpx_codec_alg_priv_t *ctx); + + /*!\brief parse stream info function pointer prototype + * + * Performs high level parsing of the bitstream. This function is + * called by the generic vpx_codec_parse_stream() wrapper function, + * so plugins implementing this interface may trust the input + * parameters to be properly initialized. + * + * \param[in] data Pointer to a block of data to parse + * \param[in] data_sz Size of the data buffer + * \param[in,out] si Pointer to stream info to update. The + * size member \ref MUST be properly + * initialized, but \ref MAY be clobbered by + * the algorithm. This parameter \ref MAY + * be NULL. + * + * \retval #VPX_CODEC_OK + * Bitstream is parsable and stream information updated + */ + typedef vpx_codec_err_t (*vpx_codec_peek_si_fn_t)( + const uint8_t *data, + unsigned int data_sz, + vpx_codec_stream_info_t *si); + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 254] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /*!\brief Return information about the current stream. + * + * Returns information about the stream that has been parsed during + * decoding. + * + * \param[in] ctx Pointer to this instance's context + * \param[in,out] si Pointer to stream info to update. The + * size member \ref MUST be properly + * initialized, but \ref MAY be clobbered by + * the algorithm. This parameter \ref MAY + * be NULL. + * + * \retval #VPX_CODEC_OK + * Bitstream is parsable and stream information updated + */ + typedef vpx_codec_err_t (*vpx_codec_get_si_fn_t)( + vpx_codec_alg_priv_t *ctx, + vpx_codec_stream_info_t *si); + + /*!\brief control function pointer prototype + * + * This function is used to exchange algorithm-specific data with the + * decoder instance. This can be used to implement features specific + * to a particular algorithm. + * + * This function is called by the generic vpx_codec_control() wrapper + * function, so plugins implementing this interface may trust the + * input parameters to be properly initialized. However, this + * interface does not provide type safety for the exchanged data or + * assign meanings to the control codes. Those details should be + * specified in the algorithm's header file. In particular, the + * ctrl_id parameter is guaranteed to exist in the algorithm's + * control mapping table, and the data parameter may be NULL. + * + * + * \param[in] ctx Pointer to this instance's context + * \param[in] ctrl_id Algorithm-specific control identifier + * \param[in,out] data Data to exchange with algorithm instance. + * + * \retval #VPX_CODEC_OK + * The internal state data was deserialized. + */ + typedef vpx_codec_err_t (*vpx_codec_control_fn_t)( + vpx_codec_alg_priv_t *ctx, + int ctrl_id, + va_list ap); + + + + + +Bankoski, et al. Informational [Page 255] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /*!\brief control function pointer mapping + * + * This structure stores the mapping between control identifiers and + * implementing functions. Each algorithm provides a list of these + * mappings. This list is searched by the vpx_codec_control() + * wrapper function to determine which function to invoke. The + * special value {0, NULL} is used to indicate end-of-list, and must + * be present. The special value {0, <non-null>} can be used as a + * catch-all mapping. This implies that ctrl_id values chosen by the + * algorithm \ref MUST be non-zero. + */ + typedef const struct + { + int ctrl_id; + vpx_codec_control_fn_t fn; + } vpx_codec_ctrl_fn_map_t; + + /*!\brief decode data function pointer prototype + * + * Processes a buffer of coded data. If the processing results in a + * new decoded frame becoming available, #VPX_CODEC_CB_PUT_SLICE and + * #VPX_CODEC_CB_PUT_FRAME events are generated as appropriate. + * This function is called by the generic vpx_codec_decode() wrapper + * function, so plugins implementing this interface may trust the + * input parameters to be properly initialized. + * + * \param[in] ctx Pointer to this instance's context + * \param[in] data Pointer to this block of new coded data. + * If NULL, a #VPX_CODEC_CB_PUT_FRAME event is + * posted for the previously decoded frame. + * \param[in] data_sz Size of the coded data, in bytes. + * + * \return Returns #VPX_CODEC_OK if the coded data was processed + * completely and future pictures can be decoded without + * error. Otherwise, see the descriptions of the other error + * codes in ::vpx_codec_err_t for recoverability + * capabilities. + */ + typedef vpx_codec_err_t (*vpx_codec_decode_fn_t)( + vpx_codec_alg_priv_t *ctx, + const uint8_t *data, + unsigned int data_sz, + void *user_priv, + long deadline); + + + + + + + +Bankoski, et al. Informational [Page 256] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /*!\brief Decoded frames iterator + * + * Iterates over a list of the frames available for display. The + * iterator storage should be initialized to NULL to start the + * iteration. Iteration is complete when this function returns NULL. + * + * The list of available frames becomes valid upon completion of the + * vpx_codec_decode call, and remains valid until the next call to + * vpx_codec_decode. + * + * \param[in] ctx Pointer to this instance's context + * \param[in out] iter Iterator storage, initialized to NULL + * + * \return Returns a pointer to an image, if one is ready for + * display. Frames produced will always be in PTS + * (presentation time stamp) order. + */ + typedef vpx_image_t*(*vpx_codec_get_frame_fn_t)( + vpx_codec_alg_priv_t *ctx, + vpx_codec_iter_t *iter); + + /*\brief External Memory Allocation memory map get iterator + * + * Iterates over a list of the memory maps requested by the decoder. + * The iterator storage should be initialized to NULL to start the + * iteration. Iteration is complete when this function returns NULL. + * + * \param[in out] iter Iterator storage, initialized to NULL + * + * \return Returns a pointer to a memory segment descriptor, or NULL + * to indicate end-of-list. + */ + typedef vpx_codec_err_t (*vpx_codec_get_mmap_fn_t)( + const vpx_codec_ctx_t *ctx, + vpx_codec_mmap_t *mmap, + vpx_codec_iter_t *iter); + + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 257] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /*\brief External Memory Allocation memory map set iterator + * + * Sets a memory descriptor inside the decoder instance. + * + * \param[in] ctx Pointer to this instance's context + * \param[in] mmap Memory map to store. + * + * \retval #VPX_CODEC_OK + * The memory map was accepted and stored. + * \retval #VPX_CODEC_MEM_ERROR + * The memory map was rejected. + */ + typedef vpx_codec_err_t (*vpx_codec_set_mmap_fn_t)( + vpx_codec_ctx_t *ctx, + const vpx_codec_mmap_t *mmap); + + + typedef vpx_codec_err_t (*vpx_codec_encode_fn_t)( + vpx_codec_alg_priv_t *ctx, + const vpx_image_t *img, + vpx_codec_pts_t pts, + unsigned long duration, + vpx_enc_frame_flags_t flags, + unsigned long deadline); + typedef const vpx_codec_cx_pkt_t*(*vpx_codec_get_cx_data_fn_t)( + vpx_codec_alg_priv_t *ctx, + vpx_codec_iter_t *iter); + + typedef vpx_codec_err_t + (*vpx_codec_enc_config_set_fn_t)( + vpx_codec_alg_priv_t *ctx, + const vpx_codec_enc_cfg_t *cfg); + typedef vpx_fixed_buf_t * + (*vpx_codec_get_global_headers_fn_t)(vpx_codec_alg_priv_t *ctx); + + typedef vpx_image_t * + (*vpx_codec_get_preview_frame_fn_t)(vpx_codec_alg_priv_t *ctx); + + /*!\brief usage configuration mapping + * + * This structure stores the mapping between usage identifiers and + * configuration structures. Each algorithm provides a list of these + * mappings. This list is searched by the + * vpx_codec_enc_config_default() wrapper function to determine which + + + + + + + +Bankoski, et al. Informational [Page 258] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + * config to return. The special value {-1, {0}} is used to indicate + * end-of-list, and must be present. At least one mapping must be + * present, in addition to the end-of-list. + * + */ + typedef const struct + { + int usage; + vpx_codec_enc_cfg_t cfg; + } vpx_codec_enc_cfg_map_t; + + #define NOT_IMPLEMENTED 0 + + /*!\brief Decoder algorithm interface + * + * All decoders \ref MUST expose a variable of this type. + */ + struct vpx_codec_iface + { + const char *name; + int abi_version; + vpx_codec_caps_t caps; + vpx_codec_init_fn_t init; + vpx_codec_destroy_fn_t destroy; + vpx_codec_ctrl_fn_map_t *ctrl_maps; + vpx_codec_get_mmap_fn_t get_mmap; + vpx_codec_set_mmap_fn_t set_mmap; + struct + { + vpx_codec_peek_si_fn_t peek_si; + vpx_codec_get_si_fn_t get_si; + vpx_codec_decode_fn_t decode; + vpx_codec_get_frame_fn_t get_frame; + } dec; + struct + { + vpx_codec_enc_cfg_map_t *cfg_maps; + vpx_codec_encode_fn_t encode; + vpx_codec_get_cx_data_fn_t get_cx_data; + vpx_codec_enc_config_set_fn_t cfg_set; + vpx_codec_get_global_headers_fn_t get_glob_hdrs; + vpx_codec_get_preview_frame_fn_t get_preview; + } enc; + }; + + + + + + + +Bankoski, et al. Informational [Page 259] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /*!\brief Callback function pointer / user data pair storage */ + typedef struct vpx_codec_priv_cb_pair + { + union + { + vpx_codec_put_frame_cb_fn_t put_frame; + vpx_codec_put_slice_cb_fn_t put_slice; + }; + void *user_priv; + } vpx_codec_priv_cb_pair_t; + + + /*!\brief Instance private storage + * + * This structure is allocated by the algorithm's init function. It + * can be extended in one of two ways. First, a second, algorithm + * specific structure can be allocated and the priv member pointed to + * it. Alternatively, this structure can be made the first member of + * the algorithm-specific structure, and the pointer casted to the + * proper type. + */ + struct vpx_codec_priv + { + unsigned int sz; + vpx_codec_iface_t *iface; + struct vpx_codec_alg_priv *alg_priv; + const char *err_detail; + vpx_codec_flags_t init_flags; + struct + { + vpx_codec_priv_cb_pair_t put_frame_cb; + vpx_codec_priv_cb_pair_t put_slice_cb; + } dec; + struct + { + struct vpx_fixed_buf cx_data_dst_buf; + unsigned int cx_data_pad_before; + unsigned int cx_data_pad_after; + vpx_codec_cx_pkt_t cx_data_pkt; + } enc; + }; + + #undef VPX_CTRL_USE_TYPE + #define VPX_CTRL_USE_TYPE(id, typ) \ + static typ id##__value(va_list args) \ + {return va_arg(args, typ);} \ + static typ id##__convert(void *x)\ + {\ + + + +Bankoski, et al. Informational [Page 260] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + union\ + {\ + void *x;\ + typ d;\ + } u;\ + u.x = x;\ + return u.d;\ + } + + + #undef VPX_CTRL_USE_TYPE_DEPRECATED + #define VPX_CTRL_USE_TYPE_DEPRECATED(id, typ) \ + static typ id##__value(va_list args) \ + {return va_arg(args, typ);} \ + static typ id##__convert(void *x)\ + {\ + union\ + {\ + void *x;\ + typ d;\ + } u;\ + u.x = x;\ + return u.d;\ + } + + #define CAST(id, arg) id##__value(arg) + #define RECAST(id, x) id##__convert(x) + + + /* Internal Utility Functions + * + * The following functions are intended to be used inside algorithms + * as utilities for manipulating vpx_codec_* data structures. + */ + struct vpx_codec_pkt_list + { + unsigned int cnt; + unsigned int max; + struct vpx_codec_cx_pkt pkts[1]; + }; + + #define vpx_codec_pkt_list_decl(n)\ + union {struct vpx_codec_pkt_list head;\ + struct {struct vpx_codec_pkt_list head;\ + struct vpx_codec_cx_pkt pkts[n];} alloc;} + + + + + + +Bankoski, et al. Informational [Page 261] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + #define vpx_codec_pkt_list_init(m)\ + (m)->alloc.head.cnt = 0,\ + (m)->alloc.head.max = \ + sizeof((m)->alloc.pkts) / sizeof((m)->alloc.pkts[0]) + + int + vpx_codec_pkt_list_add(struct vpx_codec_pkt_list *, + const struct vpx_codec_cx_pkt *); + + const vpx_codec_cx_pkt_t* + vpx_codec_pkt_list_get(struct vpx_codec_pkt_list *list, + vpx_codec_iter_t *iter); + + + #include <stdio.h> + #include <setjmp.h> + struct vpx_internal_error_info + { + vpx_codec_err_t error_code; + int has_detail; + char detail[80]; + int setjmp; + jmp_buf jmp; + }; + + static void vpx_internal_error(struct vpx_internal_error_info *info, + vpx_codec_err_t error, + const char *fmt, + ...) + { + va_list ap; + + info->error_code = error; + info->has_detail = 0; + + if (fmt) + { + size_t sz = sizeof(info->detail); + + info->has_detail = 1; + va_start(ap, fmt); + vsnprintf(info->detail, sz - 1, fmt, ap); + va_end(ap); + info->detail[sz-1] = '\0'; + } + + + + + + +Bankoski, et al. Informational [Page 262] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + if (info->setjmp) + longjmp(info->jmp, info->error_code); + } + #endif + + ---- End code block ---------------------------------------- + +20.20. vpx_decoder.h + + ---- Begin code block -------------------------------------- + + /* + * Copyright (c) 2010, 2011, Google Inc. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be + * found in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + + /*!\defgroup decoder Decoder Algorithm Interface + * \ingroup codec + * This abstraction allows applications using this decoder to easily + * support multiple video formats with minimal code duplication. + * This section describes the interface common to all decoders. + * @{ + */ + + /*!\file vpx_decoder.h + * \brief Describes the decoder algorithm interface to applications. + * + * This file describes the interface between an application and a + * video decoder algorithm. + * + */ + #ifdef __cplusplus + extern "C" { + #endif + #ifndef VPX_DECODER_H + #define VPX_DECODER_H + #include "vpx_codec.h" + + + + + + + + +Bankoski, et al. Informational [Page 263] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /*!\brief Current ABI version number + * + * \internal + * If this file is altered in any way that changes the ABI, this + * value must be bumped. Examples include, but are not limited + * to, changing types, removing or reassigning enums, + * adding/removing/rearranging fields to structures + */ + #define VPX_DECODER_ABI_VERSION (2 + VPX_CODEC_ABI_VERSION) + + /*! \brief Decoder capabilities bitfield + * + * Each decoder advertises the capabilities it supports as part + * of its ::vpx_codec_iface_t interface structure. Capabilities + * are extra interfaces or functionality, and are not required + * to be supported by a decoder. + * + * The available flags are specified by VPX_CODEC_CAP_* defines. + */ + #define VPX_CODEC_CAP_PUT_SLICE 0x10000 /**< Will issue put_slice + callbacks */ + #define VPX_CODEC_CAP_PUT_FRAME 0x20000 /**< Will issue put_frame + callbacks */ + #define VPX_CODEC_CAP_POSTPROC 0x40000 /**< Can postprocess decoded + frame */ + + /*! \brief Initialization-time Feature Enabling + * + * Certain codec features must be known at initialization time, + * to allow for proper memory allocation. + * + * The available flags are specified by VPX_CODEC_USE_* defines. + */ + #define VPX_CODEC_USE_POSTPROC 0x10000 /**< Postprocess decoded + frame */ + + /*!\brief Stream properties + * + * This structure is used to query or set properties of the + * decoded stream. Algorithms may extend this structure with + * data specific to their bitstream by setting the sz member + * appropriately. + */ + + + + + + + + +Bankoski, et al. Informational [Page 264] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + typedef struct vpx_codec_stream_info + { + unsigned int sz; /**< Size of this structure */ + unsigned int w; /**< Width (or 0 for unknown/default) */ + unsigned int h; /**< Height (or 0 for unknown/default) */ + unsigned int is_kf; /**< Current frame is a keyframe */ + } vpx_codec_stream_info_t; + + /* REQUIRED FUNCTIONS + * + * The following functions are required to be implemented for all + * decoders. They represent the base case functionality expected + * of all decoders. + */ + + + /*!\brief Initialization Configurations + * + * This structure is used to pass init time configuration options + * to the decoder. + */ + typedef struct vpx_codec_dec_cfg + { + unsigned int threads; /**< Maximum number of threads to use, + default 1 */ + unsigned int w; /**< Width */ + unsigned int h; /**< Height */ + } vpx_codec_dec_cfg_t; /**< alias for struct vpx_codec_dec_cfg */ + + + /*!\brief Initialize a decoder instance + * + * Initializes a decoder context using the given interface. + * Applications should call the vpx_codec_dec_init convenience + * macro instead of this function directly, to ensure that the + * ABI version number parameter is properly initialized. + * + * In XMA mode (activated by setting VPX_CODEC_USE_XMA in the + * flags parameter), the storage pointed to by the cfg parameter + * must be kept readable and stable until all memory maps have + * been set. + * + * \param[in] ctx Pointer to this instance's context. + * \param[in] iface Pointer to the algorithm interface to + * use. + * \param[in] cfg Configuration to use, if known. May be + * NULL. + + + + +Bankoski, et al. Informational [Page 265] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + * \param[in] flags Bitfield of VPX_CODEC_USE_* flags + * \param[in] ver ABI version number. Must be set to + * VPX_DECODER_ABI_VERSION + * \retval #VPX_CODEC_OK + * The decoder algorithm initialized. + * \retval #VPX_CODEC_MEM_ERROR + * Memory allocation failed. + */ + vpx_codec_err_t vpx_codec_dec_init_ver( + vpx_codec_ctx_t *ctx, + vpx_codec_iface_t *iface, + vpx_codec_dec_cfg_t *cfg, + vpx_codec_flags_t flags, + int ver); + + /*!\brief Convenience macro for vpx_codec_dec_init_ver() + * + * Ensures the ABI version parameter is properly set. + */ + #define vpx_codec_dec_init(ctx, iface, cfg, flags) \ + vpx_codec_dec_init_ver(ctx, iface, cfg, flags, \ + VPX_DECODER_ABI_VERSION) + + + /*!\brief Parse stream info from a buffer + * + * Performs high level parsing of the bitstream. Construction of + * a decoder context is not necessary. Can be used to determine + * if the bitstream is of the proper format, and to extract + * information from the stream. + * + * \param[in] iface Pointer to the algorithm interface + * \param[in] data Pointer to a block of data to parse + * \param[in] data_sz Size of the data buffer + * \param[in,out] si Pointer to stream info to update. The + * size member + * \ref MUST be properly initialized, but + * \ref MAY be clobbered by the + * algorithm. This parameter \ref MAY be + * NULL. + * + * \retval #VPX_CODEC_OK + * Bitstream is parsable and stream information updated + */ + + + + + + + +Bankoski, et al. Informational [Page 266] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + vpx_codec_err_t vpx_codec_peek_stream_info( + vpx_codec_iface_t *iface, + const uint8_t *data, + unsigned int data_sz, + vpx_codec_stream_info_t *si); + + /*!\brief Return information about the current stream. + * + * Returns information about the stream that has been parsed + * during decoding. + * + * \param[in] ctx Pointer to this instance's context + * \param[in,out] si Pointer to stream info to update. The + * size member \ref MUST be properly + * initialized, but \ref MAY be clobbered + * by the algorithm. This parameter \ref + * MAY be NULL. + * + * \retval #VPX_CODEC_OK + * Bitstream is parsable and stream information updated + */ + vpx_codec_err_t vpx_codec_get_stream_info( + vpx_codec_ctx_t *ctx, + vpx_codec_stream_info_t *si); + + + /*!\brief Decode data + * + * Processes a buffer of coded data. If the processing results + * in a new decoded frame becoming available, PUT_SLICE and + * PUT_FRAME events may be generated, as appropriate. Encoded + * data \ref MUST be passed in DTS (decode time stamp) order. + * Frames produced will always be in PTS (presentation time + * stamp) order. + * + * \param[in] ctx Pointer to this instance's context + * \param[in] data Pointer to this block of new coded + * data. If NULL, a + * VPX_CODEC_CB_PUT_FRAME event is posted + * for the previously decoded frame. + * \param[in] data_sz Size of the coded data, in bytes. + * \param[in] user_priv Application-specific data to associate + * with this frame. + * \param[in] deadline Soft deadline the decoder should + * attempt to meet, in us. Set to zero + * for unlimited. + * + + + + +Bankoski, et al. Informational [Page 267] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + * \return Returns #VPX_CODEC_OK if the coded data was processed + * completely and future pictures can be decoded without + * error. Otherwise, see the descriptions of the other + * error codes in ::vpx_codec_err_t for recoverability + * capabilities. + */ + vpx_codec_err_t vpx_codec_decode(vpx_codec_ctx_t *ctx, + const uint8_t *data, + unsigned int data_sz, + void *user_priv, + long deadline); + + + /*!\brief Decoded frames iterator + * + * Iterates over a list of the frames available for display. The + * iterator storage should be initialized to NULL to start the + * iteration. Iteration is complete when this function returns + * NULL. + * + * The list of available frames becomes valid upon completion of + * the vpx_codec_decode call, and remains valid until the next + * call to vpx_codec_decode. + * + * \param[in] ctx Pointer to this instance's context + * \param[in,out] iter Iterator storage, initialized to NULL + * + * \return Returns a pointer to an image, if one is ready for + * display. Frames produced will always be in PTS + * (presentation time stamp) order. + */ + vpx_image_t *vpx_codec_get_frame(vpx_codec_ctx_t *ctx, + vpx_codec_iter_t *iter); + + + /*!\defgroup cap_put_frame Frame-Based Decoding Functions + * + * The following functions are required to be implemented for all + * decoders that advertise the VPX_CODEC_CAP_PUT_FRAME + * capability. Calling these functions for codecs that don't + * advertise this capability will result in an error code being + * returned, usually VPX_CODEC_ERROR + * @{ + */ + + + + + + + +Bankoski, et al. Informational [Page 268] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /*!\brief put frame callback prototype + * + * This callback is invoked by the decoder to notify the + * application of the availability of decoded image data. + */ + typedef void (*vpx_codec_put_frame_cb_fn_t)( + void *user_priv, + const vpx_image_t *img); + + /*!\brief Register for notification of frame completion. + * + * Registers a given function to be called when a decoded frame + * is available. + * + * \param[in] ctx Pointer to this instance's context + * \param[in] cb Pointer to the callback function + * \param[in] user_priv User's private data + * + * \retval #VPX_CODEC_OK + * Callback successfully registered. + * \retval #VPX_CODEC_ERROR + * Decoder context not initialized, or algorithm not capable + * of posting slice completion. + */ + vpx_codec_err_t vpx_codec_register_put_frame_cb( + vpx_codec_ctx_t *ctx, + vpx_codec_put_frame_cb_fn_t cb, + void *user_priv); + + + /*!@} - end defgroup cap_put_frame */ + + /*!\defgroup cap_put_slice Slice-Based Decoding Functions + * + * The following functions are required to be implemented for all + * decoders that advertise the VPX_CODEC_CAP_PUT_SLICE + * capability. Calling these functions for codecs that don't + * advertise this capability will result in an error code being + * returned, usually VPX_CODEC_ERROR + * @{ + */ + + /*!\brief put slice callback prototype + * + * This callback is invoked by the decoder to notify the + * application of the availability of partially decoded image + * data. + */ + + + +Bankoski, et al. Informational [Page 269] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + typedef void (*vpx_codec_put_slice_cb_fn_t)( + void *user_priv, + const vpx_image_t *img, + const vpx_image_rect_t *valid, + const vpx_image_rect_t *update); + + + /*!\brief Register for notification of slice completion. + * + * Registers a given function to be called when a decoded slice + * is available. + * + * \param[in] ctx Pointer to this instance's context + * \param[in] cb Pointer to the callback function + * \param[in] user_priv User's private data + * + * \retval #VPX_CODEC_OK + * Callback successfully registered. + * \retval #VPX_CODEC_ERROR + * Decoder context not initialized, or algorithm not capable + * of posting slice completion. + */ + vpx_codec_err_t vpx_codec_register_put_slice_cb( + vpx_codec_ctx_t *ctx, + vpx_codec_put_slice_cb_fn_t cb, + void *user_priv); + + + /*!@} - end defgroup cap_put_slice*/ + + /*!@} - end defgroup decoder*/ + + #endif + + #ifdef __cplusplus + } + #endif + + #if !defined(VPX_CODEC_DISABLE_COMPAT) || !VPX_CODEC_DISABLE_COMPAT + #include "vpx_decoder_compat.h" + #endif + + ---- End code block ---------------------------------------- + + + + + + + + +Bankoski, et al. Informational [Page 270] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +20.21. vpx_decoder_compat.h + + ---- Begin code block -------------------------------------- + + /* + * Copyright (c) 2010, 2011, Google Inc. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be + * found in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + /*!\defgroup decoder Common Decoder Algorithm Interface + * This abstraction allows applications using this decoder to easily + * support multiple video formats with minimal code duplication. + * This section describes the interface common to all codecs. + * @{ + */ + + /*!\file + * \brief Provides a compatibility layer between version 1 and 2 of + * this API. + * + * This interface has been deprecated. Only existing code should + * make use of this interface, and therefore, it is only thinly + * documented. Existing code should be ported to the vpx_codec_* + * API. + */ + #ifdef __cplusplus + extern "C" { + #endif + + #ifndef VPX_DECODER_COMPAT_H + #define VPX_DECODER_COMPAT_H + + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 271] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /*!\brief Decoder algorithm return codes */ + typedef enum { + /*!\brief Operation completed without error */ + VPX_DEC_OK = VPX_CODEC_OK, + + /*!\brief Unspecified error */ + VPX_DEC_ERROR = VPX_CODEC_ERROR, + + /*!\brief Memory operation failed */ + VPX_DEC_MEM_ERROR = VPX_CODEC_MEM_ERROR, + + /*!\brief ABI version mismatch */ + VPX_DEC_ABI_MISMATCH = VPX_CODEC_ABI_MISMATCH, + + /*!\brief The given bitstream is not supported. + * + * The bitstream was unable to be parsed at the highest + * level. The decoder is unable to proceed. This error \ref + * SHOULD be treated as fatal to the stream. + */ + VPX_DEC_UNSUP_BITSTREAM = VPX_CODEC_UNSUP_BITSTREAM, + + /*!\brief Encoded bitstream uses an unsupported feature + * + * The decoder does not implement a feature required by the + * encoder. This return code should only be used for + * features that prevent future pictures from being properly + * decoded. This error \ref MAY be treated as fatal to the + * stream or \ref MAY be treated as fatal to the current + * Group of Pictures (GOP). + */ + VPX_DEC_UNSUP_FEATURE = VPX_CODEC_UNSUP_FEATURE, + + /*!\brief The coded data for this stream is corrupt or + * incomplete + * + * There was a problem decoding the current frame. This + * return code should only be used for failures that prevent + * future pictures from being properly decoded. This error + * \ref MAY be treated as fatal to the stream or \ref MAY be + * treated as fatal to the current GOP. If decoding is + * continued for the current GOP, artifacts may be present. + */ + VPX_DEC_CORRUPT_FRAME = VPX_CODEC_CORRUPT_FRAME, + + + + + + + +Bankoski, et al. Informational [Page 272] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /*!\brief An application-supplied parameter is not valid. + * + */ + VPX_DEC_INVALID_PARAM = VPX_CODEC_INVALID_PARAM, + + /*!\brief An iterator reached the end of list. + * + */ + VPX_DEC_LIST_END = VPX_CODEC_LIST_END + + } + vpx_dec_err_t; + + /*! \brief Decoder capabilities bitfield + * + * Each decoder advertises the capabilities it supports as part + * of its ::vpx_dec_iface_t interface structure. Capabilities + * are extra interfaces or functionality, and are not required + * to be supported by a decoder. + * + * The available flags are specified by VPX_DEC_CAP_* defines. + */ + typedef int vpx_dec_caps_t; + #define VPX_DEC_CAP_PUT_SLICE 0x0001 /**< Will issue put_slice + callbacks */ + #define VPX_DEC_CAP_PUT_FRAME 0x0002 /**< Will issue put_frame + callbacks */ + + #define VPX_DEC_CAP_XMA 0x0004 /**< Supports External Memory + Allocation */ + + /*!\brief Stream properties + * + * This structure is used to query or set properties of the + * decoded stream. Algorithms may extend this structure with + * data specific to their bitstream by setting the sz member + * appropriately. + */ + #if 1 + typedef vpx_codec_stream_info_t vpx_dec_stream_info_t; + #else + typedef struct + { + unsigned int sz; /**< Size of this structure */ + unsigned int w; /**< Width (or 0 for unknown/default) */ + unsigned int h; /**< Height (or 0 for unknown/default) */ + unsigned int is_kf; /**< Current frame is a keyframe */ + } vpx_dec_stream_info_t; + + + +Bankoski, et al. Informational [Page 273] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + #endif + + + /*!\brief Decoder interface structure. + * + * Contains function pointers and other data private to the + * decoder implementation. This structure is opaque to the + * application. + */ + typedef const struct vpx_codec_iface vpx_dec_iface_t; + typedef struct vpx_codec_priv vpx_dec_priv_t; + + /*!\brief Iterator + * + * Opaque storage used for iterating over lists. + */ + typedef vpx_codec_iter_t vpx_dec_iter_t; + + /*!\brief Decoder context structure + * + * All decoders \ref MUST support this context structure fully. + * In general, this data should be considered private to the + * decoder algorithm, and not be manipulated or examined by the + * calling application. Applications may reference the 'name' + * member to get a printable description of the algorithm. + */ + #if 1 + typedef vpx_codec_ctx_t vpx_dec_ctx_t; + #else + typedef struct + { + const char *name; /**< Printable interface name */ + vpx_dec_iface_t *iface; /**< Interface pointers */ + vpx_dec_err_t err; /**< Last returned error */ + vpx_dec_priv_t *priv; /**< Algorithm private storage */ + } vpx_dec_ctx_t; + #endif + + + /*!\brief Return the build configuration + * + * Returns a printable string containing an encoded version of + * the build configuration. This may be useful to vpx support. + * + */ + const char *vpx_dec_build_config(void) DEPRECATED; + + + + + +Bankoski, et al. Informational [Page 274] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /*!\brief Return the name for a given interface + * + * Returns a human readable string for name of the given decoder + * interface. + * + * \param[in] iface Interface pointer + * + */ + const char *vpx_dec_iface_name( + vpx_dec_iface_t *iface) DEPRECATED; + + + /*!\brief Convert error number to printable string + * + * Returns a human readable string for the last error returned + * by the algorithm. The returned error will be one line and + * will not contain any newline characters. + * + * + * \param[in] err Error number. + * + */ + const char *vpx_dec_err_to_string(vpx_dec_err_t err) DEPRECATED; + + + /*!\brief Retrieve error synopsis for decoder context + * + * Returns a human readable string for the last error returned by + * the algorithm. The returned error will be one line and will + * not contain any newline characters. + * + * + * \param[in] ctx Pointer to this instance's context. + * + */ + const char *vpx_dec_error(vpx_dec_ctx_t *ctx) DEPRECATED; + + + /*!\brief Retrieve detailed error information for decoder context + * + * Returns a human readable string providing detailed information + * about the last error. + * + * \param[in] ctx Pointer to this instance's context. + * + + + + + + +Bankoski, et al. Informational [Page 275] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + * \retval NULL + * No detailed information is available. + */ + const char *vpx_dec_error_detail(vpx_dec_ctx_t *ctx) DEPRECATED; + + + /* REQUIRED FUNCTIONS + * + * The following functions are required to be implemented for all + * decoders. They represent the base case functionality expected + * of all decoders. + */ + + + /*!\brief Initialize a decoder instance + * + * Initializes a decoder context using the given interface. + * Applications should call the vpx_dec_init convenience macro + * instead of this function directly, to ensure that the ABI + * version number parameter is properly initialized. + * + * \param[in] ctx Pointer to this instance's context. + * \param[in] iface Pointer to the algorithm interface to use. + * \param[in] ver ABI version number. Must be set to + * VPX_DECODER_ABI_VERSION + * \retval #VPX_DEC_OK + * The decoder algorithm initialized. + * \retval #VPX_DEC_MEM_ERROR + * Memory allocation failed. + */ + vpx_dec_err_t vpx_dec_init_ver( + vpx_dec_ctx_t *ctx, + vpx_dec_iface_t *iface, + int ver) DEPRECATED; + + #define vpx_dec_init(ctx, iface) \ + vpx_dec_init_ver(ctx, iface, VPX_DECODER_ABI_VERSION) + + + /*!\brief Destroy a decoder instance + * + * Destroys a decoder context, freeing any associated memory + * buffers. + * + * \param[in] ctx Pointer to this instance's context + * + * \retval #VPX_DEC_OK + * The decoder algorithm initialized. + + + +Bankoski, et al. Informational [Page 276] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + * \retval #VPX_DEC_MEM_ERROR + * Memory allocation failed. + */ + vpx_dec_err_t vpx_dec_destroy(vpx_dec_ctx_t *ctx) DEPRECATED; + + + /*!\brief Get the capabilities of an algorithm. + * + * Retrieves the capabilities bitfield from the algorithm's + * interface. + * + * \param[in] iface Pointer to the algorithm interface + * + */ + vpx_dec_caps_t vpx_dec_get_caps( + vpx_dec_iface_t *iface) DEPRECATED; + + + /*!\brief Parse stream info from a buffer + * + * Performs high level parsing of the bitstream. Construction of + * a decoder context is not necessary. Can be used to determine + * if the bitstream is of the proper format, and to extract + * information from the stream. + * + * \param[in] iface Pointer to the algorithm interface + * \param[in] data Pointer to a block of data to parse + * \param[in] data_sz Size of the data buffer + * \param[in,out] si Pointer to stream info to update. The + * size member \ref MUST be properly + * initialized, but \ref MAY be + * clobbered by the algorithm. This + * parameter \ref MAY be NULL. + * + * \retval #VPX_DEC_OK + * Bitstream is parsable and stream information updated + */ + vpx_dec_err_t vpx_dec_peek_stream_info( + vpx_dec_iface_t *iface, + const uint8_t *data, + unsigned int data_sz, + vpx_dec_stream_info_t *si) DEPRECATED; + + + + + + + + + +Bankoski, et al. Informational [Page 277] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /*!\brief Return information about the current stream. + * + * Returns information about the stream that has been parsed + * during decoding. + * + * \param[in] ctx Pointer to this instance's context + * \param[in,out] si Pointer to stream info to update. + * The size member \ref MUST be properly + * initialized, but \ref MAY be clobbered + * by the algorithm. This parameter \ref + * MAY be NULL. + * + * \retval #VPX_DEC_OK + * Bitstream is parsable and stream information updated + */ + vpx_dec_err_t vpx_dec_get_stream_info( + vpx_dec_ctx_t *ctx, + vpx_dec_stream_info_t *si) DEPRECATED; + + + /*!\brief Control algorithm + * + * This function is used to exchange algorithm-specific data with + * the decoder instance. This can be used to implement features + * specific to a particular algorithm. + * + * This wrapper function dispatches the request to the helper + * function associated with the given ctrl_id. It tries to call + * this function transparently, but will return #VPX_DEC_ERROR if + * the request could not be dispatched. + * + * \param[in] ctx Pointer to this instance's context + * \param[in] ctrl_id Algorithm-specific control + * identifier + * \param[in,out] data Data to exchange with algorithm + * instance. + * + * \retval #VPX_DEC_OK + * The control request was processed. + * \retval #VPX_DEC_ERROR + * The control request was not processed. + * \retval #VPX_DEC_INVALID_PARAM + * The data was not valid. + */ + vpx_dec_err_t vpx_dec_control(vpx_dec_ctx_t *ctx, + int ctrl_id, + void *data) DEPRECATED; + + + + +Bankoski, et al. Informational [Page 278] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /*!\brief Decode data + * + * Processes a buffer of coded data. If the processing results + * in a new decoded frame becoming available, + * #VPX_DEC_CB_PUT_SLICE and #VPX_DEC_CB_PUT_FRAME events may be + * generated, as appropriate. Encoded data \ref MUST be passed + * in DTS (decode time stamp) order. Frames produced will always + * be in PTS (presentation time stamp) order. + * + * \param[in] ctx Pointer to this instance's context + * \param[in] data Pointer to this block of new coded + * data. If NULL, a VPX_DEC_CB_PUT_FRAME + * event is posted for the previously + * decoded frame. + * \param[in] data_sz Size of the coded data, in bytes. + * \param[in] user_priv Application-specific data to associate + * with this frame. + * \param[in] rel_pts PTS relative to the previous frame, in + * us. If unknown or unavailable, set to + * zero. + * + * \return Returns #VPX_DEC_OK if the coded data was processed + * completely and future pictures can be decoded without + * error. Otherwise, see the descriptions of the other + * error codes in ::vpx_dec_err_t for recoverability + * capabilities. + */ + vpx_dec_err_t vpx_dec_decode( + vpx_dec_ctx_t *ctx, + uint8_t *data, + unsigned int data_sz, + void *user_priv, + int rel_pts) DEPRECATED; + + + /*!\brief Decoded frames iterator + * + * Iterates over a list of the frames available for display. The + * iterator storage should be initialized to NULL to start the + * iteration. Iteration is complete when this function returns + * NULL. + * + * The list of available frames becomes valid upon completion of + * the vpx_dec_decode call, and remains valid until the next call + * to vpx_dec_decode. + * + * \param[in] ctx Pointer to this instance's context + * \param[in out] iter Iterator storage, initialized to NULL + + + +Bankoski, et al. Informational [Page 279] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + * + * \return Returns a pointer to an image, if one is ready for + * display. Frames produced will always be in PTS + * (presentation time stamp) order. + */ + vpx_image_t *vpx_dec_get_frame(vpx_dec_ctx_t *ctx, + vpx_dec_iter_t *iter) DEPRECATED; + + + /*!\defgroup cap_put_frame Frame-Based Decoding Functions + * + * The following functions are required to be implemented for all + * decoders that advertise the VPX_DEC_CAP_PUT_FRAME capability. + * Calling these functions for codecs that don't advertise this + * capability will result in an error code being returned, + * usually VPX_DEC_ERROR @{ + */ + + /*!\brief put frame callback prototype + * + * This callback is invoked by the decoder to notify the + * application of the availability of decoded image data. + */ + typedef void (*vpx_dec_put_frame_cb_fn_t)( + void *user_priv, + const vpx_image_t *img); + + + /*!\brief Register for notification of frame completion. + * + * Registers a given function to be called when a decoded frame + * is available. + * + * \param[in] ctx Pointer to this instance's context + * \param[in] cb Pointer to the callback function + * \param[in] user_priv User's private data + * + * \retval #VPX_DEC_OK + * Callback successfully registered. + * \retval #VPX_DEC_ERROR + * Decoder context not initialized, or algorithm not capable + * of posting slice completion. + */ + vpx_dec_err_t vpx_dec_register_put_frame_cb( + vpx_dec_ctx_t *ctx, + vpx_dec_put_frame_cb_fn_t cb, + void *user_priv) DEPRECATED; + + + + +Bankoski, et al. Informational [Page 280] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /*!@} - end defgroup cap_put_frame */ + + /*!\defgroup cap_put_slice Slice-Based Decoding Functions + * + * The following functions are required to be implemented for all + * decoders that advertise the VPX_DEC_CAP_PUT_SLICE capability. + * Calling these functions for codecs that don't advertise this + * capability will result in an error code being returned, + * usually VPX_DEC_ERROR + * @{ + */ + + /*!\brief put slice callback prototype + * + * This callback is invoked by the decoder to notify the + * application of the availability of partially decoded image + * data. + */ + typedef void (*vpx_dec_put_slice_cb_fn_t)(void *user_priv, + const vpx_image_t *img, + const vpx_image_rect_t *valid, + const vpx_image_rect_t *update); + + + /*!\brief Register for notification of slice completion. + * + * Registers a given function to be called when a decoded slice + * is available. + * + * \param[in] ctx Pointer to this instance's context + * \param[in] cb Pointer to the callback function + * \param[in] user_priv User's private data + * + * \retval #VPX_DEC_OK + * Callback successfully registered. + * \retval #VPX_DEC_ERROR + * Decoder context not initialized, or algorithm not capable + * of posting slice completion. + */ + vpx_dec_err_t vpx_dec_register_put_slice_cb(vpx_dec_ctx_t *ctx, + vpx_dec_put_slice_cb_fn_t cb, + void *user_priv) DEPRECATED; + + + /*!@} - end defgroup cap_put_slice*/ + + + + + + +Bankoski, et al. Informational [Page 281] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /*!\defgroup cap_xma External Memory Allocation Functions + * + * The following functions are required to be implemented for all + * decoders that advertise the VPX_DEC_CAP_XMA capability. + * Calling these functions for codecs that don't advertise this + * capability will result in an error code being returned, + * usually VPX_DEC_ERROR + * @{ + */ + + /*!\brief Memory Map Entry + * + * This structure is used to contain the properties of a memory + * segment. It is populated by the decoder in the request phase, + * and by the calling application once the requested allocation + * has been performed. + */ + #if 1 + #define VPX_DEC_MEM_ZERO 0x1 /**< Segment must be zeroed by + allocation */ + #define VPX_DEC_MEM_WRONLY 0x2 /**< Segment need not be + readable */ + #define VPX_DEC_MEM_FAST 0x4 /**< Place in fast memory, if + available */ + typedef struct vpx_codec_mmap vpx_dec_mmap_t; + #else + typedef struct vpx_dec_mmap + { + /* + * The following members are set by the codec when requesting + * a segment + */ + unsigned int id; /**< identifier for the segment's + contents */ + unsigned long sz; /**< size of the segment, in bytes */ + unsigned int align; /**< required alignment of the + segment, in bytes */ + unsigned int flags; /**< bitfield containing segment + properties */ + #define VPX_DEC_MEM_ZERO 0x1 /**< Segment must be zeroed by + allocation */ + #define VPX_DEC_MEM_WRONLY 0x2 /**< Segment need not be + readable */ + #define VPX_DEC_MEM_FAST 0x4 /**< Place in fast memory, if + available */ + + + + + + +Bankoski, et al. Informational [Page 282] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /* The following members are to be filled in by the + * allocation function */ + void *base; /**< pointer to the allocated + segment */ + void (*dtor)(struct vpx_dec_mmap *map); /**< destructor to + call */ + void *priv; /**< allocator private storage */ + } vpx_dec_mmap_t; + #endif + + /*!\brief Initialize a decoder instance in external allocation + * mode + * + * Initializes a decoder context using the given interface. + * Applications should call the vpx_dec_xma_init convenience + * macro instead of this function directly, to ensure that the + * ABI version number parameter is properly initialized. + * + * \param[in] ctx Pointer to this instance's context. + * \param[in] iface Pointer to the algorithm interface to + * use. + * \param[in] ver ABI version number. Must be set to + * VPX_DECODER_ABI_VERSION + * \retval #VPX_DEC_OK + * The decoder algorithm initialized. + * \retval #VPX_DEC_ERROR + * Decoder does not support XMA mode. + */ + vpx_dec_err_t vpx_dec_xma_init_ver(vpx_dec_ctx_t *ctx, + vpx_dec_iface_t *iface, + int ver) DEPRECATED; + #define vpx_dec_xma_init(ctx, iface) \ + vpx_dec_xma_init_ver(ctx, iface, VPX_DECODER_ABI_VERSION) + + + /*!\brief Iterate over the list of segments to allocate. + * + * Iterates over a list of the segments to allocate. The + * iterator storage should be initialized to NULL to start the + * iteration. Iteration is complete when this function returns + * VPX_DEC_LIST_END. The amount of memory needed to allocate is + * dependent upon the size of the encoded stream. This means + * that the stream info structure must be known at allocation + * time. It can be populated with the vpx_dec_peek_stream_info() + * function. In cases where the stream to be decoded is not + * available at allocation time, a fixed size must be requested. + * The decoder will not be able to decode streams larger than the + * size used at allocation time. + + + +Bankoski, et al. Informational [Page 283] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + * + * \param[in] ctx Pointer to this instance's context. + * \param[out] mmap Pointer to the memory map entry to + * populate. + * \param[in] si Pointer to the stream info. + * \param[in out] iter Iterator storage, initialized to NULL + * + * \retval #VPX_DEC_OK + * The memory map entry was populated. + * \retval #VPX_DEC_ERROR + * Decoder does not support XMA mode. + * \retval #VPX_DEC_MEM_ERROR + * Unable to determine segment size from stream info. + */ + vpx_dec_err_t vpx_dec_get_mem_map( + vpx_dec_ctx_t *ctx, + vpx_dec_mmap_t *mmap, + const vpx_dec_stream_info_t *si, + vpx_dec_iter_t *iter) DEPRECATED; + + + /*!\brief Identify allocated segments to decoder instance + * + * Stores a list of allocated segments in the decoder. Segments + * \ref MUST be passed in the order they are read from + * vpx_dec_get_mem_map(), but may be passed in groups of any + * size. Segments \ref MUST be set only once. The allocation + * function \ref MUST ensure that the vpx_dec_mmap_t::base member + * is non-NULL. If the segment requires cleanup handling (e.g., + * calling free() or close()) then the vpx_dec_mmap_t::dtor + * member \ref MUST be populated. + * + * \param[in] ctx Pointer to this instance's context. + * \param[in] mmaps Pointer to the first memory map + * entry in the list. + * \param[in] num_maps Number of entries being set at this + * time + * + * \retval #VPX_DEC_OK + * The segment was stored in the decoder context. + * \retval #VPX_DEC_ERROR + * Decoder does not support XMA mode. + * \retval #VPX_DEC_MEM_ERROR + * Segment base address was not set, or segment was already + * stored. + + */ + + + + +Bankoski, et al. Informational [Page 284] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + vpx_dec_err_t vpx_dec_set_mem_map( + vpx_dec_ctx_t *ctx, + vpx_dec_mmap_t *mmaps, + unsigned int num_maps) DEPRECATED; + + /*!@} - end defgroup cap_xma*/ + /*!@} - end defgroup decoder*/ + + + #endif + #ifdef __cplusplus + } + #endif + + ---- End code block ---------------------------------------- + +20.22. vpx_image.c + + ---- Begin code block -------------------------------------- + + /* + * Copyright (c) 2010, 2011, Google Inc. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be + * found in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + + #include <stdlib.h> + #include <string.h> + #include "vpx/vpx_image.h" + + static vpx_image_t *img_alloc_helper(vpx_image_t *img, + vpx_img_fmt_t fmt, + unsigned int d_w, + unsigned int d_h, + unsigned int stride_align, + unsigned char *img_data) + { + + + + + + + + + +Bankoski, et al. Informational [Page 285] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + unsigned int h, w, s, xcs, ycs, bps; + int align; + + /* Treat align==0 like align==1 */ + if (!stride_align) + stride_align = 1; + + /* Validate alignment (must be power of 2) */ + if (stride_align & (stride_align - 1)) + goto fail; + + /* Get sample size for this format */ + switch (fmt) + { + case VPX_IMG_FMT_RGB32: + case VPX_IMG_FMT_RGB32_LE: + case VPX_IMG_FMT_ARGB: + case VPX_IMG_FMT_ARGB_LE: + bps = 32; + break; + case VPX_IMG_FMT_RGB24: + case VPX_IMG_FMT_BGR24: + bps = 24; + break; + case VPX_IMG_FMT_RGB565: + case VPX_IMG_FMT_RGB565_LE: + case VPX_IMG_FMT_RGB555: + case VPX_IMG_FMT_RGB555_LE: + case VPX_IMG_FMT_UYVY: + case VPX_IMG_FMT_YUY2: + case VPX_IMG_FMT_YVYU: + bps = 16; + break; + case VPX_IMG_FMT_I420: + case VPX_IMG_FMT_YV12: + case VPX_IMG_FMT_VPXI420: + case VPX_IMG_FMT_VPXYV12: + bps = 12; + break; + default: + bps = 16; + break; + } + + + + + + + + +Bankoski, et al. Informational [Page 286] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /* Get chroma shift values for this format */ + switch (fmt) + { + case VPX_IMG_FMT_I420: + case VPX_IMG_FMT_YV12: + case VPX_IMG_FMT_VPXI420: + case VPX_IMG_FMT_VPXYV12: + xcs = 1; + break; + default: + xcs = 0; + break; + } + + switch (fmt) + { + case VPX_IMG_FMT_I420: + case VPX_IMG_FMT_YV12: + case VPX_IMG_FMT_VPXI420: + case VPX_IMG_FMT_VPXYV12: + ycs = 1; + break; + default: + ycs = 0; + break; + } + + /* Calculate storage sizes given the chroma subsampling */ + align = (1 << xcs) - 1; + w = (d_w + align) & ~align; + align = (1 << ycs) - 1; + h = (d_h + align) & ~align; + s = (fmt & VPX_IMG_FMT_PLANAR) ? w : bps * w / 8; + s = (s + stride_align - 1) & ~(stride_align - 1); + + /* Allocate the new image */ + if (!img) + { + img = (vpx_image_t *)calloc(1, sizeof(vpx_image_t)); + + if (!img) + goto fail; + + img->self_allocd = 1; + } + + + + + + +Bankoski, et al. Informational [Page 287] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + else + { + memset(img, 0, sizeof(vpx_image_t)); + } + + img->img_data = img_data; + + if (!img_data) + { + img->img_data = malloc((fmt & VPX_IMG_FMT_PLANAR) ? + h * w * bps / 8 : h * s); + img->img_data_owner = 1; + } + + if (!img->img_data) + goto fail; + + img->fmt = fmt; + img->w = w; + img->h = h; + img->x_chroma_shift = xcs; + img->y_chroma_shift = ycs; + img->bps = bps; + + /* Calculate strides */ + img->stride[VPX_PLANE_Y] = img->stride[VPX_PLANE_ALPHA] = s; + img->stride[VPX_PLANE_U] = img->stride[VPX_PLANE_V] = s >> xcs; + + /* Default viewport to entire image */ + if (!vpx_img_set_rect(img, 0, 0, d_w, d_h)) + return img; + + fail: + vpx_img_free(img); + return NULL; + } + + vpx_image_t *vpx_img_alloc(vpx_image_t *img, + vpx_img_fmt_t fmt, + unsigned int d_w, + unsigned int d_h, + unsigned int stride_align) + { + return img_alloc_helper(img, fmt, d_w, d_h, stride_align, NULL); + } + + + + + + +Bankoski, et al. Informational [Page 288] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + vpx_image_t *vpx_img_wrap(vpx_image_t *img, + vpx_img_fmt_t fmt, + unsigned int d_w, + unsigned int d_h, + unsigned int stride_align, + unsigned char *img_data) + { + return img_alloc_helper(img, fmt, d_w, d_h, stride_align, + img_data); + } + + int vpx_img_set_rect(vpx_image_t *img, + unsigned int x, + unsigned int y, + unsigned int w, + unsigned int h) + { + unsigned char *data; + + if (x + w <= img->w && y + h <= img->h) + { + img->d_w = w; + img->d_h = h; + + /* Calculate plane pointers */ + if (!(img->fmt & VPX_IMG_FMT_PLANAR)) + { + img->planes[VPX_PLANE_PACKED] = + img->img_data + x * img->bps / 8 + y * + img->stride[VPX_PLANE_PACKED]; + } + else + { + data = img->img_data; + + if (img->fmt & VPX_IMG_FMT_HAS_ALPHA) + { + img->planes[VPX_PLANE_ALPHA] = + data + x + y * img->stride[VPX_PLANE_ALPHA]; + data += img->h * img->stride[VPX_PLANE_ALPHA]; + } + + img->planes[VPX_PLANE_Y] = + data + x + y * img->stride[VPX_PLANE_Y]; + data += img->h * img->stride[VPX_PLANE_Y]; + + + + + + +Bankoski, et al. Informational [Page 289] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + if (!(img->fmt & VPX_IMG_FMT_UV_FLIP)) + { + img->planes[VPX_PLANE_U] = data + + (x >> img->x_chroma_shift) + + (y >> img->y_chroma_shift) * + img->stride[VPX_PLANE_U]; + data += (img->h >> img->y_chroma_shift) * + img->stride[VPX_PLANE_U]; + img->planes[VPX_PLANE_V] = data + + (x >> img->x_chroma_shift) + + (y >> img->y_chroma_shift) * + img->stride[VPX_PLANE_V]; + } + else + { + img->planes[VPX_PLANE_V] = data + + (x >> img->x_chroma_shift) + + (y >> img->y_chroma_shift) * + img->stride[VPX_PLANE_V]; + data += (img->h >> img->y_chroma_shift) * + img->stride[VPX_PLANE_V]; + img->planes[VPX_PLANE_U] = data + + (x >> img->x_chroma_shift) + + (y >> img->y_chroma_shift) * + img->stride[VPX_PLANE_U]; + } + } + + return 0; + } + + return -1; + } + + void vpx_img_flip(vpx_image_t *img) + { + /* Note: In the calculation pointer adjustment calculation, we + * want the rhs to be promoted to a signed type. Section 6.3.1.8 + * of the ISO C99 standard [ISO-C99] indicates that if the + * adjustment parameter is unsigned, the stride parameter will be + * promoted to unsigned, causing errors when the lhs is a larger + * type than the rhs. + */ + img->planes[VPX_PLANE_Y] += (signed) + (img->d_h - 1) * img->stride[VPX_PLANE_Y]; + img->stride[VPX_PLANE_Y] = -img->stride[VPX_PLANE_Y]; + + + + + +Bankoski, et al. Informational [Page 290] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + img->planes[VPX_PLANE_U] += (signed) + ((img->d_h >> img->y_chroma_shift) - 1) + * img->stride[VPX_PLANE_U]; + img->stride[VPX_PLANE_U] = -img->stride[VPX_PLANE_U]; + + img->planes[VPX_PLANE_V] += (signed) + ((img->d_h >> img->y_chroma_shift) - 1) * + img->stride[VPX_PLANE_V]; + img->stride[VPX_PLANE_V] = -img->stride[VPX_PLANE_V]; + + img->planes[VPX_PLANE_ALPHA] += (signed) + (img->d_h - 1) * img->stride[VPX_PLANE_ALPHA]; + img->stride[VPX_PLANE_ALPHA] = -img->stride[VPX_PLANE_ALPHA]; + } + + void vpx_img_free(vpx_image_t *img) + { + if (img) + { + if (img->img_data && img->img_data_owner) + free(img->img_data); + + if (img->self_allocd) + free(img); + } + } + + ---- End code block ---------------------------------------- + +20.23. vpx_image.h + + ---- Begin code block -------------------------------------- + + /* + * Copyright (c) 2010, 2011, Google Inc. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be + * found in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + /*!\file + * \brief Describes the vpx image descriptor and associated + * operations + * + */ + + + +Bankoski, et al. Informational [Page 291] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + #ifdef __cplusplus + extern "C" { + #endif + + #ifndef VPX_IMAGE_H + #define VPX_IMAGE_H + + /*!\brief Current ABI version number + * + * \internal + * If this file is altered in any way that changes the ABI, this + * value must be bumped. Examples include, but are not limited + * to, changing types, removing or reassigning enums, + * adding/removing/rearranging fields to structures + */ + #define VPX_IMAGE_ABI_VERSION (1) /**<\hideinitializer*/ + + + #define VPX_IMG_FMT_PLANAR 0x100 /**< Image is a planar + format */ + #define VPX_IMG_FMT_UV_FLIP 0x200 /**< V plane precedes U plane + in memory */ + #define VPX_IMG_FMT_HAS_ALPHA 0x400 /**< Image has an alpha channel + component */ + + + /*!\brief List of supported image formats */ + typedef enum vpx_img_fmt { + VPX_IMG_FMT_NONE, + VPX_IMG_FMT_RGB24, /**< 24 bit per pixel packed RGB */ + VPX_IMG_FMT_RGB32, /**< 32 bit per pixel packed 0RGB */ + VPX_IMG_FMT_RGB565, /**< 16 bit per pixel, 565 */ + VPX_IMGFMT_RGB555, /**< 16 bit per pixel, 555 */ + VPX_IMG_FMT_UYVY, /**< UYVY packed YUV */ + VPX_IMG_FMT_YUY2, /**< YUYV packed YUV */ + VPX_IMG_FMT_YVYU, /**< YVYU packed YUV */ + VPX_IMG_FMT_BGR24, /**< 24 bit per pixel packed BGR */ + VPX_IMG_FMT_RGB32_LE, /**< 32 bit packed BGR0 */ + VPX_IMG_FMT_ARGB, /**< 32 bit packed ARGB, alpha=255 */ + VPX_IMG_FMT_ARGB_LE, /**< 32 bit packed BGRA, alpha=255 */ + VPX_IMG_FMT_RGB565_LE, /**< 16 bit per pixel, + gggbbbbb rrrrrggg */ + VPX_IMG_FMT_RGB555_LE, /**< 16 bit per pixel, + gggbbbbb 0rrrrrgg */ + VPX_IMG_FMT_YV12 = VPX_IMG_FMT_PLANAR | + VPX_IMG_FMT_UV_FLIP | 1, /**< planar YVU */ + VPX_IMG_FMT_I420 = VPX_IMG_FMT_PLANAR | 2, + + + + +Bankoski, et al. Informational [Page 292] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + VPX_IMG_FMT_VPXYV12 = VPX_IMG_FMT_PLANAR | + VPX_IMG_FMT_UV_FLIP | 3, /** < planar 4:2:0 format with + vpx color space */ + VPX_IMG_FMT_VPXI420 = VPX_IMG_FMT_PLANAR | 4 /** < planar + 4:2:0 format with vpx color space */ + } + vpx_img_fmt_t; /**< alias for enum vpx_img_fmt */ + + #if !defined(VPX_CODEC_DISABLE_COMPAT) || !VPX_CODEC_DISABLE_COMPAT + /** \deprecated Use #VPX_IMG_FMT_PLANAR */ + #define IMG_FMT_PLANAR VPX_IMG_FMT_PLANAR + /** \deprecated Use #VPX_IMG_FMT_UV_FLIP */ + #define IMG_FMT_UV_FLIP VPX_IMG_FMT_UV_FLIP + /** \deprecated Use #VPX_IMG_FMT_HAS_ALPHA */ + #define IMG_FMT_HAS_ALPHA VPX_IMG_FMT_HAS_ALPHA + + /*!\brief Deprecated list of supported image formats + * \deprecated New code should use #vpx_img_fmt + */ + #define img_fmt vpx_img_fmt + /*!\brief alias for enum img_fmt. + * \deprecated New code should use #vpx_img_fmt_t + */ + #define img_fmt_t vpx_img_fmt_t + + /** \deprecated Use #VPX_IMG_FMT_NONE */ + #define IMG_FMT_NONE VPX_IMG_FMT_NONE + /** \deprecated Use #VPX_IMG_FMT_RGB24 */ + #define IMG_FMT_RGB24 VPX_IMG_FMT_RGB24 + /** \deprecated Use #VPX_IMG_FMT_RGB32 */ + #define IMG_FMT_RGB32 VPX_IMG_FMT_RGB32 + /** \deprecated Use #VPX_IMG_FMT_RGB565 */ + #define IMG_FMT_RGB565 VPX_IMG_FMT_RGB565 + /** \deprecated Use #VPX_IMG_FMT_RGB555 */ + #define IMG_FMT_RGB555 VPX_IMG_FMT_RGB555 + /** \deprecated Use #VPX_IMG_FMT_UYVY */ + #define IMG_FMT_UYVY VPX_IMG_FMT_UYVY + /** \deprecated Use #VPX_IMG_FMT_YUY2 */ + #define IMG_FMT_YUY2 VPX_IMG_FMT_YUY2 + /** \deprecated Use #VPX_IMG_FMT_YVYU */ + #define IMG_FMT_YVYU VPX_IMG_FMT_YVYU + /** \deprecated Use #VPX_IMG_FMT_BGR24 */ + #define IMG_FMT_BGR24 VPX_IMG_FMT_BGR24 + /**< \deprecated Use #VPX_IMG_FMT_RGB32_LE */ + #define IMG_FMT_RGB32_LE VPX_IMG_FMT_RGB32_LE + /** \deprecated Use #VPX_IMG_FMT_ARGB */ + #define IMG_FMT_ARGB VPX_IMG_FMT_ARGB + + + + +Bankoski, et al. Informational [Page 293] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + /** \deprecated Use #VPX_IMG_FMT_ARGB_LE */ + #define IMG_FMT_ARGB_LE VPX_IMG_FMT_ARGB_LE + /** \deprecated Use #VPX_IMG_FMT_RGB565_LE */ + #define IMG_FMT_RGB565_LE VPX_IMG_FMT_RGB565_LE + /** \deprecated Use #VPX_IMG_FMT_RGB555_LE */ + #define IMG_FMT_RGB555_LE VPX_IMG_FMT_RGB555_LE + /** \deprecated Use #VPX_IMG_FMT_YV12 */ + #define IMG_FMT_YV12 VPX_IMG_FMT_YV12 + /** \deprecated Use #VPX_IMG_FMT_I420 */ + #define IMG_FMT_I420 VPX_IMG_FMT_I420 + /** \deprecated Use #VPX_IMG_FMT_VPXYV12 */ + #define IMG_FMT_VPXYV12 VPX_IMG_FMT_VPXYV12 + /** \deprecated Use #VPX_IMG_FMT_VPXI420 */ + #define IMG_FMT_VPXI420 VPX_IMG_FMT_VPXI420 + #endif /* VPX_CODEC_DISABLE_COMPAT */ + + /**\brief Image Descriptor */ + typedef struct vpx_image + { + vpx_img_fmt_t fmt; /**< Image Format */ + + /* Image storage dimensions */ + unsigned int w; /**< Stored image width */ + unsigned int h; /**< Stored image height */ + + /* Image display dimensions */ + unsigned int d_w; /**< Displayed image width */ + unsigned int d_h; /**< Displayed image height */ + + /* Chroma subsampling info */ + unsigned int x_chroma_shift; /**< subsampling order, X */ + unsigned int y_chroma_shift; /**< subsampling order, Y */ + + /* Image data pointers. */ + #define VPX_PLANE_PACKED 0 /**< To be used for all packed formats */ + #define VPX_PLANE_Y 0 /**< Y (Luminance) plane */ + #define VPX_PLANE_U 1 /**< U (Chroma) plane */ + #define VPX_PLANE_V 2 /**< V (Chroma) plane */ + #define VPX_PLANE_ALPHA 3 /**< A (Transparency) plane */ + #if !defined(VPX_CODEC_DISABLE_COMPAT) || !VPX_CODEC_DISABLE_COMPAT + #define PLANE_PACKED VPX_PLANE_PACKED + #define PLANE_Y VPX_PLANE_Y + #define PLANE_U VPX_PLANE_U + #define PLANE_V VPX_PLANE_V + #define PLANE_ALPHA VPX_PLANE_ALPHA + #endif + + + + + +Bankoski, et al. Informational [Page 294] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + unsigned char *planes[4]; /**< pointer to the top-left pixel + q for each plane */ + int stride[4]; /**< stride between rows for each plane */ + + int bps; /**< bits per sample (for packed formats) */ + + /* The following member may be set by the application to + * associate data with this image. + */ + void *user_priv; /**< may be set by the application to + associate data with this image. */ + + /* The following members should be treated as private. */ + unsigned char *img_data; /**< private */ + int img_data_owner; /**< private */ + int self_allocd; /**< private */ + } vpx_image_t; /**< alias for struct vpx_image */ + + /**\brief Representation of a rectangle on a surface */ + typedef struct vpx_image_rect + { + unsigned int x; /**< leftmost column */ + unsigned int y; /**< topmost row */ + unsigned int w; /**< width */ + unsigned int h; /**< height */ + } vpx_image_rect_t; /**< alias for struct vpx_image_rect */ + + /*!\brief Open a descriptor, allocating storage for the + * underlying image + * + * Returns a descriptor for storing an image of the given format. + * The storage for the descriptor is allocated on the heap. + * + * \param[in] img Pointer to storage for descriptor. + * If this parameter is NULL, the storage + * for the descriptor will be allocated + * on the heap. + * \param[in] fmt Format for the image + * \param[in] d_w Width of the image + * \param[in] d_h Height of the image + * \param[in] align Alignment, in bytes, of each row in + * the image. + * + * \return Returns a pointer to the initialized image descriptor. + * If the img parameter is non-null, the value of the img + * parameter will be returned. + */ + + + + +Bankoski, et al. Informational [Page 295] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + vpx_image_t *vpx_img_alloc(vpx_image_t *img, + vpx_img_fmt_t fmt, + unsigned int d_w, + unsigned int d_h, + unsigned int align); + + /*!\brief Open a descriptor, using existing storage for the + * underlying image + * + * Returns a descriptor for storing an image of the given format. + * The storage for descriptor has been allocated elsewhere, and a + * descriptor is desired to "wrap" that storage. + * + * \param[in] img Pointer to storage for descriptor. + * If this parameter is NULL, the storage + * for the descriptor will be + * allocated on the heap. + * \param[in] fmt Format for the image + * \param[in] d_w Width of the image + * \param[in] d_h Height of the image + * \param[in] align Alignment, in bytes, of each row in + * the image. + * \param[in] img_data Storage to use for the image + * + * \return Returns a pointer to the initialized image descriptor. + * If the img parameter is non-null, the value of the img + * parameter will be returned. + */ + vpx_image_t *vpx_img_wrap(vpx_image_t *img, + vpx_img_fmt_t fmt, + unsigned int d_w, + unsigned int d_h, + unsigned int align, + unsigned char *img_data); + + + /*!\brief Set the rectangle identifying the displayed portion of + * the image + * + * Updates the displayed rectangle (aka viewport) on the image + * surface to match the specified coordinates and size. + * + * \param[in] img Image descriptor + * \param[in] x leftmost column + * \param[in] y topmost row + * \param[in] w width + * \param[in] h height + * + + + +Bankoski, et al. Informational [Page 296] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + * \return 0 if the requested rectangle is valid, non-zero + * otherwise. + */ + int vpx_img_set_rect(vpx_image_t *img, + unsigned int x, + unsigned int y, + unsigned int w, + unsigned int h); + + + /*!\brief Flip the image vertically (top for bottom) + * + * Adjusts the image descriptor's pointers and strides to make + * the image be referenced upside-down. + * + * \param[in] img Image descriptor + */ + void vpx_img_flip(vpx_image_t *img); + + /*!\brief Close an image descriptor + * + * Frees all allocated storage associated with an image + * descriptor. + * + * \param[in] img Image descriptor + */ + void vpx_img_free(vpx_image_t *img); + + #endif + #ifdef __cplusplus + } + #endif + + ---- End code block ---------------------------------------- + + + + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 297] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +20.24. vpx_integer.h + + ---- Begin code block -------------------------------------- + + /* + * Copyright (c) 2010, 2011, Google Inc. All rights reserved. + * + * Use of this source code is governed by a BSD-style license + * that can be found in the LICENSE file in the root of the source + * tree. An additional intellectual property rights grant can be + * found in the file PATENTS. All contributing project authors may + * be found in the AUTHORS file in the root of the source tree. + */ + + #ifndef VPX_INTEGER_H + #define VPX_INTEGER_H + + /* get ptrdiff_t, size_t, wchar_t, NULL */ + #include <stddef.h> + + #if defined(_MSC_VER) || defined(VPX_EMULATE_INTTYPES) + typedef signed char int8_t; + typedef signed short int16_t; + typedef signed int int32_t; + typedef unsigned char uint8_t; + typedef unsigned short uint16_t; + typedef unsigned int uint32_t; + + #if defined(_MSC_VER) + typedef signed __int64 int64_t; + typedef unsigned __int64 uint64_t; + #define PRId64 "I64d" + #endif + + #ifdef HAVE_ARMV6 + typedef unsigned int int_fast16_t; + #else + typedef signed short int_fast16_t; + #endif + typedef signed char int_fast8_t; + typedef unsigned char uint_fast8_t; + + #ifndef _UINTPTR_T_DEFINED + typedef unsigned int uintptr_t; + #endif + + + + + + +Bankoski, et al. Informational [Page 298] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + #else + + /* Most platforms have the C99 standard integer types. */ + + #if defined(__cplusplus) && !defined(__STDC_FORMAT_MACROS) + #define __STDC_FORMAT_MACROS + #endif + #include <stdint.h> + #include <inttypes.h> + + #endif + + #endif + + ---- End code block ---------------------------------------- + +20.25. AUTHORS File + + Aaron Watry <awatry@gmail.com> + + Adrian Grange <agrange@google.com> + + Alex Converse <alex.converse@gmail.com> + + Andoni Morales Alastruey <ylatuya@gmail.com> + + Andres Mejia <mcitadel@gmail.com> + + Attila Nagy <attilanagy@google.com> + + Fabio Pedretti <fabio.ped@libero.it> + + Frank Galligan <fgalligan@google.com> + + Fredrik Soederquist <fs@opera.com> + + Fritz Koenig <frkoenig@google.com> + + Gaute Strokkenes <gaute.strokkenes@broadcom.com> + + Giuseppe Scrivano <gscrivano@gnu.org> + + Guillermo Ballester Valor <gbvalor@gmail.com> + + Henrik Lundin <hlundin@google.com> + + James Berry <jamesberry@google.com> + + + + +Bankoski, et al. Informational [Page 299] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + James Zern <jzern@google.com> + + Jan Kratochvil <jan.kratochvil@redhat.com> + + Jeff Muizelaar <jmuizelaar@mozilla.com> + + Jim Bankoski <jimbankoski@google.com> + + Johann Koenig <johannkoenig@google.com> + + John Koleszar <jkoleszar@google.com> + + Justin Clift <justin@salasaga.org> + + Justin Lebar <justin.lebar@gmail.com> + + Luca Barbato <lu_zero@gentoo.org> + + Makoto Kato <makoto.kt@gmail.com> + + Martin Ettl <ettl.martin78@googlemail.com> + + Michael Kohler <michaelkohler@live.com> + + Mikhal Shemer <mikhal@google.com> + + Pascal Massimino <pascal.massimino@gmail.com> + + Patrik Westin <patrik.westin@gmail.com> + + Paul Wilkins <paulwilkins@google.com> + + Pavol Rusnak <stick@gk2.sk> + + Philip Jaegenstedt <philipj@opera.com> + + Scott LaVarnway <slavarnway@google.com> + + Tero Rintaluoma <teror@google.com> + + Timothy B. Terriberry <tterribe@xiph.org> + + Tom Finegan <tomfinegan@google.com> + + Yaowu Xu <yaowu@google.com> + + Yunqing Wang <yunqingwang@google.com> + + + + +Bankoski, et al. Informational [Page 300] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + + Google Inc. + + The Mozilla Foundation + + The Xiph.Org Foundation + +20.26. LICENSE + + Copyright (c) 2010, 2011, Google Inc. All rights reserved. + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions + are met: + + o Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + o Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in + the documentation and/or other materials provided with the + distribution. + + o Neither the name of Google nor the names of its contributors may + be used to endorse or promote products derived from this software + without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY + WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + POSSIBILITY OF SUCH DAMAGE. + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 301] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +20.27. PATENTS + + Additional IP Rights Grant (Patents) + + "This implementation" means the copyrightable works distributed by + Google as part of the WebM Project. + + Google hereby grants to you a perpetual, worldwide, non-exclusive, + no-charge, royalty-free, irrevocable (except as stated in this + section) patent license to make, have made, use, offer to sell, sell, + import, transfer, and otherwise run, modify and propagate the + contents of this implementation of VP8, where such license applies + only to those patent claims, both currently owned by Google and + acquired in the future, licensable by Google that are necessarily + infringed by this implementation of VP8. This grant does not include + claims that would be infringed only as a consequence of further + modification of this implementation. If you or your agent or + exclusive licensee institute or order or agree to the institution of + patent litigation against any entity (including a cross-claim or + counterclaim in a lawsuit) alleging that this implementation of VP8 + or any code incorporated within this implementation of VP8 + constitutes direct or contributory patent infringement, or inducement + of patent infringement, then any patent rights granted to you under + this License for this implementation of VP8 shall terminate as of the + date such litigation is filed. + +21. Security Considerations + + A VP8 decoder should take appropriate security considerations into + account, as outlined in [RFC4732] and [RFC3552]. It is extremely + important that a decoder be robust against malicious payloads. + Malicious payloads must not cause the decoder to overrun its + allocated memory or to consume inordinate resources. Although + encoder issues are typically rarer, the same applies to an encoder. + Malicious stream data must not cause the encoder to misbehave, as + this might allow an attacker access to transcoding gateways. + + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 302] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +22. References + +22.1. Normative Reference + + [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate + Requirement Levels", BCP 14, RFC 2119, March 1997. + +22.2. Informative References + + [Bell] Bell, T., Cleary, J., and I. Witten, "Text Compression", + 1990. + + [ISO-C99] International Organization for Standardization, + "Information technology -- Programming languages -- C", + ISO/IEC 9899:1999, 1999. + + [ITU-R_BT.601] + International Telecommunication Union, "ITU BT.601-7: + Studio encoding parameters of digital television for + standard 4:3 and wide screen 16:9 aspect ratios", + March 2011. + + [Kernighan] Kernighan, B. and D. Ritchie, "The C Programming Language + (2nd edition)", April 1988. + + [Loeffler] Loeffler, C., Ligtenberg , A., and G. Moschytz, + "Practical Fast 1-D DCT Algorithms with 11 + Multiplications", May 1989. + + [RFC3552] Rescorla, E. and B. Korver, "Guidelines for Writing RFC + Text on Security Considerations", BCP 72, RFC 3552, + July 2003. + + [RFC4732] Handley, M., Ed., Rescorla, E., Ed., and IAB, "Internet + Denial-of-Service Considerations", RFC 4732, + December 2006. + + [Shannon] Shannon, C., "A Mathematical Theory of Communication", + Bell System Technical Journal Vol. 27, pp. 379-423 and + 623-656, July and October 1948. + + + + + + + + + + + +Bankoski, et al. Informational [Page 303] + +RFC 6386 VP8 Data Format and Decoding Guide November 2011 + + +Authors' Addresses + + James Bankoski + Google Inc. + + EMail: jimbankoski@google.com + + + John Koleszar + Google Inc. + + EMail: jkoleszar@google.com + + + Lou Quillio + Google Inc. + + EMail: louquillio@google.com + + + Janne Salonen + Google Inc. + + EMail: jsalonen@google.com + + + Paul Wilkins + Google Inc. + + EMail: paulwilkins@google.com + + + Yaowu Xu + Google Inc. + + EMail: yaowu@google.com + + + + + + + + + + + + + + + +Bankoski, et al. Informational [Page 304] + |