| < draft-bankoski-vp8-bitstream-04.txt | draft-bankoski-vp8-bitstream-05.txt > | |||
|---|---|---|---|---|
| Network Working Group J. Bankoski | Network Working Group J. Bankoski | |||
| Internet-Draft J. Koleszar | Internet-Draft J. Koleszar | |||
| Intended status: Informational L. Quillio | Intended status: Informational L. Quillio | |||
| Expires: December 18, 2011 J. Salonen | Expires: February 3, 2012 J. Salonen | |||
| P. Wilkins | P. Wilkins | |||
| Y. Xu | Y. Xu | |||
| Google Inc. | Google Inc. | |||
| June 16, 2011 | August 2, 2011 | |||
| VP8 Data Format and Decoding Guide | VP8 Data Format and Decoding Guide | |||
| draft-bankoski-vp8-bitstream-04 | draft-bankoski-vp8-bitstream-05 | |||
| Abstract | Abstract | |||
| This document describes the VP8 compressed video data format, | This document describes the VP8 compressed video data format, | |||
| together with a discussion of the decoding procedure for the format. | together with a discussion of the decoding procedure for the format. | |||
| Status of this Memo | Status of this Memo | |||
| This Internet-Draft is submitted in full conformance with the | This Internet-Draft is submitted in full conformance with the | |||
| provisions of BCP 78 and BCP 79. | provisions of BCP 78 and BCP 79. | |||
| skipping to change at page 1, line 35 ¶ | skipping to change at page 1, line 35 ¶ | |||
| Internet-Drafts are working documents of the Internet Engineering | Internet-Drafts are working documents of the Internet Engineering | |||
| Task Force (IETF). Note that other groups may also distribute | Task Force (IETF). Note that other groups may also distribute | |||
| working documents as Internet-Drafts. The list of current Internet- | working documents as Internet-Drafts. The list of current Internet- | |||
| Drafts is at http://datatracker.ietf.org/drafts/current/. | Drafts is at http://datatracker.ietf.org/drafts/current/. | |||
| Internet-Drafts are draft documents valid for a maximum of six months | Internet-Drafts are draft documents valid for a maximum of six months | |||
| and may be updated, replaced, or obsoleted by other documents at any | and may be updated, replaced, or obsoleted by other documents at any | |||
| time. It is inappropriate to use Internet-Drafts as reference | time. It is inappropriate to use Internet-Drafts as reference | |||
| material or to cite them other than as "work in progress." | material or to cite them other than as "work in progress." | |||
| This Internet-Draft will expire on December 18, 2011. | This Internet-Draft will expire on February 3, 2012. | |||
| Copyright Notice | Copyright Notice | |||
| Copyright (c) 2011 IETF Trust and the persons identified as the | Copyright (c) 2011 IETF Trust and the persons identified as the | |||
| document authors. All rights reserved. | document authors. All rights reserved. | |||
| This document is subject to BCP 78 and the IETF Trust's Legal | This document is subject to BCP 78 and the IETF Trust's Legal | |||
| Provisions Relating to IETF Documents | Provisions Relating to IETF Documents | |||
| (http://trustee.ietf.org/license-info) in effect on the date of | (http://trustee.ietf.org/license-info) in effect on the date of | |||
| publication of this document. Please review these documents | publication of this document. Please review these documents | |||
| skipping to change at page 3, line 43 ¶ | skipping to change at page 3, line 43 ¶ | |||
| 20.5. dixie.h . . . . . . . . . . . . . . . . . . . . . . . . 163 | 20.5. dixie.h . . . . . . . . . . . . . . . . . . . . . . . . 163 | |||
| 20.6. dixie_loopfilter.c . . . . . . . . . . . . . . . . . . . 170 | 20.6. dixie_loopfilter.c . . . . . . . . . . . . . . . . . . . 170 | |||
| 20.7. dixie_loopfilter.h . . . . . . . . . . . . . . . . . . . 182 | 20.7. dixie_loopfilter.h . . . . . . . . . . . . . . . . . . . 182 | |||
| 20.8. idct_add.c . . . . . . . . . . . . . . . . . . . . . . . 182 | 20.8. idct_add.c . . . . . . . . . . . . . . . . . . . . . . . 182 | |||
| 20.9. idct_add.h . . . . . . . . . . . . . . . . . . . . . . . 186 | 20.9. idct_add.h . . . . . . . . . . . . . . . . . . . . . . . 186 | |||
| 20.10. mem.h . . . . . . . . . . . . . . . . . . . . . . . . . 186 | 20.10. mem.h . . . . . . . . . . . . . . . . . . . . . . . . . 186 | |||
| 20.11. modemv.c . . . . . . . . . . . . . . . . . . . . . . . . 188 | 20.11. modemv.c . . . . . . . . . . . . . . . . . . . . . . . . 188 | |||
| 20.12. modemv.h . . . . . . . . . . . . . . . . . . . . . . . . 203 | 20.12. modemv.h . . . . . . . . . . . . . . . . . . . . . . . . 203 | |||
| 20.13. modemv_data.h . . . . . . . . . . . . . . . . . . . . . 203 | 20.13. modemv_data.h . . . . . . . . . . . . . . . . . . . . . 203 | |||
| 20.14. predict.c . . . . . . . . . . . . . . . . . . . . . . . 208 | 20.14. predict.c . . . . . . . . . . . . . . . . . . . . . . . 208 | |||
| 20.15. predict.h . . . . . . . . . . . . . . . . . . . . . . . 238 | 20.15. predict.h . . . . . . . . . . . . . . . . . . . . . . . 239 | |||
| 20.16. tokens.c . . . . . . . . . . . . . . . . . . . . . . . . 238 | 20.16. tokens.c . . . . . . . . . . . . . . . . . . . . . . . . 239 | |||
| 20.17. tokens.h . . . . . . . . . . . . . . . . . . . . . . . . 248 | 20.17. tokens.h . . . . . . . . . . . . . . . . . . . . . . . . 250 | |||
| 20.18. vp8_prob_data.h . . . . . . . . . . . . . . . . . . . . 257 | 20.18. vp8_prob_data.h . . . . . . . . . . . . . . . . . . . . 250 | |||
| 20.19. vpx_codec_internal.h . . . . . . . . . . . . . . . . . . 266 | 20.19. vpx_codec_internal.h . . . . . . . . . . . . . . . . . . 259 | |||
| 20.20. vpx_decoder.h . . . . . . . . . . . . . . . . . . . . . 276 | 20.20. vpx_decoder.h . . . . . . . . . . . . . . . . . . . . . 269 | |||
| 20.21. vpx_integer.h . . . . . . . . . . . . . . . . . . . . . 283 | 20.21. vpx_decoder_compat.h . . . . . . . . . . . . . . . . . . 276 | |||
| 20.22. AUTHORS . . . . . . . . . . . . . . . . . . . . . . . . 285 | 20.22. vpx_image.c . . . . . . . . . . . . . . . . . . . . . . 290 | |||
| 20.23. LICENSE . . . . . . . . . . . . . . . . . . . . . . . . 286 | 20.23. vpx_image.h . . . . . . . . . . . . . . . . . . . . . . 296 | |||
| 20.24. PATENTS . . . . . . . . . . . . . . . . . . . . . . . . 287 | 20.24. vpx_integer.h . . . . . . . . . . . . . . . . . . . . . 302 | |||
| 21. References . . . . . . . . . . . . . . . . . . . . . . . . . 289 | 20.25. AUTHORS . . . . . . . . . . . . . . . . . . . . . . . . 303 | |||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 290 | 20.26. LICENSE . . . . . . . . . . . . . . . . . . . . . . . . 305 | |||
| 20.27. PATENTS . . . . . . . . . . . . . . . . . . . . . . . . 306 | ||||
| 21. Security Considerations . . . . . . . . . . . . . . . . . . . 307 | ||||
| 22. IANA Considerations . . . . . . . . . . . . . . . . . . . . . 308 | ||||
| 23. Informative References . . . . . . . . . . . . . . . . . . . 309 | ||||
| Authors' Addresses . . . . . . . . . . . . . . . . . . . . . . . 310 | ||||
| 1. Introduction | 1. Introduction | |||
| This document describes the VP8 compressed video data format, | This document describes the VP8 compressed video data format, | |||
| together with a discussion of the decoding procedure for the 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 | It is intended to be used in conjunction with and as a guide to the | |||
| reference decoder source code provided in Attachment One. If there | reference decoder source code provided in Attachment One. If there | |||
| are any conflicts between this narrative and the reference source | are any conflicts between this narrative and the reference source | |||
| code, the reference source code should be considered correct. The | code, the reference source code should be considered correct. The | |||
| bitstream is defined by the reference source code and not this | bitstream is defined by the reference source code and not this | |||
| skipping to change at page 8, line 26 ¶ | skipping to change at page 8, line 26 ¶ | |||
| that the zeroth DCT coefficients of the Y subblocks. This "higher- | that the zeroth DCT coefficients of the Y subblocks. This "higher- | |||
| level" WHT is a substitute for the explicit specification of those | level" WHT is a substitute for the explicit specification of those | |||
| coefficients, in exactly the same way as the DCT of a subblock | coefficients, in exactly the same way as the DCT of a subblock | |||
| substitutes for the specification of the pixel values comprising the | substitutes for the specification of the pixel values comprising the | |||
| subblock. We consider this 4x4 array as a second-order subblock | subblock. We consider this 4x4 array as a second-order subblock | |||
| called Y2, and think of a macroblock as containing 24 "real" | called Y2, and think of a macroblock as containing 24 "real" | |||
| subblocks and, sometimes, a 25th "virtual" subblock. This is dealt | subblocks and, sometimes, a 25th "virtual" subblock. This is dealt | |||
| with further in Chapter 13. | with further in Chapter 13. | |||
| The frame layout used by the reference decoder may be found in the | The frame layout used by the reference decoder may be found in the | |||
| file yv12config.h. | file vpx_image.h. | |||
| 3. Compressed Frame Types | 3. Compressed Frame Types | |||
| There are only two types of frames in VP8. | There are only two types of frames in VP8. | |||
| Intraframes (also called key frames and, in MPEG terminology, | Intraframes (also called key frames and, in MPEG terminology, | |||
| I-frames) are decoded without reference to any other frame in a | I-frames) are decoded without reference to any other frame in a | |||
| sequence, that is, the decompressor reconstructs such frames | sequence, that is, the decompressor reconstructs such frames | |||
| beginning from its "default" state. Key frames provide random access | beginning from its "default" state. Key frames provide random access | |||
| (or seeking) points in a video stream. | (or seeking) points in a video stream. | |||
| skipping to change at page 15, line 40 ¶ | skipping to change at page 15, line 40 ¶ | |||
| straightforward, many of the details are quite complex. The | straightforward, many of the details are quite complex. The | |||
| management of probabilities is particularly elaborate. Not only do | management of probabilities is particularly elaborate. Not only do | |||
| the various modes of intra-prediction and motion vector specification | the various modes of intra-prediction and motion vector specification | |||
| have associated probabilities but they, together with the coding of | have associated probabilities but they, together with the coding of | |||
| DCT coefficients and motion vectors, often base these probabilities | DCT coefficients and motion vectors, often base these probabilities | |||
| on a variety of contextual information (calculated from what has been | on a variety of contextual information (calculated from what has been | |||
| decoded so far), as well as on explicit modification via the frame | decoded so far), as well as on explicit modification via the frame | |||
| header. | header. | |||
| The "top-level" of decoding and frame reconstruction is implemented | The "top-level" of decoding and frame reconstruction is implemented | |||
| in the reference decoder files onyxd_if.c and decodframe.c. | in the reference decoder files dixie.c. | |||
| This concludes our summary of decoding and reconstruction; we | This concludes our summary of decoding and reconstruction; we | |||
| continue by discussing the individual aspects in more depth. | continue by discussing the individual aspects in more depth. | |||
| A reasonable "divide and conquer" approach to implementation of a | A reasonable "divide and conquer" approach to implementation of a | |||
| decoder is to begin by decoding streams composed exclusively of key | decoder is to begin by decoding streams composed exclusively of key | |||
| frames. After that works reliably, interframe handling can be added | frames. After that works reliably, interframe handling can be added | |||
| more easily than if complete functionality were attempted | more easily than if complete functionality were attempted | |||
| immediately. In accordance with this, we first discuss components | immediately. In accordance with this, we first discuss components | |||
| needed to decode key frames (most of which are also used in the | needed to decode key frames (most of which are also used in the | |||
| skipping to change at page 24, line 31 ¶ | skipping to change at page 24, line 31 ¶ | |||
| 7.3. Actual Implementation | 7.3. Actual Implementation | |||
| The C code below gives complete implementations of the encoder and | The C code below gives complete implementations of the encoder and | |||
| decoder described above. While they are logically identical to the | decoder described above. While they are logically identical to the | |||
| "bit-at-a-time" versions, they internally buffer a couple of extra | "bit-at-a-time" versions, they internally buffer a couple of extra | |||
| bytes of the bitstream. This allows I/O to be done (more | bytes of the bitstream. This allows I/O to be done (more | |||
| practically) a byte at a time and drastically reduces the number of | practically) a byte at a time and drastically reduces the number of | |||
| carries the encoder has to propagate into the already-written data. | carries the encoder has to propagate into the already-written data. | |||
| Another (logically equivalent) implementation may be found in the | Another (logically equivalent) implementation may be found in the | |||
| reference decoder files dboolhuff.h and dboolhuff.c. | reference decoder files bool_decoder.h. | |||
| ---- Begin code block -------------------------------------- | ---- Begin code block -------------------------------------- | |||
| /* Encoder first */ | /* Encoder first */ | |||
| typedef struct { | typedef struct { | |||
| uint8 *output; /* ptr to next byte to be written */ | uint8 *output; /* ptr to next byte to be written */ | |||
| uint32 range; /* 128 <= range <= 255 */ | uint32 range; /* 128 <= range <= 255 */ | |||
| uint32 bottom; /* minimum value of remaining output */ | uint32 bottom; /* minimum value of remaining output */ | |||
| int bit_count; /* # of shifts before an output byte | int bit_count; /* # of shifts before an output byte | |||
| skipping to change at page 32, line 32 ¶ | skipping to change at page 32, line 32 ¶ | |||
| /* Descend tree until leaf is reached */ | /* Descend tree until leaf is reached */ | |||
| while( ( i = t[ i + read_bool( d, p[i>>1]) ] ) > 0) {} | while( ( i = t[ i + read_bool( d, p[i>>1]) ] ) > 0) {} | |||
| return -i; /* return value is negation of nonpositive index */ | return -i; /* return value is negation of nonpositive index */ | |||
| } | } | |||
| ---- End code block ---------------------------------------- | ---- End code block ---------------------------------------- | |||
| Tree-based decoding is implemented in the reference decoder file | Tree-based decoding is implemented in the reference decoder file | |||
| tree_reader.h. | bool_decoder.h. | |||
| 8.2. Tree Coding Example | 8.2. Tree Coding Example | |||
| As a multi-part example, without getting too far into the semantics | As a multi-part example, without getting too far into the semantics | |||
| of macroblock decoding (which is of course taken up below), we look | of macroblock decoding (which is of course taken up below), we look | |||
| at the "mode" coding for intra-predicted macroblocks. | at the "mode" coding for intra-predicted macroblocks. | |||
| It so happens that, because of a difference in statistics, the Y (or | 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 | luma) mode encoding uses two different trees: one for key frames and | |||
| another for interframes. This is the only instance in VP8 of the | another for interframes. This is the only instance in VP8 of the | |||
| skipping to change at page 35, line 12 ¶ | skipping to change at page 35, line 12 ¶ | |||
| probability table layouts as described in this document (and in the | probability table layouts as described in this document (and in the | |||
| reference code) for all tree-coded data in VP8. | reference code) for all tree-coded data in VP8. | |||
| 9. Frame Header | 9. Frame Header | |||
| The uncompressed data chunk at the start of each frame and the first | The uncompressed data chunk at the start of each frame and the first | |||
| part of the first data partition contains information pertaining to | part of the first data partition contains information pertaining to | |||
| the frame as a whole. We list the fields in the order of occurrence, | the frame as a whole. We list the fields in the order of occurrence, | |||
| giving details for some of the fields. Other details are postponed | giving details for some of the fields. Other details are postponed | |||
| until a more logical point in our overall description. Most of the | until a more logical point in our overall description. Most of the | |||
| header decoding occurs in the reference decoder file decodeframe.c. | header decoding occurs in the reference decoder file dixie.c. | |||
| 9.1. Uncompressed Data Chunk | 9.1. Uncompressed Data Chunk | |||
| The uncompressed data chunk comprises a common (for key frames and | The uncompressed data chunk comprises a common (for key frames and | |||
| interframes) 3-byte frame tag that contains four fields, as follows: | interframes) 3-byte frame tag that contains four fields, as follows: | |||
| 1. A 1-bit frame type (0 for key frames, 1 for interframes). | 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 | 2. A 3-bit version number (0 - 3 are defined as four different | |||
| profiles with different decoding complexity; other values may be | profiles with different decoding complexity; other values may be | |||
| skipping to change at page 44, line 52 ¶ | skipping to change at page 44, line 52 ¶ | |||
| | | | | | | | | |||
| | F | If true, followed by three L(8)s updating the | | | F | If true, followed by three L(8)s updating the | | |||
| | | probabilities for the different types of intra-prediction | | | | probabilities for the different types of intra-prediction | | |||
| | | for the chroma planes. These probabilities correspond to | | | | for the chroma planes. These probabilities correspond to | | |||
| | | the even positions in the uv_mode_tree array given above. | | | | the even positions in the uv_mode_tree array given above. | | |||
| | | | | | | | | |||
| | X | Motion vector probability update. The details will be | | | X | Motion vector probability update. The details will be | | |||
| | | given after the discussion of motion vector decoding. | | | | given after the discussion of motion vector decoding. | | |||
| +-------+-----------------------------------------------------------+ | +-------+-----------------------------------------------------------+ | |||
| Decoding of this portion (only) of the frame header is handled in the | Decoding of this portion of the frame header is handled in the | |||
| reference decoder file decodemv.c. | reference decoder file dixie.c. | |||
| 9.11. Remaining Frame Header Data (Key Frame) | 9.11. Remaining Frame Header Data (Key Frame) | |||
| +-------+-----------------------------------------------------------+ | +-------+-----------------------------------------------------------+ | |||
| | Index | Description | | | Index | Description | | |||
| +-------+-----------------------------------------------------------+ | +-------+-----------------------------------------------------------+ | |||
| | L(1) | mb_no_coeff_skip. This flag indicates at the frame level | | | L(1) | mb_no_coeff_skip. This flag indicates at the frame level | | |||
| | | if skipping of macroblocks with no non-zero coefficients | | | | if skipping of macroblocks with no non-zero coefficients | | |||
| | | is enabled. If it is set to 0 then prob_skip_false is | | | | 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 | | | | not read and mb_skip_coeff is forced to 0 for all | | |||
| | | macroblocks (see Sections 11.1 and 12.1). | | | | macroblocks (see Sections 11.1 and 12.1). | | |||
| | | | | | | | | |||
| | L(8) | prob_skip_false = Probability used for decoding a | | | L(8) | prob_skip_false = Probability used for decoding a | | |||
| | | macroblock level flag, which indicates if a macroblock | | | | macroblock level flag, which indicates if a macroblock | | |||
| | | has any non-zero coefficients. Only read if | | | | has any non-zero coefficients. Only read if | | |||
| | | mb_no_coeff_skip is 1. | | | | mb_no_coeff_skip is 1. | | |||
| +-------+-----------------------------------------------------------+ | +-------+-----------------------------------------------------------+ | |||
| Decoding of this portion of the frame header is handled in the | Decoding of this portion of the frame header is handled in the | |||
| reference decoder file demode.c. | reference decoder file modemv.c. | |||
| This completes the layout of the frame header. The remainder of the | This completes the layout of the frame header. The remainder of the | |||
| first data partition consists of macroblock-level prediction data. | first data partition consists of macroblock-level prediction data. | |||
| After the frame header is processed, all probabilities needed to | After the frame header is processed, all probabilities needed to | |||
| decode the prediction and residue data are known and will not change | decode the prediction and residue data are known and will not change | |||
| until the next frame. | until the next frame. | |||
| 10. Segment-based Feature Adjustments | 10. Segment-based Feature Adjustments | |||
| skipping to change at page 46, line 41 ¶ | skipping to change at page 46, line 41 ¶ | |||
| ---- End code block ---------------------------------------- | ---- End code block ---------------------------------------- | |||
| ... combined with a 3-entry probability table | ... combined with a 3-entry probability table | |||
| mb_segment_tree_probs[3]. The macroblock's segment_id is used later | 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 | in the decoding process to look into the segment_feature_data table | |||
| and determine how the quantizer and loop filter levels are adjusted. | and determine how the quantizer and loop filter levels are adjusted. | |||
| The decoding of segment_id, together with the parsing of intra- | The decoding of segment_id, together with the parsing of intra- | |||
| prediction modes (which is taken up next), is implemented in the | prediction modes (which is taken up next), is implemented in the | |||
| reference decoder file demode.c. | reference decoder file modemv.c. | |||
| 11. Key Frame Macroblock Prediction Records | 11. Key Frame Macroblock Prediction Records | |||
| After the features described above, the macroblock prediction record | After the features described above, the macroblock prediction record | |||
| next specifies the prediction mode used for the macroblock. | next specifies the prediction mode used for the macroblock. | |||
| 11.1. mb_skip_coeff | 11.1. mb_skip_coeff | |||
| The single bool flag is decoded using prob_skip_false if and only if | The single bool flag is decoded using prob_skip_false if and only if | |||
| mb_no_coeff_skip is set to 1 (see sections 9.10 and 9.11). If | mb_no_coeff_skip is set to 1 (see sections 9.10 and 9.11). If | |||
| skipping to change at page 59, line 36 ¶ | skipping to change at page 59, line 36 ¶ | |||
| } while( ++r < 8); | } while( ++r < 8); | |||
| } | } | |||
| ---- End code block ---------------------------------------- | ---- End code block ---------------------------------------- | |||
| Note that the process could equivalently be described as propagating | Note that the process could equivalently be described as propagating | |||
| the vertical differences between pixels in L (starting from P), using | the vertical differences between pixels in L (starting from P), using | |||
| the pixels from A to start each column. | the pixels from A to start each column. | |||
| An implementation of chroma intra-prediction may be found in the | An implementation of chroma intra-prediction may be found in the | |||
| reference decoder file reconintra.c. | reference decoder file predict.c. | |||
| Unlike DC_PRED, for macroblocks on the top row or left edge TM_PRED | 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) | does use the out-of-bounds values of 127 and 129 (respectively) | |||
| defined for V_PRED and H_PRED. | defined for V_PRED and H_PRED. | |||
| 12.3. Luma Prediction | 12.3. Luma Prediction | |||
| The prediction processes for the first four 16x16 luma modes | The prediction processes for the first four 16x16 luma modes | |||
| (DC_PRED, V_PRED, H_PRED, and TM_PRED) are essentially identical to | (DC_PRED, V_PRED, H_PRED, and TM_PRED) are essentially identical to | |||
| the corresponding chroma prediction processes described above, the | the corresponding chroma prediction processes described above, the | |||
| only difference being that we are predicting a single 16x16 luma | only difference being that we are predicting a single 16x16 luma | |||
| block instead of two 8x8 chroma blocks. | block instead of two 8x8 chroma blocks. | |||
| Thus, the row "A" and column "L" here contain 16 pixels, the DC | 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), | 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 | and we of course fill the entire prediction buffer, that is, 16 rows | |||
| (or columns) containing 16 pixels each. The reference implementation | (or columns) containing 16 pixels each. The reference implementation | |||
| of 16x16 luma prediction is also in reconintra.c. | of 16x16 luma prediction is also in predict.c. | |||
| In the remaining luma mode (B_PRED), each 4x4 Y subblock is | In the remaining luma mode (B_PRED), each 4x4 Y subblock is | |||
| independently predicted using one of ten modes (listed, along with | independently predicted using one of ten modes (listed, along with | |||
| their encodings, in Chapter 11). | their encodings, in Chapter 11). | |||
| Also, unlike the full-macroblock modes already described, some of the | Also, unlike the full-macroblock modes already described, some of the | |||
| subblock modes use prediction pixels above and to the right of the | subblock modes use prediction pixels above and to the right of the | |||
| current subblock. In detail, each 4x4 subblock "B" is predicted | current subblock. In detail, each 4x4 subblock "B" is predicted | |||
| using (at most) the 4-pixel column "L" immediately to the left of B | 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 | and the 8-pixel row "A" immediately above B, consisting of the 4 | |||
| skipping to change at page 74, line 34 ¶ | skipping to change at page 74, line 34 ¶ | |||
| if( read_bool( d, coef_update_probs [i] [j] [k] [t])) | if( read_bool( d, coef_update_probs [i] [j] [k] [t])) | |||
| coef_probs [i] [j] [k] [t] = read_literal( d, 8); | coef_probs [i] [j] [k] [t] = read_literal( d, 8); | |||
| } while( ++t < num_dct_tokens - 1); | } while( ++t < num_dct_tokens - 1); | |||
| } while( ++k < 3); | } while( ++k < 3); | |||
| } while( ++j < 8); | } while( ++j < 8); | |||
| } while( ++i < 4); | } while( ++i < 4); | |||
| ---- End code block ---------------------------------------- | ---- End code block ---------------------------------------- | |||
| The (constant) update probabilities are as follows (they may also be | The (constant) update probabilities are as follows: | |||
| found in the reference decoder file coef_update_probs.c). | ||||
| ---- Begin code block -------------------------------------- | ---- Begin code block -------------------------------------- | |||
| const Prob coef_update_probs [4] [8] [3] [num_dct_tokens-1] = | const Prob coef_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}, | { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, | |||
| { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} | { 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255} | |||
| skipping to change at page 82, line 4 ¶ | skipping to change at page 81, line 51 ¶ | |||
| { 1, 121, 236, 253, 212, 214, 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}, | { 141, 84, 213, 252, 201, 202, 255, 219, 128, 128, 128}, | |||
| { 42, 80, 160, 240, 162, 185, 255, 205, 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}, | { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, | |||
| { 244, 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} | { 238, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128} | |||
| } | } | |||
| } | } | |||
| }; | }; | |||
| ---- End code block ---------------------------------------- | ---- End code block ---------------------------------------- | |||
| 14. DCT and WHT Inversion and Macroblock Reconstruction | 14. DCT and WHT Inversion and Macroblock Reconstruction | |||
| 14.1. Dequantization | 14.1. Dequantization | |||
| After decoding the DCTs/WHTs as described above, each (quantized) | After decoding the DCTs/WHTs as described above, each (quantized) | |||
| coefficient in each subblock is multiplied by one of six | coefficient in each subblock is multiplied by one of six | |||
| dequantization factors, the choice of factor depending on the plane | dequantization factors, the choice of factor depending on the plane | |||
| (Y2, Y, or chroma) and position (DC = coefficient zero, AC = any | (Y2, Y, or chroma) and position (DC = coefficient zero, AC = any | |||
| other coefficient). If the current macroblock has overridden the | other coefficient). If the current macroblock has overridden the | |||
| quantization level (as described in Chapter 10) then the six factors | quantization level (as described in Chapter 10) then the six factors | |||
| are looked up from two dequantization tables with appropriate scaling | are looked up from two dequantization tables with appropriate scaling | |||
| and clamping using the single index supplied by the override. | and clamping using the single index supplied by the override. | |||
| Otherwise, the frame-level dequantization factors (as described in | Otherwise, the frame-level dequantization factors (as described in | |||
| Section 9.6) are used. In either case, the multiplies are computed | Section 9.6) are used. In either case, the multiplies are computed | |||
| and stored using 16-bit signed integers. | and stored using 16-bit signed integers. | |||
| The two dequantization tables, which may also be found in the | The two dequantization tables, which may also be found in the | |||
| reference decoder file quant_common.c, are as follows. | reference decoder file dequant_data.h, are as follows. | |||
| ---- Begin code block -------------------------------------- | ---- Begin code block -------------------------------------- | |||
| static const int dc_qlookup[QINDEX_RANGE] = | static const int dc_qlookup[QINDEX_RANGE] = | |||
| { | { | |||
| 4, 5, 6, 7, 8, 9, 10, 10, 11, 12, 13, 14, 15, | 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, | 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, | 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, | 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, | 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, | |||
| skipping to change at page 84, line 41 ¶ | skipping to change at page 84, line 41 ¶ | |||
| 181, 185, 189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, | 181, 185, 189, 193, 197, 201, 205, 209, 213, 217, 221, 225, 229, | |||
| 234, 239, 245, 249, 254, 259, 264, 269, 274, 279, 284, | 234, 239, 245, 249, 254, 259, 264, 269, 274, 279, 284, | |||
| }; | }; | |||
| ---- End code block ---------------------------------------- | ---- End code block ---------------------------------------- | |||
| Lookup values from the above two tables are directly used the DC and | Lookup values from the above two tables are directly used the DC and | |||
| AC coefficients in Y1 respectively. For Y2 and chroma, values from | AC coefficients in Y1 respectively. For Y2 and chroma, values from | |||
| above tables undergo either a scaling process or clamping processing | above tables undergo either a scaling process or clamping processing | |||
| before the multiplies. Details to these scaling and clamping can be | before the multiplies. Details to these scaling and clamping can be | |||
| found related lookup functions in quant_common.c. | found related lookup functions in dixie.c. | |||
| 14.2. Inverse Transforms | 14.2. Inverse Transforms | |||
| If the Y2 residue block exists (i.e., the macroblock luma mode is not | 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 | 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 | 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 | coefficient of the Y subblock at position (i, j), that is, the Y | |||
| subblock whose index is (i * 4) + j. As discussed in Chapter 13, if | subblock whose index is (i * 4) + j. As discussed in Chapter 13, if | |||
| the luma mode is B_PRED or SPLITMV, the 0th Y coefficients are part | the luma mode is B_PRED or SPLITMV, the 0th Y coefficients are part | |||
| of the residue signal for the subblocks themselves. | of the residue signal for the subblocks themselves. | |||
| skipping to change at page 91, line 33 ¶ | skipping to change at page 91, line 33 ¶ | |||
| entirely at the option of the implementor (and/or user) and has no | entirely at the option of the implementor (and/or user) and has no | |||
| effect on decoding per se. | effect on decoding per se. | |||
| The baseline frame level parameters controlling the loop filter are | The baseline frame level parameters controlling the loop filter are | |||
| defined in the frame header (Chapter 9.4) along with a mechanism for | defined in the frame header (Chapter 9.4) along with a mechanism for | |||
| adjustment based on a macroblock's prediction mode and/or reference | adjustment based on a macroblock's prediction mode and/or reference | |||
| frame. The first is a flag selecting the type of filter (normal or | frame. The first is a flag selecting the type of filter (normal or | |||
| simple), the other two are numbers (loop_filter_level and | simple), the other two are numbers (loop_filter_level and | |||
| sharpness_level) that adjust the strength or sensitivity of the | sharpness_level) that adjust the strength or sensitivity of the | |||
| filter. As described in Chapters 9.3 and 10, loop_filter_level may | filter. As described in Chapters 9.3 and 10, loop_filter_level may | |||
| be also overridden on a per-macroblock basis using segmentation. | also be overridden on a per-macroblock basis using segmentation. | |||
| Loop filtering is one of the more computationally-intensive aspects | Loop filtering is one of the more computationally-intensive aspects | |||
| of VP8 decoding. This is the reason for the existence of the | of VP8 decoding. This is the reason for the existence of the | |||
| optional less-demanding simple filter type. Also, the loop filter is | optional, less-demanding simple filter type. | |||
| completely disabled if the loop_filter_level in the frame header is | ||||
| zero; macroblock-level overrides are ignored in this case. (It is of | Note carefully that loop filtering must be skipped entirely if | |||
| course possible for a compressor to encode a frame in which only a | loop_filter_level at either the frame header level or macroblock | |||
| few macroblocks are loop filtered: The global loop_filter_level must | override level is 0. In no case should the loop filter be run with a | |||
| be non-zero and each macroblock can select one of four levels, most | value of 0; it should instead be skipped. | |||
| of which could be zero.) | ||||
| To facilitate efficient implementation, the VP8 decoding algorithms | To facilitate efficient implementation, the VP8 decoding algorithms | |||
| generally, and the loop filter especially, were designed with SIMD | generally, and the loop filter especially, were designed with SIMD | |||
| ("Single Instruction Multiple Datum" or "integer vector") processors | ("Single Instruction Multiple Datum" or "integer vector") processors | |||
| in mind. The reference decoder implementation of loop filtering | in mind. The reference decoder implementation of loop filtering | |||
| (found in loopfilter.c) is, in effect, a portable SIMD specification | (found in loopfilter.c) is, in effect, a portable SIMD specification | |||
| of the loop filtering algorithms intended to simplify a realization | of the loop filtering algorithms intended to simplify a realization | |||
| on an actual SIMD processor. | on an actual SIMD processor. | |||
| Unfortunately, the approach taken there does not lead to maximal | Unfortunately, the approach taken there does not lead to maximal | |||
| skipping to change at page 116, line 43 ¶ | skipping to change at page 116, line 43 ¶ | |||
| ZERO4x4 uses a zero motion vector and predicts the current subset | ZERO4x4 uses a zero motion vector and predicts the current subset | |||
| using the corresponding subset from the prediction frame. | using the corresponding subset from the prediction frame. | |||
| NEW4x4 is exactly like NEWMV except applied only to the current | NEW4x4 is exactly like NEWMV except applied only to the current | |||
| subset. It is followed by a 2-dimensional motion vector offset | subset. It is followed by a 2-dimensional motion vector offset | |||
| (described in the next chapter) that is added to the best vector | (described in the next chapter) that is added to the best vector | |||
| returned by the earlier call to find_near_mvs to form the motion | returned by the earlier call to find_near_mvs to form the motion | |||
| vector in effect for the subset. | vector in effect for the subset. | |||
| Parsing of both inter-prediction modes and motion vectors (described | Parsing of both inter-prediction modes and motion vectors (described | |||
| next) can be found in the reference decoder file decodemv.c. | next) can be found in the reference decoder file modemv.c. | |||
| 17. Motion Vector Decoding | 17. Motion Vector Decoding | |||
| As discussed above, motion vectors appear in two places in the VP8 | As discussed above, motion vectors appear in two places in the VP8 | |||
| datastream: applied to whole macroblocks in NEWMV mode and applied to | datastream: applied to whole macroblocks in NEWMV mode and applied to | |||
| subsets of macroblocks in NEW4x4 mode. The format of the vectors is | subsets of macroblocks in NEW4x4 mode. The format of the vectors is | |||
| identical in both cases. | identical in both cases. | |||
| Each vector has two pieces: A vertical component (row) followed by a | Each vector has two pieces: A vertical component (row) followed by a | |||
| horizontal component (column). The row and column use separate | horizontal component (column). The row and column use separate | |||
| skipping to change at page 122, line 14 ¶ | skipping to change at page 122, line 14 ¶ | |||
| 18. Interframe Prediction | 18. Interframe Prediction | |||
| Given an inter-prediction specification for the current macroblock, | Given an inter-prediction specification for the current macroblock, | |||
| that is, a reference frame together with a motion vector for each of | that is, a reference frame together with a motion vector for each of | |||
| the sixteen Y subblocks, we describe the calculation of the | the sixteen Y subblocks, we describe the calculation of the | |||
| prediction buffer for the macroblock. Frame reconstruction is then | prediction buffer for the macroblock. Frame reconstruction is then | |||
| completed via the previously-described processes of residue summation | completed via the previously-described processes of residue summation | |||
| (Section 14) and loop filtering (Section 15). | (Section 14) and loop filtering (Section 15). | |||
| The management of inter-predicted subblocks may be found in the | The management of inter-predicted subblocks and sub-pixel | |||
| reference decoder file reconinter.c; sub-pixel interpolation is | interpolation may be found in the reference decoder file predict.c. | |||
| implemented in filter_c.c. | ||||
| 18.1. Bounds on and Adjustment of Motion Vectors | 18.1. Bounds on and Adjustment of Motion Vectors | |||
| Since each motion vector is differentially encoded from a neighboring | Since each motion vector is differentially encoded from a neighboring | |||
| block or macroblock and the only clamp is to ensure that the | block or macroblock and the only clamp is to ensure that the | |||
| referenced motion vector represents a valid location inside a | referenced motion vector represents a valid location inside a | |||
| reference frame buffer, it is technically possible within the VP8 | reference frame buffer, it is technically possible within the VP8 | |||
| format for a block or macroblock to have arbitrarily large motion | format for a block or macroblock to have arbitrarily large motion | |||
| vectors, up to the size of the input image plus the extended border | vectors, up to the size of the input image plus the extended border | |||
| areas. For practical reasons, VP8 imposes a motion vector size range | areas. For practical reasons, VP8 imposes a motion vector size range | |||
| limit of [-4096, 4095] full pixels, regardless of image size (VP8 | limit of -4096 to 4095 full pixels, regardless of image size (VP8 | |||
| defines 14 raw bits for width and height; 16383x16383 is the maximum | defines 14 raw bits for width and height; 16383x16383 is the maximum | |||
| possible image size). Bitstream-compliant encoders and decoders | possible image size). Bitstream-compliant encoders and decoders | |||
| shall enforce this limit. | shall enforce this limit. | |||
| Because the motion vectors applied to the chroma subblocks have 1/8 | Because the motion vectors applied to the chroma subblocks have 1/8 | |||
| pixel resolution, the synthetic pixel calculation, outlined in | pixel resolution, the synthetic pixel calculation, outlined in | |||
| Chapter 5 and detailed below, uses this resolution for the luma | Chapter 5 and detailed below, uses this resolution for the luma | |||
| subblocks as well. In accordance, the stored luma motion vectors are | subblocks as well. In accordance, the stored luma motion vectors are | |||
| all doubled, each component of each luma vector becoming an even | all doubled, each component of each luma vector becoming an even | |||
| integer in the range -2046 to +2046, inclusive. | integer in the range -2046 to +2046, inclusive. | |||
| skipping to change at page 147, line 7 ¶ | skipping to change at page 147, line 7 ¶ | |||
| o token defines the value of the coefficient, the value range of the | o token defines the value of the coefficient, the value range of the | |||
| coefficient or the end of block (Section 13.2) | coefficient or the end of block (Section 13.2) | |||
| o extra_bits determine the value of the coefficient within the value | o extra_bits determine the value of the coefficient within the value | |||
| range defined by token (Section 13.2) | range defined by token (Section 13.2) | |||
| o sign indicates the sign of the coefficient (Section 13.2) | o sign indicates the sign of the coefficient (Section 13.2) | |||
| 20. Attachment One: Reference Decoder Source Code | 20. Attachment One: Reference Decoder Source Code | |||
| Note that the code in this attachment may exhibit bugs, and should be | ||||
| considered a draft until this document reaches RFC status. | ||||
| 20.1. bit_ops.h | 20.1. bit_ops.h | |||
| ---- Begin code block -------------------------------------- | ---- Begin code block -------------------------------------- | |||
| /* | /* | |||
| * Copyright (c) 2010 The VP8 project authors. All Rights Reserved. | * Copyright (c) 2010 The VP8 project authors. All Rights Reserved. | |||
| * | * | |||
| * Use of this source code is governed by a BSD-style license | * 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 | * that can be found in the LICENSE file in the root of the source | |||
| * tree. An additional intellectual property rights grant can be | * tree. An additional intellectual property rights grant can be | |||
| skipping to change at page 170, line 22 ¶ | skipping to change at page 170, line 22 ¶ | |||
| unsigned int sz); | unsigned int sz); | |||
| #define CLAMP_255(x) ((x)<0?0:((x)>255?255:(x))) | #define CLAMP_255(x) ((x)<0?0:((x)>255?255:(x))) | |||
| #endif | #endif | |||
| ---- End code block ---------------------------------------- | ---- End code block ---------------------------------------- | |||
| 20.6. dixie_loopfilter.c | 20.6. dixie_loopfilter.c | |||
| ---- Begin code block -------------------------------------- | ---- Begin code block -------------------------------------- | |||
| /* | /* | |||
| * Copyright (c) 2010 The VP8 project authors. All Rights Reserved. | * Copyright (c) 2010 The VP8 project authors. All Rights Reserved. | |||
| * | * | |||
| * Use of this source code is governed by a BSD-style license | * 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 | * that can be found in the LICENSE file in the root of the source | |||
| * tree. An additional intellectual property rights grant can be | * tree. An additional intellectual property rights grant can be | |||
| * found in the file PATENTS. All contributing project authors may | * found in the file PATENTS. All contributing project authors may | |||
| * be found in the AUTHORS file in the root of the source tree. | * be found in the AUTHORS file in the root of the source tree. | |||
| */ | */ | |||
| #include "dixie.h" | #include "dixie.h" | |||
| #include "dixie_loopfilter.h" | #include "dixie_loopfilter.h" | |||
| #define ABS(x) ((x) >= 0 ? (x) : -(x)) | #define ABS(x) ((x) >= 0 ? (x) : -(x)) | |||
| #define p3 pixels[-4*stride] | #define p3 pixels[-4*stride] | |||
| #define p2 pixels[-3*stride] | #define p2 pixels[-3*stride] | |||
| #define p1 pixels[-2*stride] | #define p1 pixels[-2*stride] | |||
| #define p0 pixels[-1*stride] | #define p0 pixels[-1*stride] | |||
| #define q0 pixels[ 0*stride] | #define q0 pixels[ 0*stride] | |||
| #define q1 pixels[ 1*stride] | #define q1 pixels[ 1*stride] | |||
| #define q2 pixels[ 2*stride] | #define q2 pixels[ 2*stride] | |||
| #define q3 pixels[ 3*stride] | #define q3 pixels[ 3*stride] | |||
| #define static | #define static | |||
| static int | static int | |||
| saturate_int8(int x) | saturate_int8(int x) | |||
| { | { | |||
| if (x < -128) | if (x < -128) | |||
| return -128; | return -128; | |||
| if (x > 127) | if (x > 127) | |||
| return 127; | return 127; | |||
| return x; | return x; | |||
| } | } | |||
| static int | static int | |||
| saturate_uint8(int x) | saturate_uint8(int x) | |||
| { | { | |||
| if (x < 0) | if (x < 0) | |||
| return 0; | return 0; | |||
| if (x > 255) | if (x > 255) | |||
| return 255; | return 255; | |||
| return x; | return x; | |||
| } | } | |||
| static int | static int | |||
| high_edge_variance(unsigned char *pixels, | 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 stride, | |||
| int hev_threshold) | int filter_limit) | |||
| { | { | |||
| return ABS(p1 - p0) > hev_threshold || | return (ABS(p0 - q0) * 2 + (ABS(p1 - q1) >> 1)) <= filter_limit; | |||
| ABS(q1 - q0) > hev_threshold; | } | |||
| } | ||||
| static int | static int | |||
| simple_threshold(unsigned char *pixels, | normal_threshold(unsigned char *pixels, | |||
| int stride, | int stride, | |||
| int filter_limit) | int edge_limit, | |||
| { | int interior_limit) | |||
| return (ABS(p0 - q0) * 2 + (ABS(p1 - q1) >> 1)) <= filter_limit; | { | |||
| } | int E = edge_limit; | |||
| int I = interior_limit; | ||||
| static int | return simple_threshold(pixels, stride, 2 * E + I) | |||
| normal_threshold(unsigned char *pixels, | && ABS(p3 - p2) <= I && ABS(p2 - p1) <= I | |||
| int stride, | && ABS(p1 - p0) <= I && ABS(q3 - q2) <= I | |||
| int edge_limit, | && ABS(q2 - q1) <= I && ABS(q1 - q0) <= I; | |||
| int interior_limit) | } | |||
| { | ||||
| int E = edge_limit; | ||||
| int I = interior_limit; | ||||
| return simple_threshold(pixels, stride, 2 * E + I) | static void | |||
| && ABS(p3 - p2) <= I && ABS(p2 - p1) <= I | filter_common(unsigned char *pixels, | |||
| && ABS(p1 - p0) <= I && ABS(q3 - q2) <= I | int stride, | |||
| && ABS(q2 - q1) <= I && ABS(q1 - q0) <= I; | int use_outer_taps) | |||
| } | { | |||
| int a, f1, f2; | ||||
| static void | a = 3 * (q0 - p0); | |||
| 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); | ||||
| if (use_outer_taps) | a = saturate_int8(a); | |||
| 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; | ||||
| f1 = ((a + 4 > 127) ? 127 : a + 4) >> 3; | p0 = saturate_uint8(p0 + f2); | |||
| f2 = ((a + 3 > 127) ? 127 : a + 3) >> 3; | q0 = saturate_uint8(q0 - f1); | |||
| p0 = saturate_uint8(p0 + f2); | if (!use_outer_taps) | |||
| q0 = saturate_uint8(q0 - f1); | { | |||
| /* 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); | ||||
| } | ||||
| } | ||||
| if (!use_outer_taps) | static void | |||
| { | filter_mb_edge(unsigned char *pixels, | |||
| /* This handles the case of subblock_filter() | int stride) | |||
| * (from the bitstream guide. | { | |||
| */ | int w, a; | |||
| a = (f1 + 1) >> 1; | ||||
| p1 = saturate_uint8(p1 + a); | ||||
| q1 = saturate_uint8(q1 - a); | ||||
| } | ||||
| } | ||||
| static void | w = saturate_int8(saturate_int8(p1 - q1) + 3 * (q0 - p0)); | |||
| 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 = (27 * w + 63) >> 7; | a = (18 * w + 63) >> 7; | |||
| p0 = saturate_uint8(p0 + a); | p1 = saturate_uint8(p1 + a); | |||
| q0 = saturate_uint8(q0 - a); | q1 = saturate_uint8(q1 - a); | |||
| a = (18 * w + 63) >> 7; | a = (9 * w + 63) >> 7; | |||
| p1 = saturate_uint8(p1 + a); | p2 = saturate_uint8(p2 + a); | |||
| q1 = saturate_uint8(q1 - a); | q2 = saturate_uint8(q2 - 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; | ||||
| static void | for (i = 0; i < 8 * size; i++) | |||
| filter_mb_v_edge(unsigned char *src, | { | |||
| int stride, | if (normal_threshold(src, 1, edge_limit, interior_limit)) | |||
| int edge_limit, | { | |||
| int interior_limit, | if (high_edge_variance(src, 1, hev_threshold)) | |||
| int hev_threshold, | filter_common(src, 1, 1); | |||
| int size) | else | |||
| { | filter_mb_edge(src, 1); | |||
| int i; | } | |||
| for (i = 0; i < 8 * size; i++) | src += stride; | |||
| { | } | |||
| 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; | static void | |||
| } | filter_subblock_v_edge(unsigned char *src, | |||
| } | int stride, | |||
| int edge_limit, | ||||
| int interior_limit, | ||||
| int hev_threshold, | ||||
| int size) | ||||
| { | ||||
| int i; | ||||
| static void | for (i = 0; i < 8 * size; i++) | |||
| filter_subblock_v_edge(unsigned char *src, | { | |||
| int stride, | if (normal_threshold(src, 1, edge_limit, interior_limit)) | |||
| int edge_limit, | filter_common(src, 1, | |||
| int interior_limit, | high_edge_variance(src, 1, hev_threshold)); | |||
| int hev_threshold, | ||||
| int size) | ||||
| { | ||||
| int i; | ||||
| for (i = 0; i < 8 * size; i++) | src += stride; | |||
| { | } | |||
| 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; | ||||
| static void | for (i = 0; i < 8 * size; i++) | |||
| filter_mb_h_edge(unsigned char *src, | { | |||
| int stride, | if (normal_threshold(src, stride, edge_limit, | |||
| int edge_limit, | interior_limit)) | |||
| int interior_limit, | { | |||
| int hev_threshold, | if (high_edge_variance(src, stride, hev_threshold)) | |||
| int size) | filter_common(src, stride, 1); | |||
| { | else | |||
| int i; | filter_mb_edge(src, stride); | |||
| } | ||||
| for (i = 0; i < 8 * size; i++) | src += 1; | |||
| { | } | |||
| 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; | static void | |||
| } | filter_subblock_h_edge(unsigned char *src, | |||
| } | int stride, | |||
| int edge_limit, | ||||
| int interior_limit, | ||||
| int hev_threshold, | ||||
| int size) | ||||
| { | ||||
| int i; | ||||
| static void | for (i = 0; i < 8 * size; i++) | |||
| filter_subblock_h_edge(unsigned char *src, | { | |||
| 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 stride, | |||
| int edge_limit, | int filter_limit) | |||
| int interior_limit, | { | |||
| int hev_threshold, | int i; | |||
| int size) | ||||
| { | ||||
| int i; | ||||
| for (i = 0; i < 8 * size; i++) | for (i = 0; i < 16; i++) | |||
| { | { | |||
| if (normal_threshold(src, stride, edge_limit, interior_limit)) | if (simple_threshold(src, 1, filter_limit)) | |||
| filter_common(src, stride, | filter_common(src, 1, 1); | |||
| high_edge_variance(src, stride, | ||||
| hev_threshold)); | ||||
| src += 1; | src += stride; | |||
| } | } | |||
| } | } | |||
| static void | static void | |||
| filter_v_edge_simple(unsigned char *src, | filter_h_edge_simple(unsigned char *src, | |||
| int stride, | int stride, | |||
| int filter_limit) | int filter_limit) | |||
| { | { | |||
| int i; | int i; | |||
| for (i = 0; i < 16; i++) | for (i = 0; i < 16; i++) | |||
| { | { | |||
| if (simple_threshold(src, 1, filter_limit)) | if (simple_threshold(src, stride, filter_limit)) | |||
| filter_common(src, 1, 1); | filter_common(src, stride, 1); | |||
| src += stride; | src += 1; | |||
| } | ||||
| } | ||||
| static void | } | |||
| filter_h_edge_simple(unsigned char *src, | } | |||
| int stride, | ||||
| int filter_limit) | ||||
| { | ||||
| int i; | ||||
| for (i = 0; i < 16; i++) | static void | |||
| { | calculate_filter_parameters(struct vp8_decoder_ctx *ctx, | |||
| if (simple_threshold(src, stride, filter_limit)) | struct mb_info *mbi, | |||
| filter_common(src, stride, 1); | int *edge_limit_, | |||
| int *interior_limit_, | ||||
| int *hev_threshold_) | ||||
| { | ||||
| int filter_level, interior_limit, hev_threshold; | ||||
| src += 1; | /* Reference code/spec seems to conflate filter_level and | |||
| } | * edge_limit | |||
| } | */ | |||
| 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 | filter_level = ctx->loopfilter_hdr.level; | |||
| * 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 (ctx->segment_hdr.enabled) | if (filter_level > 63) | |||
| { | filter_level = 63; | |||
| if (!ctx->segment_hdr.abs) | else if (filter_level < 0) | |||
| filter_level += | filter_level = 0; | |||
| ctx->segment_hdr.lf_level[mbi->base.segment_id]; | ||||
| else | ||||
| filter_level = | ||||
| ctx->segment_hdr.lf_level[mbi->base.segment_id]; | ||||
| } | ||||
| if (ctx->loopfilter_hdr.delta_enabled) | if (ctx->loopfilter_hdr.delta_enabled) | |||
| { | { | |||
| filter_level += | filter_level += | |||
| ctx->loopfilter_hdr.ref_delta[mbi->base.ref_frame]; | ctx->loopfilter_hdr.ref_delta[mbi->base.ref_frame]; | |||
| if (mbi->base.ref_frame == CURRENT_FRAME) | if (mbi->base.ref_frame == CURRENT_FRAME) | |||
| { | { | |||
| if (mbi->base.y_mode == B_PRED) | if (mbi->base.y_mode == B_PRED) | |||
| filter_level += ctx->loopfilter_hdr.mode_delta[0]; | filter_level += ctx->loopfilter_hdr.mode_delta[0]; | |||
| } | } | |||
| else if (mbi->base.y_mode == ZEROMV) | else if (mbi->base.y_mode == ZEROMV) | |||
| filter_level += ctx->loopfilter_hdr.mode_delta[1]; | filter_level += ctx->loopfilter_hdr.mode_delta[1]; | |||
| else if (mbi->base.y_mode == SPLITMV) | else if (mbi->base.y_mode == SPLITMV) | |||
| filter_level += ctx->loopfilter_hdr.mode_delta[3]; | filter_level += ctx->loopfilter_hdr.mode_delta[3]; | |||
| else | ||||
| filter_level += ctx->loopfilter_hdr.mode_delta[2]; | ||||
| } | ||||
| if (filter_level > 63) | else | |||
| filter_level = 63; | filter_level += ctx->loopfilter_hdr.mode_delta[2]; | |||
| else if (filter_level < 0) | } | |||
| filter_level = 0; | ||||
| interior_limit = filter_level; | if (filter_level > 63) | |||
| filter_level = 63; | ||||
| else if (filter_level < 0) | ||||
| filter_level = 0; | ||||
| if (ctx->loopfilter_hdr.sharpness) | interior_limit = filter_level; | |||
| { | ||||
| interior_limit >>= ctx->loopfilter_hdr.sharpness > 4 ? 2 : 1; | ||||
| if (interior_limit > 9 - ctx->loopfilter_hdr.sharpness) | if (ctx->loopfilter_hdr.sharpness) | |||
| interior_limit = 9 - ctx->loopfilter_hdr.sharpness; | { | |||
| } | interior_limit >>= ctx->loopfilter_hdr.sharpness > 4 ? 2 : 1; | |||
| if (interior_limit < 1) | if (interior_limit > 9 - ctx->loopfilter_hdr.sharpness) | |||
| interior_limit = 1; | interior_limit = 9 - ctx->loopfilter_hdr.sharpness; | |||
| } | ||||
| hev_threshold = (filter_level >= 15); | if (interior_limit < 1) | |||
| interior_limit = 1; | ||||
| if (filter_level >= 40) | hev_threshold = (filter_level >= 15); | |||
| hev_threshold++; | ||||
| if (filter_level >= 20 && !ctx->frame_hdr.is_keyframe) | if (filter_level >= 40) | |||
| hev_threshold++; | hev_threshold++; | |||
| *edge_limit_ = filter_level; | if (filter_level >= 20 && !ctx->frame_hdr.is_keyframe) | |||
| *interior_limit_ = interior_limit; | hev_threshold++; | |||
| *hev_threshold_ = hev_threshold; | ||||
| } | ||||
| static void | *edge_limit_ = filter_level; | |||
| filter_row_normal(struct vp8_decoder_ctx *ctx, | *interior_limit_ = interior_limit; | |||
| unsigned int row, | *hev_threshold_ = hev_threshold; | |||
| 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 */ | static void | |||
| stride = ctx->ref_frames[CURRENT_FRAME]->img.stride[PLANE_Y]; | filter_row_normal(struct vp8_decoder_ctx *ctx, | |||
| uv_stride = ctx->ref_frames[CURRENT_FRAME]->img.stride[PLANE_U]; | unsigned int row, | |||
| y = ctx->ref_frames[CURRENT_FRAME]->img.planes[PLANE_Y]; | unsigned int start_col, | |||
| u = ctx->ref_frames[CURRENT_FRAME]->img.planes[PLANE_U]; | unsigned int num_cols) | |||
| v = ctx->ref_frames[CURRENT_FRAME]->img.planes[PLANE_V]; | { | |||
| y += (stride * row + start_col) * 16; | unsigned char *y, *u, *v; | |||
| u += (uv_stride * row + start_col) * 8; | int stride, uv_stride; | |||
| v += (uv_stride * row + start_col) * 8; | struct mb_info *mbi; | |||
| mbi = ctx->mb_info_rows[row] + start_col; | unsigned int 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 | /* Adjust pointers based on row, start_col */ | |||
| * enabled. | stride = ctx->ref_frames[CURRENT_FRAME]->img.stride[PLANE_Y]; | |||
| */ | uv_stride = ctx->ref_frames[CURRENT_FRAME]->img.stride[PLANE_U]; | |||
| calculate_filter_parameters(ctx, mbi, &edge_limit, | y = ctx->ref_frames[CURRENT_FRAME]->img.planes[PLANE_Y]; | |||
| &interior_limit, &hev_threshold); | 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; | ||||
| if (edge_limit) | for (col = start_col; col < start_col + num_cols; col++) | |||
| { | { | |||
| if (col) | int edge_limit, interior_limit, hev_threshold; | |||
| { | ||||
| 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); | ||||
| } | ||||
| /* NOTE: This conditional is actually dependent on the | /* TODO: only need to recalculate every MB if segmentation is | |||
| * number of coefficients decoded, not the skip flag as | * enabled. | |||
| * coded in the bitstream. The tokens task is expected to | */ | |||
| * set 31 if there is *any* non-zero data. | calculate_filter_parameters(ctx, mbi, &edge_limit, | |||
| */ | &interior_limit, &hev_threshold); | |||
| 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); | ||||
| } | ||||
| if (mbi->base.eob_mask | if (edge_limit) | |||
| || mbi->base.y_mode == SPLITMV | { | |||
| || mbi->base.y_mode == B_PRED) | if (col) | |||
| { | { | |||
| filter_subblock_h_edge(y + 4 * stride, stride, | filter_mb_v_edge(y, stride, edge_limit + 2, | |||
| edge_limit, interior_limit, | interior_limit, hev_threshold, 2); | |||
| hev_threshold, 2); | filter_mb_v_edge(u, uv_stride, edge_limit + 2, | |||
| filter_subblock_h_edge(y + 8 * stride, stride, | interior_limit, hev_threshold, 1); | |||
| edge_limit, interior_limit, | filter_mb_v_edge(v, uv_stride, edge_limit + 2, | |||
| hev_threshold, 2); | interior_limit, hev_threshold, 1); | |||
| 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; | /* NOTE: This conditional is actually dependent on the | |||
| u += 8; | * number of coefficients decoded, not the skip flag as | |||
| v += 8; | * coded in the bitstream. The tokens task is expected to | |||
| mbi++; | * 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); | ||||
| } | ||||
| static void | if (row) | |||
| filter_row_simple(struct vp8_decoder_ctx *ctx, | { | |||
| unsigned int row, | filter_mb_h_edge(y, stride, edge_limit + 2, | |||
| unsigned int start_col, | interior_limit, hev_threshold, 2); | |||
| unsigned int num_cols) | filter_mb_h_edge(u, uv_stride, edge_limit + 2, | |||
| { | interior_limit, hev_threshold, 1); | |||
| unsigned char *y; | filter_mb_h_edge(v, uv_stride, edge_limit + 2, | |||
| int stride; | interior_limit, hev_threshold, 1); | |||
| struct mb_info *mbi; | } | |||
| unsigned int col; | ||||
| /* Adjust pointers based on row, start_col */ | if (mbi->base.eob_mask | |||
| stride = ctx->ref_frames[CURRENT_FRAME]->img.stride[PLANE_Y]; | || mbi->base.y_mode == SPLITMV | |||
| y = ctx->ref_frames[CURRENT_FRAME]->img.planes[PLANE_Y]; | || mbi->base.y_mode == B_PRED) | |||
| y += (stride * row + start_col) * 16; | { | |||
| mbi = ctx->mb_info_rows[row] + start_col; | 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); | ||||
| } | ||||
| } | ||||
| for (col = start_col; col < start_col + num_cols; col++) | y += 16; | |||
| { | u += 8; | |||
| int edge_limit, interior_limit, hev_threshold; | 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; | ||||
| /* TODO: only need to recalculate every MB if segmentation is | /* Adjust pointers based on row, start_col */ | |||
| * enabled. | stride = ctx->ref_frames[CURRENT_FRAME]->img.stride[PLANE_Y]; | |||
| */ | y = ctx->ref_frames[CURRENT_FRAME]->img.planes[PLANE_Y]; | |||
| calculate_filter_parameters(ctx, mbi, &edge_limit, | y += (stride * row + start_col) * 16; | |||
| &interior_limit, &hev_threshold); | mbi = ctx->mb_info_rows[row] + start_col; | |||
| if (edge_limit) | for (col = start_col; col < start_col + num_cols; col++) | |||
| { | { | |||
| int edge_limit, interior_limit, hev_threshold; | ||||
| /* NOTE: This conditional is actually dependent on the | /* TODO: only need to recalculate every MB if segmentation is | |||
| * number of coefficients decoded, not the skip flag as | * enabled. | |||
| * coded in the bitstream. The tokens task is expected to | */ | |||
| * set 31 if there is *any* non-zero data. | calculate_filter_parameters(ctx, mbi, &edge_limit, | |||
| */ | &interior_limit, &hev_threshold); | |||
| 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) | if (edge_limit) | |||
| filter_v_edge_simple(y, stride, mb_limit); | { | |||
| if (filter_subblocks) | /* NOTE: This conditional is actually dependent on the | |||
| { | * number of coefficients decoded, not the skip flag as | |||
| filter_v_edge_simple(y + 4, stride, b_limit); | * coded in the bitstream. The tokens task is expected to | |||
| filter_v_edge_simple(y + 8, stride, b_limit); | * set 31 if there is *any* non-zero data. | |||
| filter_v_edge_simple(y + 12, stride, b_limit); | */ | |||
| } | 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 (row) | if (col) | |||
| filter_h_edge_simple(y, stride, mb_limit); | filter_v_edge_simple(y, stride, mb_limit); | |||
| if (filter_subblocks) | if (filter_subblocks) | |||
| { | { | |||
| filter_h_edge_simple(y + 4 * stride, stride, b_limit); | filter_v_edge_simple(y + 4, stride, b_limit); | |||
| filter_h_edge_simple(y + 8 * stride, stride, b_limit); | filter_v_edge_simple(y + 8, stride, b_limit); | |||
| filter_h_edge_simple(y + 12 * stride, stride, b_limit); | filter_v_edge_simple(y + 12, stride, b_limit); | |||
| } | } | |||
| } | ||||
| y += 16; | if (row) | |||
| mbi++; | filter_h_edge_simple(y, stride, mb_limit); | |||
| } | ||||
| } | ||||
| void | if (filter_subblocks) | |||
| vp8_dixie_loopfilter_process_row(struct vp8_decoder_ctx *ctx, | { | |||
| unsigned int row, | filter_h_edge_simple(y + 4 * stride, stride, | |||
| unsigned int start_col, | b_limit); | |||
| unsigned int num_cols) | filter_h_edge_simple(y + 8 * stride, stride, | |||
| { | b_limit); | |||
| if (ctx->loopfilter_hdr.use_simple) | filter_h_edge_simple(y + 12 * stride, stride, | |||
| filter_row_simple(ctx, row, start_col, num_cols); | b_limit); | |||
| else | } | |||
| filter_row_normal(ctx, row, start_col, num_cols); | } | |||
| } | ||||
| ---- End code block ---------------------------------------- | 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 | 20.7. dixie_loopfilter.h | |||
| ---- Begin code block -------------------------------------- | ---- Begin code block -------------------------------------- | |||
| /* | /* | |||
| * Copyright (c) 2010 The VP8 project authors. All Rights Reserved. | * Copyright (c) 2010 The VP8 project authors. All Rights Reserved. | |||
| * | * | |||
| * Use of this source code is governed by a BSD-style license | * 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 | * that can be found in the LICENSE file in the root of the source | |||
| skipping to change at page 188, line 8 ¶ | skipping to change at page 188, line 8 ¶ | |||
| */ | */ | |||
| #if defined(__GNUC__) && __GNUC__ | #if defined(__GNUC__) && __GNUC__ | |||
| #define UNINITIALIZED_IS_SAFE(x) x=x | #define UNINITIALIZED_IS_SAFE(x) x=x | |||
| #else | #else | |||
| #define UNINITIALIZED_IS_SAFE(x) x | #define UNINITIALIZED_IS_SAFE(x) x | |||
| #endif | #endif | |||
| ---- End code block ---------------------------------------- | ---- End code block ---------------------------------------- | |||
| 20.11. modemv.c | 20.11. modemv.c | |||
| ---- Begin code block -------------------------------------- | ||||
| /* | /* | |||
| * Copyright (c) 2010 The VP8 project authors. All Rights Reserved. | * Copyright (c) 2010 The VP8 project authors. All Rights Reserved. | |||
| * | * | |||
| * Use of this source code is governed by a BSD-style license | * 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 | * that can be found in the LICENSE file in the root of the source | |||
| * tree. An additional intellectual property rights grant can be | * tree. An additional intellectual property rights grant can be | |||
| * found in the file PATENTS. All contributing project authors may | * found in the file PATENTS. All contributing project authors may | |||
| * be found in the AUTHORS file in the root of the source tree. | * be found in the AUTHORS file in the root of the source tree. | |||
| */ | */ | |||
| #include "dixie.h" | #include "dixie.h" | |||
| #include "modemv_data.h" | #include "modemv_data.h" | |||
| #include <stdlib.h> | #include <stdlib.h> | |||
| #include <assert.h> | #include <assert.h> | |||
| struct mv_clamp_rect | struct mv_clamp_rect | |||
| { | { | |||
| int to_left, to_right, to_top, to_bottom; | int to_left, to_right, to_top, to_bottom; | |||
| }; | }; | |||
| static union mv | static union mv | |||
| clamp_mv(union mv raw, const struct mv_clamp_rect *bounds) | clamp_mv(union mv raw, const struct mv_clamp_rect *bounds) | |||
| { | { | |||
| union mv newmv; | union mv newmv; | |||
| newmv.d.x = (raw.d.x < bounds->to_left) | newmv.d.x = (raw.d.x < bounds->to_left) | |||
| ? bounds->to_left : raw.d.x; | ? bounds->to_left : raw.d.x; | |||
| newmv.d.x = (raw.d.x > bounds->to_right) | newmv.d.x = (raw.d.x > bounds->to_right) | |||
| ? bounds->to_right : newmv.d.x; | ? bounds->to_right : newmv.d.x; | |||
| newmv.d.y = (raw.d.y < bounds->to_top) | newmv.d.y = (raw.d.y < bounds->to_top) | |||
| ? bounds->to_top : raw.d.y; | ? bounds->to_top : raw.d.y; | |||
| newmv.d.y = (raw.d.y > bounds->to_bottom) | newmv.d.y = (raw.d.y > bounds->to_bottom) | |||
| ? bounds->to_bottom : newmv.d.y; | ? bounds->to_bottom : newmv.d.y; | |||
| return newmv; | return newmv; | |||
| } | } | |||
| static int | static int | |||
| read_segment_id(struct bool_decoder *bool, | read_segment_id(struct bool_decoder *bool, | |||
| struct vp8_segment_hdr *seg) | struct vp8_segment_hdr *seg) | |||
| { | { | |||
| return bool_get(bool, seg->tree_probs[0]) | return bool_get(bool, seg->tree_probs[0]) | |||
| ? 2 + bool_get(bool, seg->tree_probs[2]) | ? 2 + bool_get(bool, seg->tree_probs[2]) | |||
| : bool_get(bool, seg->tree_probs[1]); | : bool_get(bool, seg->tree_probs[1]); | |||
| } | } | |||
| static enum prediction_mode | static enum prediction_mode | |||
| above_block_mode(const struct mb_info *this, | above_block_mode(const struct mb_info *this, | |||
| const struct mb_info *above, | const struct mb_info *above, | |||
| unsigned int b) | unsigned int b) | |||
| { | { | |||
| if (b < 4) | if (b < 4) | |||
| { | { | |||
| switch (above->base.y_mode) | switch (above->base.y_mode) | |||
| { | { | |||
| case DC_PRED: | case DC_PRED: | |||
| return B_DC_PRED; | return B_DC_PRED; | |||
| case V_PRED: | case V_PRED: | |||
| return B_VE_PRED; | return B_VE_PRED; | |||
| case H_PRED: | case H_PRED: | |||
| return B_HE_PRED; | return B_HE_PRED; | |||
| case TM_PRED: | case TM_PRED: | |||
| return B_TM_PRED; | return B_TM_PRED; | |||
| case B_PRED: | case B_PRED: | |||
| return above->split.modes[b+12]; | return above->split.modes[b+12]; | |||
| default: | default: | |||
| assert(0); | assert(0); | |||
| } | } | |||
| } | } | |||
| return this->split.modes[b-4]; | return this->split.modes[b-4]; | |||
| } | } | |||
| static enum prediction_mode | static enum prediction_mode | |||
| left_block_mode(const struct mb_info *this, | left_block_mode(const struct mb_info *this, | |||
| const struct mb_info *left, | const struct mb_info *left, | |||
| unsigned int b) | unsigned int b) | |||
| { | { | |||
| if (!(b & 3)) | if (!(b & 3)) | |||
| { | { | |||
| switch (left->base.y_mode) | switch (left->base.y_mode) | |||
| { | { | |||
| case DC_PRED: | case DC_PRED: | |||
| return B_DC_PRED; | return B_DC_PRED; | |||
| case V_PRED: | case V_PRED: | |||
| return B_VE_PRED; | return B_VE_PRED; | |||
| case H_PRED: | case H_PRED: | |||
| return B_HE_PRED; | return B_HE_PRED; | |||
| case TM_PRED: | case TM_PRED: | |||
| return B_TM_PRED; | return B_TM_PRED; | |||
| case B_PRED: | case B_PRED: | |||
| return left->split.modes[b+3]; | return left->split.modes[b+3]; | |||
| default: | default: | |||
| assert(0); | assert(0); | |||
| } | } | |||
| } | } | |||
| return this->split.modes[b-1]; | return this->split.modes[b-1]; | |||
| } | } | |||
| static void | static void | |||
| decode_kf_mb_mode(struct mb_info *this, | decode_kf_mb_mode(struct mb_info *this, | |||
| struct mb_info *left, | struct mb_info *left, | |||
| struct mb_info *above, | struct mb_info *above, | |||
| struct bool_decoder *bool) | struct bool_decoder *bool) | |||
| { | { | |||
| int y_mode, uv_mode; | int y_mode, uv_mode; | |||
| y_mode = bool_read_tree(bool, kf_y_mode_tree, kf_y_mode_probs); | y_mode = bool_read_tree(bool, kf_y_mode_tree, kf_y_mode_probs); | |||
| if (y_mode == B_PRED) | if (y_mode == B_PRED) | |||
| { | { | |||
| unsigned int i; | unsigned int i; | |||
| for (i = 0; i < 16; i++) | for (i = 0; i < 16; i++) | |||
| { | { | |||
| enum prediction_mode a = above_block_mode(this, above, i); | enum prediction_mode a = above_block_mode(this, above, | |||
| enum prediction_mode l = left_block_mode(this, left, i); | i); | |||
| enum prediction_mode b; | enum prediction_mode l = left_block_mode(this, left, i); | |||
| enum prediction_mode b; | ||||
| b = bool_read_tree(bool, b_mode_tree, | b = bool_read_tree(bool, b_mode_tree, | |||
| kf_b_mode_probs[a][l]); | kf_b_mode_probs[a][l]); | |||
| this->split.modes[i] = b; | this->split.modes[i] = b; | |||
| } | } | |||
| } | } | |||
| uv_mode = bool_read_tree(bool, uv_mode_tree, kf_uv_mode_probs); | uv_mode = bool_read_tree(bool, uv_mode_tree, kf_uv_mode_probs); | |||
| this->base.y_mode = y_mode; | this->base.y_mode = y_mode; | |||
| this->base.uv_mode = uv_mode; | this->base.uv_mode = uv_mode; | |||
| this->base.mv.raw = 0; | this->base.mv.raw = 0; | |||
| this->base.ref_frame = 0; | this->base.ref_frame = 0; | |||
| } | } | |||
| static void | static void | |||
| decode_intra_mb_mode(struct mb_info *this, | decode_intra_mb_mode(struct mb_info *this, | |||
| struct vp8_entropy_hdr *hdr, | struct vp8_entropy_hdr *hdr, | |||
| struct bool_decoder *bool) | struct bool_decoder *bool) | |||
| { | { | |||
| /* Like decode_kf_mb_mode, but with probabilities transmitted in the | /* Like decode_kf_mb_mode, but with probabilities transmitted in | |||
| * bitstream and no context on the above/left block mode. | * the bitstream and no context on the above/left block mode. | |||
| */ | */ | |||
| int y_mode, uv_mode; | int y_mode, uv_mode; | |||
| y_mode = bool_read_tree(bool, y_mode_tree, hdr->y_mode_probs); | y_mode = bool_read_tree(bool, y_mode_tree, hdr->y_mode_probs); | |||
| if (y_mode == B_PRED) | if (y_mode == B_PRED) | |||
| { | { | |||
| unsigned int i; | unsigned int i; | |||
| for (i = 0; i < 16; i++) | for (i = 0; i < 16; i++) | |||
| { | { | |||
| enum prediction_mode b; | enum prediction_mode b; | |||
| b = bool_read_tree(bool, b_mode_tree, default_b_mode_probs); | b = bool_read_tree(bool, b_mode_tree, | |||
| this->split.modes[i] = b; | default_b_mode_probs); | |||
| } | this->split.modes[i] = b; | |||
| } | } | |||
| } | ||||
| uv_mode = bool_read_tree(bool, uv_mode_tree, hdr->uv_mode_probs); | uv_mode = bool_read_tree(bool, uv_mode_tree, hdr->uv_mode_probs); | |||
| this->base.y_mode = y_mode; | this->base.y_mode = y_mode; | |||
| this->base.uv_mode = uv_mode; | this->base.uv_mode = uv_mode; | |||
| this->base.mv.raw = 0; | this->base.mv.raw = 0; | |||
| this->base.ref_frame = CURRENT_FRAME; | this->base.ref_frame = CURRENT_FRAME; | |||
| } | } | |||
| static int | static int | |||
| read_mv_component(struct bool_decoder *bool, | read_mv_component(struct bool_decoder *bool, | |||
| const unsigned char mvc[MV_PROB_CNT]) | const unsigned char mvc[MV_PROB_CNT]) | |||
| { | { | |||
| enum {IS_SHORT, SIGN, SHORT, BITS = SHORT + 8 - 1, LONG_WIDTH = 10}; | enum {IS_SHORT, SIGN, SHORT, BITS = SHORT + 8 - 1, | |||
| int x = 0; | LONG_WIDTH = 10}; | |||
| int x = 0; | ||||
| if (bool_get(bool, mvc[IS_SHORT])) /* Large */ | if (bool_get(bool, mvc[IS_SHORT])) /* Large */ | |||
| { | { | |||
| int i = 0; | int i = 0; | |||
| for (i = 0; i < 3; i++) | for (i = 0; i < 3; i++) | |||
| x += bool_get(bool, mvc[BITS + i]) << i; | x += bool_get(bool, mvc[BITS + i]) << i; | |||
| /* Skip bit 3, which is sometimes implicit */ | /* Skip bit 3, which is sometimes implicit */ | |||
| for (i = LONG_WIDTH - 1; i > 3; i--) | for (i = LONG_WIDTH - 1; i > 3; i--) | |||
| x += bool_get(bool, mvc[BITS + i]) << i; | x += bool_get(bool, mvc[BITS + i]) << i; | |||
| if (!(x & 0xFFF0) || bool_get(bool, mvc[BITS + 3])) | if (!(x & 0xFFF0) || bool_get(bool, mvc[BITS + 3])) | |||
| x += 8; | x += 8; | |||
| } | } | |||
| else /* small */ | else /* small */ | |||
| x = bool_read_tree(bool, small_mv_tree, mvc + SHORT); | x = bool_read_tree(bool, small_mv_tree, mvc + SHORT); | |||
| if (x && bool_get(bool, mvc[SIGN])) | if (x && bool_get(bool, mvc[SIGN])) | |||
| x = -x; | x = -x; | |||
| return x << 1; | return x << 1; | |||
| } | } | |||
| static mv_t | static mv_t | |||
| above_block_mv(const struct mb_info *this, | above_block_mv(const struct mb_info *this, | |||
| const struct mb_info *above, | const struct mb_info *above, | |||
| unsigned int b) | unsigned int b) | |||
| { | { | |||
| if (b < 4) | if (b < 4) | |||
| { | { | |||
| if (above->base.y_mode == SPLITMV) | if (above->base.y_mode == SPLITMV) | |||
| return above->split.mvs[b+12]; | return above->split.mvs[b+12]; | |||
| return above->base.mv; | return above->base.mv; | |||
| } | } | |||
| return this->split.mvs[b-4]; | return this->split.mvs[b-4]; | |||
| } | } | |||
| static mv_t | static mv_t | |||
| left_block_mv(const struct mb_info *this, | left_block_mv(const struct mb_info *this, | |||
| const struct mb_info *left, | const struct mb_info *left, | |||
| unsigned int b) | unsigned int b) | |||
| { | { | |||
| if (!(b & 3)) | if (!(b & 3)) | |||
| { | { | |||
| if (left->base.y_mode == SPLITMV) | if (left->base.y_mode == SPLITMV) | |||
| return left->split.mvs[b+3]; | return left->split.mvs[b+3]; | |||
| return left->base.mv; | return left->base.mv; | |||
| } | } | |||
| return this->split.mvs[b-1]; | ||||
| } | ||||
| return this->split.mvs[b-1]; | 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; | ||||
| static enum prediction_mode | if (lea && lez) | |||
| submv_ref(struct bool_decoder *bool, union mv l, union mv a) | ctx = SUBMVREF_LEFT_ABOVE_ZED; | |||
| { | else if (lea) | |||
| enum subblock_mv_ref | ctx = SUBMVREF_LEFT_ABOVE_SAME; | |||
| { | else if (aez) | |||
| SUBMVREF_NORMAL, | ctx = SUBMVREF_ABOVE_ZED; | |||
| SUBMVREF_LEFT_ZED, | else if (lez) | |||
| SUBMVREF_ABOVE_ZED, | ctx = SUBMVREF_LEFT_ZED; | |||
| SUBMVREF_LEFT_ABOVE_SAME, | ||||
| SUBMVREF_LEFT_ABOVE_ZED | ||||
| }; | ||||
| int lez = !(l.raw); | return bool_read_tree(bool, submv_ref_tree, | |||
| int aez = !(a.raw); | submv_ref_probs2[ctx]); | |||
| int lea = l.raw == a.raw; | } | |||
| enum subblock_mv_ref ctx = SUBMVREF_NORMAL; | ||||
| if (lea && lez) | static void | |||
| ctx = SUBMVREF_LEFT_ABOVE_ZED; | read_mv(struct bool_decoder *bool, | |||
| else if (lea) | union mv *mv, | |||
| ctx = SUBMVREF_LEFT_ABOVE_SAME; | mv_component_probs_t mvc[2]) | |||
| else if (aez) | { | |||
| ctx = SUBMVREF_ABOVE_ZED; | mv->d.y = read_mv_component(bool, mvc[0]); | |||
| else if (lez) | mv->d.x = read_mv_component(bool, mvc[1]); | |||
| ctx = SUBMVREF_LEFT_ZED; | } | |||
| return bool_read_tree(bool, submv_ref_tree, submv_ref_probs2[ctx]); | 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; | ||||
| } | ||||
| } | ||||
| static void | enum near_mv_v | |||
| read_mv(struct bool_decoder *bool, | { | |||
| union mv *mv, | CNT_BEST = 0, | |||
| mv_component_probs_t mvc[2]) | CNT_ZEROZERO = 0, | |||
| { | CNT_NEAREST, | |||
| mv->d.y = read_mv_component(bool, mvc[0]); | CNT_NEAR, | |||
| mv->d.x = read_mv_component(bool, mvc[1]); | CNT_SPLITMV | |||
| } | }; | |||
| static void | static void | |||
| mv_bias(const struct mb_info *mb, | find_near_mvs(const struct mb_info *this, | |||
| const unsigned int sign_bias[3], | const struct mb_info *left, | |||
| enum reference_frame ref_frame, | const struct mb_info *above, | |||
| union mv *mv) | 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 */ | |||
| if (sign_bias[mb->base.ref_frame] ^ sign_bias[ref_frame]) | mv[0].raw = mv[1].raw = mv[2].raw = 0; | |||
| { | cnt[0] = cnt[1] = cnt[2] = cnt[3] = 0; | |||
| mv->d.x *= -1; | ||||
| mv->d.y *= -1; | ||||
| } | ||||
| } | ||||
| enum near_mv_v | /* Process above */ | |||
| { | if (above->base.ref_frame != CURRENT_FRAME) | |||
| CNT_BEST = 0, | { | |||
| CNT_ZEROZERO = 0, | if (above->base.mv.raw) | |||
| CNT_NEAREST, | { | |||
| CNT_NEAR, | (++mv)->raw = above->base.mv.raw; | |||
| CNT_SPLITMV | mv_bias(above, sign_bias, this->base.ref_frame, mv); | |||
| }; | ++cntx; | |||
| } | ||||
| static void | *cntx += 2; | |||
| 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; | ||||
| /* Process above */ | /* Process left */ | |||
| if (above->base.ref_frame != CURRENT_FRAME) | if (left->base.ref_frame != CURRENT_FRAME) | |||
| { | { | |||
| if (above->base.mv.raw) | if (left->base.mv.raw) | |||
| { | { | |||
| (++mv)->raw = above->base.mv.raw; | union mv this_mv; | |||
| mv_bias(above, sign_bias, this->base.ref_frame, mv); | ||||
| ++cntx; | ||||
| } | ||||
| *cntx += 2; | this_mv.raw = left->base.mv.raw; | |||
| } | mv_bias(left, sign_bias, this->base.ref_frame, &this_mv); | |||
| /* 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; | if (this_mv.raw != mv->raw) | |||
| mv_bias(left, sign_bias, this->base.ref_frame, &this_mv); | { | |||
| (++mv)->raw = this_mv.raw; | ||||
| ++cntx; | ||||
| } | ||||
| if (this_mv.raw != mv->raw) | *cntx += 2; | |||
| { | } | |||
| (++mv)->raw = this_mv.raw; | else | |||
| ++cntx; | cnt[CNT_ZEROZERO] += 2; | |||
| } | } | |||
| *cntx += 2; | /* Process above left */ | |||
| } | if (aboveleft->base.ref_frame != CURRENT_FRAME) | |||
| else | { | |||
| cnt[CNT_ZEROZERO] += 2; | if (aboveleft->base.mv.raw) | |||
| } | { | |||
| union mv this_mv; | ||||
| /* Process above left */ | this_mv.raw = aboveleft->base.mv.raw; | |||
| if (aboveleft->base.ref_frame != CURRENT_FRAME) | mv_bias(aboveleft, sign_bias, this->base.ref_frame, | |||
| { | &this_mv); | |||
| if (aboveleft->base.mv.raw) | ||||
| { | ||||
| union mv this_mv; | ||||
| this_mv.raw = aboveleft->base.mv.raw; | if (this_mv.raw != mv->raw) | |||
| mv_bias(aboveleft, sign_bias, this->base.ref_frame, | { | |||
| &this_mv); | (++mv)->raw = this_mv.raw; | |||
| ++cntx; | ||||
| } | ||||
| if (this_mv.raw != mv->raw) | *cntx += 1; | |||
| { | } | |||
| (++mv)->raw = this_mv.raw; | else | |||
| ++cntx; | cnt[CNT_ZEROZERO] += 1; | |||
| } | } | |||
| *cntx += 1; | /* If we have three distinct MV's ... */ | |||
| } | if (cnt[CNT_SPLITMV]) | |||
| else | { | |||
| cnt[CNT_ZEROZERO] += 1; | /* See if above-left MV can be merged with NEAREST */ | |||
| } | if (mv->raw == near_mvs[CNT_NEAREST].raw) | |||
| cnt[CNT_NEAREST] += 1; | ||||
| } | ||||
| /* If we have three distinct MV's ... */ | cnt[CNT_SPLITMV] = ((above->base.y_mode == SPLITMV) | |||
| if (cnt[CNT_SPLITMV]) | + (left->base.y_mode == SPLITMV)) * 2 | |||
| { | + (aboveleft->base.y_mode == 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) | /* Swap near and nearest if necessary */ | |||
| + (left->base.y_mode == SPLITMV)) * 2 | if (cnt[CNT_NEAR] > cnt[CNT_NEAREST]) | |||
| + (aboveleft->base.y_mode == SPLITMV); | { | |||
| 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; | ||||
| } | ||||
| /* Swap near and nearest if necessary */ | /* Use near_mvs[CNT_BEST] to store the "best" MV. Note that this | |||
| if (cnt[CNT_NEAR] > cnt[CNT_NEAREST]) | * storage shares the same address as near_mvs[CNT_ZEROZERO]. | |||
| { | */ | |||
| int tmp; | if (cnt[CNT_NEAREST] >= cnt[CNT_BEST]) | |||
| tmp = cnt[CNT_NEAREST]; | near_mvs[CNT_BEST] = near_mvs[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 | static void | |||
| * storage shares the same address as near_mvs[CNT_ZEROZERO]. | decode_split_mv(struct mb_info *this, | |||
| */ | const struct mb_info *left, | |||
| if (cnt[CNT_NEAREST] >= cnt[CNT_BEST]) | const struct mb_info *above, | |||
| near_mvs[CNT_BEST] = near_mvs[CNT_NEAREST]; | struct vp8_entropy_hdr *hdr, | |||
| } | union mv *best_mv, | |||
| struct bool_decoder *bool) | ||||
| { | ||||
| const int *partition; | ||||
| int j, k, mask, partition_id; | ||||
| static void | partition_id = bool_read_tree(bool, split_mv_tree, | |||
| decode_split_mv(struct mb_info *this, | split_mv_probs); | |||
| const struct mb_info *left, | partition = mv_partitions[partition_id]; | |||
| const struct mb_info *above, | this->base.partitioning = partition_id; | |||
| 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); | for (j = 0, mask = 0; mask < 65535; j++) | |||
| partition = mv_partitions[partition_id]; | { | |||
| this->base.partitioning = partition_id; | union mv mv, left_mv, above_mv; | |||
| enum prediction_mode subblock_mode; | ||||
| for (j = 0, mask = 0; mask < 65535; j++) | /* Find the first subblock in this partition. */ | |||
| { | for (k = 0; j != partition[k]; k++); | |||
| 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 */ | /* Decode the next MV */ | |||
| left_mv = left_block_mv(this, left, k); | left_mv = left_block_mv(this, left, k); | |||
| above_mv = above_block_mv(this, above, k); | above_mv = above_block_mv(this, above, k); | |||
| subblock_mode = submv_ref(bool, left_mv, above_mv); | subblock_mode = submv_ref(bool, left_mv, above_mv); | |||
| switch (subblock_mode) | switch (subblock_mode) | |||
| { | { | |||
| case LEFT4X4: | case LEFT4X4: | |||
| mv = left_mv; | mv = left_mv; | |||
| break; | break; | |||
| case ABOVE4X4: | case ABOVE4X4: | |||
| mv = above_mv; | mv = above_mv; | |||
| break; | break; | |||
| case ZERO4X4: | case ZERO4X4: | |||
| mv.raw = 0; | mv.raw = 0; | |||
| break; | break; | |||
| case NEW4X4: | case NEW4X4: | |||
| read_mv(bool, &mv, hdr->mv_probs); | read_mv(bool, &mv, hdr->mv_probs); | |||
| mv.d.x += best_mv->d.x; | mv.d.x += best_mv->d.x; | |||
| mv.d.y += best_mv->d.y; | mv.d.y += best_mv->d.y; | |||
| break; | break; | |||
| default: | default: | |||
| assert(0); | assert(0); | |||
| } | } | |||
| /* Fill the MV's for this partition */ | /* Fill the MV's for this partition */ | |||
| for (; k < 16; k++) | for (; k < 16; k++) | |||
| if (j == partition[k]) | if (j == partition[k]) | |||
| { | { | |||
| this->split.mvs[k] = mv; | this->split.mvs[k] = mv; | |||
| mask |= 1 << k; | mask |= 1 << k; | |||
| } | } | |||
| } | } | |||
| } | } | |||
| static int | static int | |||
| need_mc_border(union mv mv, int l, int t, int b_w, int w, int h) | need_mc_border(union mv mv, int l, int t, int b_w, int w, int h) | |||
| { | { | |||
| int b, r; | 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 top-left pixel */ | /* Get distance to edge for bottom-right pixel */ | |||
| l += (mv.d.x >> 3); | r = w - (l + b_w); | |||
| t += (mv.d.y >> 3); | b = h - (t + b_w); | |||
| /* 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); | return (l >> 1 < 2 || r >> 1 < 3 || t >> 1 < 2 || b >> 1 < 3); | |||
| } | } | |||
| static void | static void | |||
| decode_mvs(struct vp8_decoder_ctx *ctx, | decode_mvs(struct vp8_decoder_ctx *ctx, | |||
| struct mb_info *this, | struct mb_info *this, | |||
| const struct mb_info *left, | const struct mb_info *left, | |||
| const struct mb_info *above, | const struct mb_info *above, | |||
| const struct mv_clamp_rect *bounds, | const struct mv_clamp_rect *bounds, | |||
| struct bool_decoder *bool) | struct bool_decoder *bool) | |||
| { | { | |||
| struct vp8_entropy_hdr *hdr = &ctx->entropy_hdr; | struct vp8_entropy_hdr *hdr = &ctx->entropy_hdr; | |||
| union mv near_mvs[4]; | union mv near_mvs[4]; | |||
| union mv clamped_best_mv; | union mv clamped_best_mv; | |||
| int mv_cnts[4]; | int mv_cnts[4]; | |||
| unsigned char probs[4]; | unsigned char probs[4]; | |||
| enum {BEST, NEAREST, NEAR}; | enum {BEST, NEAREST, NEAR}; | |||
| int x, y, w, h, b; | int x, y, w, h, b; | |||
| this->base.ref_frame = bool_get(bool, hdr->prob_last) | this->base.ref_frame = bool_get(bool, hdr->prob_last) | |||
| ? 2 + bool_get(bool, hdr->prob_gf) | ? 2 + bool_get(bool, hdr->prob_gf) | |||
| : 1; | : 1; | |||
| find_near_mvs(this, this - 1, above, ctx->reference_hdr.sign_bias, | find_near_mvs(this, this - 1, above, | |||
| near_mvs, mv_cnts); | ctx->reference_hdr.sign_bias, near_mvs, mv_cnts); | |||
| probs[0] = mv_counts_to_probs[mv_cnts[0]][0]; | probs[0] = mv_counts_to_probs[mv_cnts[0]][0]; | |||
| probs[1] = mv_counts_to_probs[mv_cnts[1]][1]; | probs[1] = mv_counts_to_probs[mv_cnts[1]][1]; | |||
| probs[2] = mv_counts_to_probs[mv_cnts[2]][2]; | probs[2] = mv_counts_to_probs[mv_cnts[2]][2]; | |||
| probs[3] = mv_counts_to_probs[mv_cnts[3]][3]; | probs[3] = mv_counts_to_probs[mv_cnts[3]][3]; | |||
| this->base.y_mode = bool_read_tree(bool, mv_ref_tree, probs); | this->base.y_mode = bool_read_tree(bool, mv_ref_tree, probs); | |||
| this->base.uv_mode = this->base.y_mode; | this->base.uv_mode = this->base.y_mode; | |||
| this->base.need_mc_border = 0; | this->base.need_mc_border = 0; | |||
| x = (-bounds->to_left - 128) >> 3; | x = (-bounds->to_left - 128) >> 3; | |||
| y = (-bounds->to_top - 128) >> 3; | y = (-bounds->to_top - 128) >> 3; | |||
| w = ctx->mb_cols * 16; | w = ctx->mb_cols * 16; | |||
| h = ctx->mb_rows * 16; | h = ctx->mb_rows * 16; | |||
| switch (this->base.y_mode) | switch (this->base.y_mode) | |||
| { | { | |||
| case NEARESTMV: | case NEARESTMV: | |||
| this->base.mv = clamp_mv(near_mvs[NEAREST], bounds); | this->base.mv = clamp_mv(near_mvs[NEAREST], bounds); | |||
| break; | 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}}}; | ||||
| case NEARMV: | clamped_best_mv = clamp_mv(near_mvs[BEST], bounds); | |||
| this->base.mv = clamp_mv(near_mvs[NEAR], bounds); | decode_split_mv(this, left, above, hdr, &clamped_best_mv, | |||
| break; | bool); | |||
| case ZEROMV: | this->base.mv = this->split.mvs[15]; | |||
| 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); | for (b = 0; b < 16; b++) | |||
| decode_split_mv(this, left, above, hdr, &clamped_best_mv, bool); | { | |||
| this->base.mv = this->split.mvs[15]; | 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; | ||||
| for (b = 0; b < 16; b++) | if (need_mc_border(this->split.mvs[b], | |||
| { | x + (b & 3) * 4, y + (b & ~3), 4, w, h)) | |||
| chroma_mv[(b>>1&1) + (b>>2&2)].d.x += | { | |||
| this->split.mvs[b].d.x; | this->base.need_mc_border = 1; | |||
| chroma_mv[(b>>1&1) + (b>>2&2)].d.y += | break; | |||
| this->split.mvs[b].d.y; | } | |||
| } | ||||
| if (need_mc_border(this->split.mvs[b], | for (b = 0; b < 4; b++) | |||
| x + (b & 3) * 4, y + (b & ~3), 4, w, h)) | { | |||
| { | chroma_mv[b].d.x += 4 + 8 * (chroma_mv[b].d.x >> 31); | |||
| this->base.need_mc_border = 1; | chroma_mv[b].d.y += 4 + 8 * (chroma_mv[b].d.y >> 31); | |||
| break; | chroma_mv[b].d.x /= 4; | |||
| } | chroma_mv[b].d.y /= 4; | |||
| } | ||||
| for (b = 0; b < 4; b++) | //note we're passing in non-subsampled coordinates | |||
| { | if (need_mc_border(chroma_mv[b], | |||
| chroma_mv[b].d.x += 4 + 8 * (chroma_mv[b].d.x >> 31); | x + (b & 1) * 8, y + (b >> 1) * 8, 16, w, h)) | |||
| chroma_mv[b].d.y += 4 + 8 * (chroma_mv[b].d.y >> 31); | { | |||
| chroma_mv[b].d.x /= 4; | this->base.need_mc_border = 1; | |||
| chroma_mv[b].d.y /= 4; | break; | |||
| } | ||||
| } | ||||
| //note we're passing in non-subsampled coordinates | return; //skip need_mc_border check | |||
| if (need_mc_border(chroma_mv[b], | } | |||
| x + (b & 1) * 8, y + (b >> 1) * 8, 16, w, h)) | default: | |||
| { | assert(0); | |||
| this->base.need_mc_border = 1; | } | |||
| break; | ||||
| } | if (need_mc_border(this->base.mv, x, y, 16, w, h)) | |||
| } | this->base.need_mc_border = 1; | |||
| } | ||||
| return; //skip need_mc_border check | void | |||
| } | vp8_dixie_modemv_process_row(struct vp8_decoder_ctx *ctx, | |||
| default: | struct bool_decoder *bool, | |||
| assert(0); | int row, | |||
| } | int start_col, | |||
| int num_cols) | ||||
| { | ||||
| struct mb_info *above, *this; | ||||
| unsigned int col; | ||||
| struct mv_clamp_rect bounds; | ||||
| if (need_mc_border(this->base.mv, x, y, 16, w, h)) | this = ctx->mb_info_rows[row] + start_col; | |||
| this->base.need_mc_border = 1; | above = ctx->mb_info_rows[row - 1] + start_col; | |||
| } | ||||
| void | /* Calculate the eighth-pel MV bounds using a 1 MB border. */ | |||
| vp8_dixie_modemv_process_row(struct vp8_decoder_ctx *ctx, | bounds.to_left = -((start_col + 1) << 7); | |||
| struct bool_decoder *bool, | bounds.to_right = (ctx->mb_cols - start_col) << 7; | |||
| int row, | bounds.to_top = -((row + 1) << 7); | |||
| int start_col, | bounds.to_bottom = (ctx->mb_rows - row) << 7; | |||
| int num_cols) | ||||
| { | ||||
| struct mb_info *above, *this; | ||||
| unsigned int col; | ||||
| struct mv_clamp_rect bounds; | ||||
| this = ctx->mb_info_rows[row] + start_col; | for (col = start_col; col < start_col + num_cols; col++) | |||
| above = ctx->mb_info_rows[row - 1] + start_col; | { | |||
| if (ctx->segment_hdr.update_map) | ||||
| this->base.segment_id = read_segment_id(bool, | ||||
| &ctx->segment_hdr); | ||||
| /* Calculate the eighth-pel MV bounds using a 1 MB border. */ | if (ctx->entropy_hdr.coeff_skip_enabled) | |||
| bounds.to_left = -((start_col + 1) << 7); | this->base.skip_coeff = bool_get(bool, | |||
| bounds.to_right = (ctx->mb_cols - start_col) << 7; | ctx->entropy_hdr.coeff_skip_prob); | |||
| 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->frame_hdr.is_keyframe) | |||
| { | { | |||
| if (ctx->segment_hdr.update_map) | if (!ctx->segment_hdr.update_map) | |||
| this->base.segment_id = read_segment_id(bool, | this->base.segment_id = 0; | |||
| &ctx->segment_hdr); | ||||
| if (ctx->entropy_hdr.coeff_skip_enabled) | decode_kf_mb_mode(this, this - 1, above, bool); | |||
| this->base.skip_coeff = bool_get(bool, | } | |||
| ctx->entropy_hdr.coeff_skip_prob); | 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); | ||||
| if (ctx->frame_hdr.is_keyframe) | bounds.to_left -= 16 << 3; | |||
| { | bounds.to_right -= 16 << 3; | |||
| if (!ctx->segment_hdr.update_map) | } | |||
| this->base.segment_id = 0; | ||||
| decode_kf_mb_mode(this, this - 1, above, bool); | /* Advance to next mb */ | |||
| } | this++; | |||
| else | above++; | |||
| { | } | |||
| 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; | void | |||
| bounds.to_right -= 16 << 3; | vp8_dixie_modemv_init(struct vp8_decoder_ctx *ctx) | |||
| } | { | |||
| unsigned int mbi_w, mbi_h, i; | ||||
| struct mb_info *mbi; | ||||
| /* Advance to next mb */ | mbi_w = ctx->mb_cols + 1; /* For left border col */ | |||
| this++; | mbi_h = ctx->mb_rows + 1; /* For above border row */ | |||
| above++; | ||||
| } | ||||
| } | ||||
| void | if (ctx->frame_hdr.frame_size_updated) | |||
| vp8_dixie_modemv_init(struct vp8_decoder_ctx *ctx) | { | |||
| { | free(ctx->mb_info_storage); | |||
| unsigned int mbi_w, mbi_h, i; | ctx->mb_info_storage = NULL; | |||
| struct mb_info *mbi; | free(ctx->mb_info_rows_storage); | |||
| ctx->mb_info_rows_storage = NULL; | ||||
| } | ||||
| mbi_w = ctx->mb_cols + 1; /* For left border col */ | if (!ctx->mb_info_storage) | |||
| mbi_h = ctx->mb_rows + 1; /* For above border row */ | ctx->mb_info_storage = calloc(mbi_w * mbi_h, | |||
| sizeof(*ctx->mb_info_storage)); | ||||
| if (ctx->frame_hdr.frame_size_updated) | if (!ctx->mb_info_rows_storage) | |||
| { | ctx->mb_info_rows_storage = calloc(mbi_h, | |||
| free(ctx->mb_info_storage); | sizeof(*ctx->mb_info_rows_storage)); | |||
| ctx->mb_info_storage = NULL; | ||||
| free(ctx->mb_info_rows_storage); | ||||
| ctx->mb_info_rows_storage = NULL; | ||||
| } | ||||
| if (!ctx->mb_info_storage) | /* Set up row pointers */ | |||
| ctx->mb_info_storage = calloc(mbi_w * mbi_h, | mbi = ctx->mb_info_storage + 1; | |||
| sizeof(*ctx->mb_info_storage)); | ||||
| if (!ctx->mb_info_rows_storage) | for (i = 0; i < mbi_h; i++) | |||
| ctx->mb_info_rows_storage = calloc(mbi_h, | { | |||
| sizeof(*ctx->mb_info_rows_storage)); | ctx->mb_info_rows_storage[i] = mbi; | |||
| mbi += mbi_w; | ||||
| } | ||||
| /* Set up row pointers */ | ctx->mb_info_rows = ctx->mb_info_rows_storage + 1; | |||
| 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; | 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; | ||||
| } | ||||
| void | ---- End code block ---------------------------------------- | |||
| 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; | ||||
| } | ||||
| 20.12. modemv.h | 20.12. modemv.h | |||
| ---- Begin code block -------------------------------------- | ---- Begin code block -------------------------------------- | |||
| /* | /* | |||
| * Copyright (c) 2010 The VP8 project authors. All Rights Reserved. | * Copyright (c) 2010 The VP8 project authors. All Rights Reserved. | |||
| * | * | |||
| * Use of this source code is governed by a BSD-style license | * 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 | * that can be found in the LICENSE file in the root of the source | |||
| * tree. An additional intellectual property rights grant can be | * tree. An additional intellectual property rights grant can be | |||
| skipping to change at page 203, line 39 ¶ | skipping to change at page 203, line 40 ¶ | |||
| int row, | int row, | |||
| int start_col, | int start_col, | |||
| int num_cols); | int num_cols); | |||
| #endif | #endif | |||
| ---- End code block ---------------------------------------- | ---- End code block ---------------------------------------- | |||
| 20.13. modemv_data.h | 20.13. modemv_data.h | |||
| ---- Begin code block -------------------------------------- | ---- Begin code block -------------------------------------- | |||
| static const unsigned char kf_y_mode_probs[] = { 145, 156, 163, 128}; | 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_uv_mode_probs[] = { 142, 114, 183}; | |||
| static const unsigned char kf_b_mode_probs[10][10][9] = | static const unsigned char kf_b_mode_probs[10][10][9] = | |||
| { | { | |||
| { /* above mode 0 */ | { /* above mode 0 */ | |||
| { /* left mode 0 */ 231, 120, 48, 89, 115, 113, 120, 152, 112}, | { /* 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 1 */ 152, 179, 64, 126, 170, 118, 46, 70, 95}, | |||
| { /* left mode 2 */ 175, 69, 143, 80, 85, 82, 72, 155, 103}, | { /* 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 3 */ 56, 58, 10, 171, 218, 189, 17, 13, 152}, | |||
| { /* left mode 4 */ 144, 71, 10, 38, 171, 213, 144, 34, 26}, | { /* 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 5 */ 114, 26, 17, 163, 44, 195, 21, 10, 173}, | |||
| { /* left mode 6 */ 121, 24, 80, 195, 26, 62, 44, 64, 85}, | { /* 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 7 */ 170, 46, 55, 19, 136, 160, 33, 206, 71}, | |||
| { /* left mode 8 */ 63, 20, 8, 114, 114, 208, 12, 9, 226}, | { /* left mode 8 */ 63, 20, 8, 114, 114, 208, 12, 9, 226}, | |||
| { /* left mode 9 */ 81, 40, 11, 96, 182, 84, 29, 16, 36} | { /* left mode 9 */ 81, 40, 11, 96, 182, 84, 29, 16, 36} | |||
| }, | }, | |||
| { /* above mode 1 */ | { /* above mode 1 */ | |||
| { /* left mode 0 */ 134, 183, 89, 137, 98, 101, 106, 165, 148}, | { /* 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 1 */ 72, 187, 100, 130, 157, 111, 32, 75, 80}, | |||
| { /* left mode 2 */ 66, 102, 167, 99, 74, 62, 40, 234, 128}, | { /* 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 3 */ 41, 53, 9, 178, 241, 141, 26, 8, 107}, | |||
| { /* left mode 4 */ 104, 79, 12, 27, 217, 255, 87, 17, 7}, | { /* 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 5 */ 74, 43, 26, 146, 73, 166, 49, 23, 157}, | |||
| { /* left mode 6 */ 65, 38, 105, 160, 51, 52, 31, 115, 128}, | { /* 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 7 */ 87, 68, 71, 44, 114, 51, 15, 186, 23}, | |||
| { /* left mode 8 */ 47, 41, 14, 110, 182, 183, 21, 17, 194}, | { /* left mode 8 */ 47, 41, 14, 110, 182, 183, 21, 17, 194}, | |||
| { /* left mode 9 */ 66, 45, 25, 102, 197, 189, 23, 18, 22} | { /* left mode 9 */ 66, 45, 25, 102, 197, 189, 23, 18, 22} | |||
| }, | }, | |||
| { /* above mode 2 */ | { /* above mode 2 */ | |||
| { /* left mode 0 */ 88, 88, 147, 150, 42, 46, 45, 196, 205}, | { /* 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 1 */ 43, 97, 183, 117, 85, 38, 35, 179, 61}, | |||
| { /* left mode 2 */ 39, 53, 200, 87, 26, 21, 43, 232, 171}, | { /* 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 3 */ 56, 34, 51, 104, 114, 102, 29, 93, 77}, | |||
| { /* left mode 4 */ 107, 54, 32, 26, 51, 1, 81, 43, 31}, | { /* left mode 4 */ 107, 54, 32, 26, 51, 1, 81, 43, 31}, | |||
| { /* left mode 5 */ 39, 28, 85, 171, 58, 165, 90, 98, 64}, | { /* 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 6 */ 34, 22, 116, 206, 23, 34, 43, 166, 73}, | |||
| { /* left mode 7 */ 68, 25, 106, 22, 64, 171, 36, 225, 114}, | { /* 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 8 */ 34, 19, 21, 102, 132, 188, 16, 76, 124}, | |||
| { /* left mode 9 */ 62, 18, 78, 95, 85, 57, 50, 48, 51} | { /* left mode 9 */ 62, 18, 78, 95, 85, 57, 50, 48, 51} | |||
| }, | }, | |||
| { /* above mode 3 */ | { /* above mode 3 */ | |||
| { /* left mode 0 */ 193, 101, 35, 159, 215, 111, 89, 46, 111}, | { /* 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 1 */ 60, 148, 31, 172, 219, 228, 21, 18, 111}, | |||
| { /* left mode 2 */ 112, 113, 77, 85, 179, 255, 38, 120, 114}, | { /* 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 3 */ 40, 42, 1, 196, 245, 209, 10, 25, 109}, | |||
| { /* left mode 4 */ 100, 80, 8, 43, 154, 1, 51, 26, 71}, | { /* 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 5 */ 88, 43, 29, 140, 166, 213, 37, 43, 154}, | |||
| { /* left mode 6 */ 61, 63, 30, 155, 67, 45, 68, 1, 209}, | { /* 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 7 */ 142, 78, 78, 16, 255, 128, 34, 197, 171}, | |||
| { /* left mode 8 */ 41, 40, 5, 102, 211, 183, 4, 1, 221}, | { /* left mode 8 */ 41, 40, 5, 102, 211, 183, 4, 1, 221}, | |||
| { /* left mode 9 */ 51, 50, 17, 168, 209, 192, 23, 25, 82} | { /* left mode 9 */ 51, 50, 17, 168, 209, 192, 23, 25, 82} | |||
| }, | }, | |||
| { /* above mode 4 */ | { /* above mode 4 */ | |||
| { /* left mode 0 */ 125, 98, 42, 88, 104, 85, 117, 175, 82}, | { /* 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 1 */ 95, 84, 53, 89, 128, 100, 113, 101, 45}, | |||
| { /* left mode 2 */ 75, 79, 123, 47, 51, 128, 81, 171, 1}, | { /* 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 3 */ 57, 17, 5, 71, 102, 57, 53, 41, 49}, | |||
| { /* left mode 4 */ 115, 21, 2, 10, 102, 255, 166, 23, 6}, | { /* 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 5 */ 38, 33, 13, 121, 57, 73, 26, 1, 85}, | |||
| { /* left mode 6 */ 41, 10, 67, 138, 77, 110, 90, 47, 114}, | { /* 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 7 */ 101, 29, 16, 10, 85, 128, 101, 196, 26}, | |||
| { /* left mode 8 */ 57, 18, 10, 102, 102, 213, 34, 20, 43}, | { /* left mode 8 */ 57, 18, 10, 102, 102, 213, 34, 20, 43}, | |||
| { /* left mode 9 */ 117, 20, 15, 36, 163, 128, 68, 1, 26} | { /* left mode 9 */ 117, 20, 15, 36, 163, 128, 68, 1, 26} | |||
| }, | }, | |||
| { /* above mode 5 */ | { /* above mode 5 */ | |||
| { /* left mode 0 */ 138, 31, 36, 171, 27, 166, 38, 44, 229}, | { /* 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 1 */ 67, 87, 58, 169, 82, 115, 26, 59, 179}, | |||
| { /* left mode 2 */ 63, 59, 90, 180, 59, 166, 93, 73, 154}, | { /* 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 3 */ 40, 40, 21, 116, 143, 209, 34, 39, 175}, | |||
| { /* left mode 4 */ 57, 46, 22, 24, 128, 1, 54, 17, 37}, | { /* 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 5 */ 47, 15, 16, 183, 34, 223, 49, 45, 183}, | |||
| { /* left mode 6 */ 46, 17, 33, 183, 6, 98, 15, 32, 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 7 */ 65, 32, 73, 115, 28, 128, 23, 128, 205}, | |||
| { /* left mode 8 */ 40, 3, 9, 115, 51, 192, 18, 6, 223}, | { /* left mode 8 */ 40, 3, 9, 115, 51, 192, 18, 6, 223}, | |||
| { /* left mode 9 */ 87, 37, 9, 115, 59, 77, 64, 21, 47} | { /* left mode 9 */ 87, 37, 9, 115, 59, 77, 64, 21, 47} | |||
| }, | }, | |||
| { /* above mode 6 */ | { /* above mode 6 */ | |||
| { /* left mode 0 */ 104, 55, 44, 218, 9, 54, 53, 130, 226}, | { /* 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 1 */ 64, 90, 70, 205, 40, 41, 23, 26, 57}, | |||
| { /* left mode 2 */ 54, 57, 112, 184, 5, 41, 38, 166, 213}, | { /* 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 3 */ 30, 34, 26, 133, 152, 116, 10, 32, 134}, | |||
| { /* left mode 4 */ 75, 32, 12, 51, 192, 255, 160, 43, 51}, | { /* left mode 4 */ 75, 32, 12, 51, 192, 255, 160, 43, 51}, | |||
| { /* left mode 5 */ 39, 19, 53, 221, 26, 114, 32, 73, 255}, | { /* 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 6 */ 31, 9, 65, 234, 2, 15, 1, 118, 73}, | |||
| { /* left mode 7 */ 88, 31, 35, 67, 102, 85, 55, 186, 85}, | { /* 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 8 */ 56, 21, 23, 111, 59, 205, 45, 37, 192}, | |||
| { /* left mode 9 */ 55, 38, 70, 124, 73, 102, 1, 34, 98} | { /* left mode 9 */ 55, 38, 70, 124, 73, 102, 1, 34, 98} | |||
| }, | }, | |||
| { /* above mode 7 */ | { /* above mode 7 */ | |||
| { /* left mode 0 */ 102, 61, 71, 37, 34, 53, 31, 243, 192}, | { /* 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 1 */ 69, 60, 71, 38, 73, 119, 28, 222, 37}, | |||
| { /* left mode 2 */ 68, 45, 128, 34, 1, 47, 11, 245, 171}, | { /* 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 3 */ 62, 17, 19, 70, 146, 85, 55, 62, 70}, | |||
| { /* left mode 4 */ 75, 15, 9, 9, 64, 255, 184, 119, 16}, | { /* 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 5 */ 37, 43, 37, 154, 100, 163, 85, 160, 1}, | |||
| { /* left mode 6 */ 63, 9, 92, 136, 28, 64, 32, 201, 85}, | { /* 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 7 */ 86, 6, 28, 5, 64, 255, 25, 248, 1}, | |||
| { /* left mode 8 */ 56, 8, 17, 132, 137, 255, 55, 116, 128}, | { /* left mode 8 */ 56, 8, 17, 132, 137, 255, 55, 116, 128}, | |||
| { /* left mode 9 */ 58, 15, 20, 82, 135, 57, 26, 121, 40} | { /* left mode 9 */ 58, 15, 20, 82, 135, 57, 26, 121, 40} | |||
| }, | }, | |||
| { /* above mode 8 */ | { /* above mode 8 */ | |||
| { /* left mode 0 */ 164, 50, 31, 137, 154, 133, 25, 35, 218}, | { /* 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 1 */ 51, 103, 44, 131, 131, 123, 31, 6, 158}, | |||
| { /* left mode 2 */ 86, 40, 64, 135, 148, 224, 45, 183, 128}, | { /* 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 3 */ 22, 26, 17, 131, 240, 154, 14, 1, 209}, | |||
| { /* left mode 4 */ 83, 12, 13, 54, 192, 255, 68, 47, 28}, | { /* 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 5 */ 45, 16, 21, 91, 64, 222, 7, 1, 197}, | |||
| { /* left mode 6 */ 56, 21, 39, 155, 60, 138, 23, 102, 213}, | { /* 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 7 */ 85, 26, 85, 85, 128, 128, 32, 146, 171}, | |||
| { /* left mode 8 */ 18, 11, 7, 63, 144, 171, 4, 4, 246}, | { /* left mode 8 */ 18, 11, 7, 63, 144, 171, 4, 4, 246}, | |||
| { /* left mode 9 */ 35, 27, 10, 146, 174, 171, 12, 26, 128} | { /* left mode 9 */ 35, 27, 10, 146, 174, 171, 12, 26, 128} | |||
| }, | }, | |||
| { /* above mode 9 */ | { /* above mode 9 */ | |||
| { /* left mode 0 */ 190, 80, 35, 99, 180, 80, 126, 54, 45}, | { /* 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 1 */ 85, 126, 47, 87, 176, 51, 41, 20, 32}, | |||
| { /* left mode 2 */ 101, 75, 128, 139, 118, 146, 116, 128, 85}, | { /* 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 3 */ 56, 41, 15, 176, 236, 85, 37, 9, 62}, | |||
| { /* left mode 4 */ 146, 36, 19, 30, 171, 255, 97, 27, 20}, | { /* 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 5 */ 71, 30, 17, 119, 118, 255, 17, 18, 138}, | |||
| { /* left mode 6 */ 101, 38, 60, 138, 55, 70, 43, 26, 142}, | { /* 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 7 */ 138, 45, 61, 62, 219, 1, 81, 188, 64}, | |||
| { /* left mode 8 */ 32, 41, 20, 117, 151, 142, 20, 21, 163}, | { /* left mode 8 */ 32, 41, 20, 117, 151, 142, 20, 21, 163}, | |||
| { /* left mode 9 */ 112, 19, 12, 61, 195, 128, 48, 4, 24} | { /* left mode 9 */ 112, 19, 12, 61, 195, 128, 48, 4, 24} | |||
| } | } | |||
| }; | }; | |||
| static const int kf_y_mode_tree[] = | static const int kf_y_mode_tree[] = | |||
| { | { | |||
| -B_PRED, 2, | -B_PRED, 2, | |||
| 4, 6, | 4, 6, | |||
| -DC_PRED, -V_PRED, | -DC_PRED, -V_PRED, | |||
| -H_PRED, -TM_PRED | -H_PRED, -TM_PRED | |||
| }; | }; | |||
| static const int y_mode_tree[] = | static const int y_mode_tree[] = | |||
| { | { | |||
| -DC_PRED, 2, | -DC_PRED, 2, | |||
| 4, 6, | 4, 6, | |||
| -V_PRED, -H_PRED, | -V_PRED, -H_PRED, | |||
| -TM_PRED, -B_PRED | -TM_PRED, -B_PRED | |||
| }; | }; | |||
| static const int uv_mode_tree[6] = | static const int uv_mode_tree[6] = | |||
| { | { | |||
| -DC_PRED, 2, | -DC_PRED, 2, | |||
| -V_PRED, 4, | -V_PRED, 4, | |||
| -H_PRED, -TM_PRED | -H_PRED, -TM_PRED | |||
| }; | }; | |||
| static const int b_mode_tree[18] = | static const int b_mode_tree[18] = | |||
| { | { | |||
| -B_DC_PRED, 2, /* 0 = DC_NODE */ | -B_DC_PRED, 2, /* 0 = DC_NODE */ | |||
| -B_TM_PRED, 4, /* 1 = TM_NODE */ | -B_TM_PRED, 4, /* 1 = TM_NODE */ | |||
| -B_VE_PRED, 6, /* 2 = VE_NODE */ | -B_VE_PRED, 6, /* 2 = VE_NODE */ | |||
| 8, 12, /* 3 = COM_NODE */ | 8, 12, /* 3 = COM_NODE */ | |||
| -B_HE_PRED, 10, /* 4 = HE_NODE */ | -B_HE_PRED, 10, /* 4 = HE_NODE */ | |||
| -B_RD_PRED, -B_VR_PRED, /* 5 = RD_NODE */ | -B_RD_PRED, -B_VR_PRED, /* 5 = RD_NODE */ | |||
| -B_LD_PRED, 14, /* 6 = LD_NODE */ | -B_LD_PRED, 14, /* 6 = LD_NODE */ | |||
| -B_VL_PRED, 16, /* 7 = VL_NODE */ | -B_VL_PRED, 16, /* 7 = VL_NODE */ | |||
| -B_HD_PRED, -B_HU_PRED /* 8 = HD_NODE */ | -B_HD_PRED, -B_HU_PRED /* 8 = HD_NODE */ | |||
| }; | }; | |||
| static const int small_mv_tree[14] = | static const int small_mv_tree[14] = | |||
| { | { | |||
| 2, 8, | 2, 8, | |||
| 4, 6, | 4, 6, | |||
| -0, -1, | -0, -1, | |||
| -2, -3, | -2, -3, | |||
| 10, 12, | 10, 12, | |||
| -4, -5, | -4, -5, | |||
| -6, -7 | -6, -7 | |||
| }; | }; | |||
| static const int mv_ref_tree[8] = | static const int mv_ref_tree[8] = | |||
| { | { | |||
| -ZEROMV, 2, | -ZEROMV, 2, | |||
| -NEARESTMV, 4, | -NEARESTMV, 4, | |||
| -NEARMV, 6, | -NEARMV, 6, | |||
| -NEWMV, -SPLITMV | -NEWMV, -SPLITMV | |||
| }; | }; | |||
| static const int submv_ref_tree[6] = | static const int submv_ref_tree[6] = | |||
| { | { | |||
| -LEFT4X4, 2, | -LEFT4X4, 2, | |||
| -ABOVE4X4, 4, | -ABOVE4X4, 4, | |||
| -ZERO4X4, -NEW4X4 | -ZERO4X4, -NEW4X4 | |||
| }; | }; | |||
| static const int split_mv_tree[6] = | static const int split_mv_tree[6] = | |||
| { | { | |||
| -3, 2, | -3, 2, | |||
| -2, 4, | -2, 4, | |||
| -0, -1 | -0, -1 | |||
| }; | }; | |||
| static const unsigned char default_b_mode_probs[] = | static const unsigned char default_b_mode_probs[] = | |||
| { 120, 90, 79, 133, 87, 85, 80, 111, 151}; | { 120, 90, 79, 133, 87, 85, 80, 111, 151}; | |||
| static const unsigned char mv_counts_to_probs[6][4] = | static const unsigned char mv_counts_to_probs[6][4] = | |||
| { | { | |||
| { 7, 1, 1, 143 }, | { 7, 1, 1, 143 }, | |||
| { 14, 18, 14, 107 }, | { 14, 18, 14, 107 }, | |||
| { 135, 64, 57, 68 }, | { 135, 64, 57, 68 }, | |||
| { 60, 56, 128, 65 }, | { 60, 56, 128, 65 }, | |||
| { 159, 134, 128, 34 }, | { 159, 134, 128, 34 }, | |||
| { 234, 188, 128, 28 } | { 234, 188, 128, 28 } | |||
| }; | }; | |||
| static const unsigned char split_mv_probs[3] = | static const unsigned char split_mv_probs[3] = | |||
| { 110, 111, 150}; | { 110, 111, 150}; | |||
| static const unsigned char submv_ref_probs2[5][3] = | static const unsigned char submv_ref_probs2[5][3] = | |||
| { | { | |||
| { 147, 136, 18 }, | { 147, 136, 18 }, | |||
| { 106, 145, 1 }, | { 106, 145, 1 }, | |||
| { 179, 121, 1 }, | { 179, 121, 1 }, | |||
| { 223, 1, 34 }, | { 223, 1, 34 }, | |||
| { 208, 1, 1 } | { 208, 1, 1 } | |||
| }; | }; | |||
| const static int mv_partitions[4][16] = | 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, 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, 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, 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 } | {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 } | |||
| }; | }; | |||
| ---- End code block ---------------------------------------- | ---- End code block ---------------------------------------- | |||
| 20.14. predict.c | 20.14. predict.c | |||
| ---- Begin code block -------------------------------------- | ||||
| /* | /* | |||
| * Copyright (c) 2010 The VP8 project authors. All Rights Reserved. | * Copyright (c) 2010 The VP8 project authors. All Rights Reserved. | |||
| * | * | |||
| * Use of this source code is governed by a BSD-style license | * 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 | * that can be found in the LICENSE file in the root of the source | |||
| * tree. An additional intellectual property rights grant can be | * tree. An additional intellectual property rights grant can be | |||
| * found in the file PATENTS. All contributing project authors may | * found in the file PATENTS. All contributing project authors may | |||
| * be found in the AUTHORS file in the root of the source tree. | * be found in the AUTHORS file in the root of the source tree. | |||
| */ | */ | |||
| #include "dixie.h" | #include "dixie.h" | |||
| #include "predict.h" | #include "predict.h" | |||
| #include "idct_add.h" | #include "idct_add.h" | |||
| #include "mem.h" | #include "mem.h" | |||
| #include <assert.h> | #include <assert.h> | |||
| #include <string.h> | #include <string.h> | |||
| enum | enum | |||
| { | { | |||
| BORDER_PIXELS = 16, | BORDER_PIXELS = 16, | |||
| }; | }; | |||
| static const filter_t sixtap_filters[8] = | static const filter_t sixtap_filters[8] = | |||
| { | { | |||
| { 0, 0, 128, 0, 0, 0 }, | { 0, 0, 128, 0, 0, 0 }, | |||
| { 0, -6, 123, 12, -1, 0 }, | { 0, -6, 123, 12, -1, 0 }, | |||
| { 2, -11, 108, 36, -8, 1 }, | { 2, -11, 108, 36, -8, 1 }, | |||
| { 0, -9, 93, 50, -6, 0 }, | { 0, -9, 93, 50, -6, 0 }, | |||
| { 3, -16, 77, 77, -16, 3 }, | { 3, -16, 77, 77, -16, 3 }, | |||
| { 0, -6, 50, 93, -9, 0 }, | { 0, -6, 50, 93, -9, 0 }, | |||
| { 1, -8, 36, 108, -11, 2 }, | { 1, -8, 36, 108, -11, 2 }, | |||
| { 0, -1, 12, 123, -6, 0 }, | { 0, -1, 12, 123, -6, 0 }, | |||
| }; | }; | |||
| static const filter_t bilinear_filters[8] = | static const filter_t bilinear_filters[8] = | |||
| { | { | |||
| { 0, 0, 128, 0, 0, 0 }, | { 0, 0, 128, 0, 0, 0 }, | |||
| { 0, 0, 112, 16, 0, 0 }, | { 0, 0, 112, 16, 0, 0 }, | |||
| { 0, 0, 96, 32, 0, 0 }, | { 0, 0, 96, 32, 0, 0 }, | |||
| { 0, 0, 80, 48, 0, 0 }, | { 0, 0, 80, 48, 0, 0 }, | |||
| { 0, 0, 64, 64, 0, 0 }, | { 0, 0, 64, 64, 0, 0 }, | |||
| { 0, 0, 48, 80, 0, 0 }, | { 0, 0, 48, 80, 0, 0 }, | |||
| { 0, 0, 32, 96, 0, 0 }, | { 0, 0, 32, 96, 0, 0 }, | |||
| { 0, 0, 16, 112, 0, 0 } | { 0, 0, 16, 112, 0, 0 } | |||
| }; | }; | |||
| static void | static void | |||
| predict_h_nxn(unsigned char *predict, | predict_h_nxn(unsigned char *predict, | |||
| int stride, | int stride, | |||
| int n) | int n) | |||
| { | { | |||
| unsigned char *left = predict - 1; | unsigned char *left = predict - 1; | |||
| int i, j; | int i, j; | |||
| for (i = 0; i < n; i++) | for (i = 0; i < n; i++) | |||
| for (j = 0; j < n; j++) | for (j = 0; j < n; j++) | |||
| predict[i *stride + j] = left[i * stride]; | predict[i *stride + j] = left[i * stride]; | |||
| } | } | |||
| static void | static void | |||
| predict_v_nxn(unsigned char *predict, | predict_v_nxn(unsigned char *predict, | |||
| int stride, | int stride, | |||
| int n) | int n) | |||
| { | { | |||
| unsigned char *above = predict - stride; | unsigned char *above = predict - stride; | |||
| int i, j; | int i, j; | |||
| for (i = 0; i < n; i++) | for (i = 0; i < n; i++) | |||
| for (j = 0; j < n; j++) | for (j = 0; j < n; j++) | |||
| predict[i *stride + j] = above[j]; | predict[i *stride + j] = above[j]; | |||
| } | } | |||
| static void | static void | |||
| predict_tm_nxn(unsigned char *predict, | predict_tm_nxn(unsigned char *predict, | |||
| int stride, | int stride, | |||
| int n) | int n) | |||
| { | { | |||
| /* Transposes the left column to the top row for later consumption | /* Transposes the left column to the top row for later | |||
| * by the idct/recon stage | * consumption by the idct/recon stage | |||
| */ | */ | |||
| unsigned char *left = predict - 1; | unsigned char *left = predict - 1; | |||
| unsigned char *above = predict - stride; | unsigned char *above = predict - stride; | |||
| unsigned char p = above[-1]; | unsigned char p = above[-1]; | |||
| int i, j; | int i, j; | |||
| for (j = 0; j < n; j++) | for (j = 0; j < n; j++) | |||
| { | { | |||
| for (i = 0; i < n; i++) | for (i = 0; i < n; i++) | |||
| predict[i] = CLAMP_255(*left + above[i] - p); | predict[i] = CLAMP_255(*left + above[i] - p); | |||
| predict += stride; | predict += stride; | |||
| left += stride; | left += stride; | |||
| } | } | |||
| } | } | |||
| static void | static void | |||
| predict_dc_nxn(unsigned char *predict, | predict_dc_nxn(unsigned char *predict, | |||
| int stride, | int stride, | |||
| int n) | int n) | |||
| { | { | |||
| unsigned char *left = predict - 1; | unsigned char *left = predict - 1; | |||
| unsigned char *above = predict - stride; | unsigned char *above = predict - stride; | |||
| int i, j, dc = 0; | int i, j, dc = 0; | |||
| for (i = 0; i < n; i++) | for (i = 0; i < n; i++) | |||
| { | { | |||
| dc += *left + above[i]; | dc += *left + above[i]; | |||
| left += stride; | left += stride; | |||
| } | } | |||
| switch (n) | switch (n) | |||
| { | { | |||
| case 16: | case 16: | |||
| dc = (dc + 16) >> 5; | dc = (dc + 16) >> 5; | |||
| break; | break; | |||
| case 8: | case 8: | |||
| dc = (dc + 8) >> 4; | dc = (dc + 8) >> 4; | |||
| break; | break; | |||
| case 4: | case 4: | |||
| dc = (dc + 4) >> 3; | dc = (dc + 4) >> 3; | |||
| break; | break; | |||
| } | } | |||
| for (i = 0; i < n; i++) | for (i = 0; i < n; i++) | |||
| for (j = 0; j < n; j++) | for (j = 0; j < n; j++) | |||
| predict[i *stride + j] = dc; | predict[i *stride + j] = dc; | |||
| } | } | |||
| static void | static void | |||
| predict_ve_4x4(unsigned char *predict, | predict_ve_4x4(unsigned char *predict, | |||
| int stride) | int stride) | |||
| { | { | |||
| unsigned char *above = predict - stride; | unsigned char *above = predict - stride; | |||
| int i, j; | int i, j; | |||
| predict[0] = (above[-1] + 2 * above[0] + above[1] + 2) >> 2; | predict[0] = (above[-1] + 2 * above[0] + above[1] + 2) >> 2; | |||
| predict[1] = (above[ 0] + 2 * above[1] + above[2] + 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[2] = (above[ 1] + 2 * above[2] + above[3] + 2) >> 2; | |||
| predict[3] = (above[ 2] + 2 * above[3] + above[4] + 2) >> 2; | predict[3] = (above[ 2] + 2 * above[3] + above[4] + 2) >> 2; | |||
| for (i = 1; i < 4; i++) | for (i = 1; i < 4; i++) | |||
| for (j = 0; j < 4; j++) | for (j = 0; j < 4; j++) | |||
| predict[i *stride + j] = predict[j]; | predict[i *stride + j] = predict[j]; | |||
| } | } | |||
| static void | static void | |||
| predict_he_4x4(unsigned char *predict, | predict_he_4x4(unsigned char *predict, | |||
| int stride) | int stride) | |||
| { | { | |||
| unsigned char *left = predict - 1; | unsigned char *left = predict - 1; | |||
| predict[0] = | predict[0] = | |||
| predict[1] = | predict[1] = | |||
| predict[2] = | predict[2] = | |||
| predict[3] = (left[-stride] + 2 * left[0] + left[stride] + 2) >> 2; | predict[3] = (left[-stride] + 2 * left[0] + | |||
| predict += stride; | left[stride] + 2) >> 2; | |||
| left += stride; | predict += stride; | |||
| left += stride; | ||||
| predict[0] = | predict[0] = | |||
| predict[1] = | predict[1] = | |||
| predict[2] = | predict[2] = | |||
| predict[3] = (left[-stride] + 2 * left[0] + left[stride] + 2) >> 2; | predict[3] = (left[-stride] + 2 * left[0] + | |||
| predict += stride; | left[stride] + 2) >> 2; | |||
| left += stride; | predict += stride; | |||
| left += stride; | ||||
| predict[0] = | predict[0] = | |||
| predict[1] = | predict[1] = | |||
| predict[2] = | predict[2] = | |||
| predict[3] = (left[-stride] + 2 * left[0] + left[stride] + 2) >> 2; | predict[3] = (left[-stride] + 2 * left[0] + | |||
| predict += stride; | left[stride] + 2) >> 2; | |||
| left += stride; | predict += stride; | |||
| left += stride; | ||||
| predict[0] = | predict[0] = | |||
| predict[1] = | predict[1] = | |||
| predict[2] = | predict[2] = | |||
| predict[3] = (left[-stride] + 2 * left[0] + left[0] + 2) >> 2; | predict[3] = (left[-stride] + 2 * left[0] + left[0] + 2) >> 2; | |||
| } | } | |||
| static void | static void | |||
| predict_ld_4x4(unsigned char *predict, | predict_ld_4x4(unsigned char *predict, | |||
| int stride) | int stride) | |||
| { | { | |||
| unsigned char *above = predict - stride; | unsigned char *above = predict - stride; | |||
| int pred0, pred1, pred2, pred3, pred4, pred5, pred6; | int pred0, pred1, pred2, pred3, pred4, pred5, pred6; | |||
| predict[0] = pred0 = (above[0] + 2 * above[1] + above[2] + 2) >> 2; | predict[0] = pred0 = (above[0] + 2 * above[1] + | |||
| predict[1] = pred1 = (above[1] + 2 * above[2] + above[3] + 2) >> 2; | above[2] + 2) >> 2; | |||
| predict[2] = pred2 = (above[2] + 2 * above[3] + above[4] + 2) >> 2; | predict[1] = pred1 = (above[1] + 2 * above[2] + | |||
| predict[3] = pred3 = (above[3] + 2 * above[4] + above[5] + 2) >> 2; | above[3] + 2) >> 2; | |||
| predict += stride; | 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[0] = pred1; | |||
| predict[1] = pred2; | predict[1] = pred2; | |||
| predict[2] = pred3; | predict[2] = pred3; | |||
| predict[3] = pred4 = (above[4] + 2 * above[5] + above[6] + 2) >> 2; | predict[3] = pred4 = (above[4] + 2 * above[5] + | |||
| predict += stride; | above[6] + 2) >> 2; | |||
| predict += stride; | ||||
| predict[0] = pred2; | predict[0] = pred2; | |||
| predict[1] = pred3; | predict[1] = pred3; | |||
| predict[2] = pred4; | predict[2] = pred4; | |||
| predict[3] = pred5 = (above[5] + 2 * above[6] + above[7] + 2) >> 2; | predict[3] = pred5 = (above[5] + 2 * above[6] + | |||
| predict += stride; | above[7] + 2) >> 2; | |||
| predict += stride; | ||||
| predict[0] = pred3; | predict[0] = pred3; | |||
| predict[1] = pred4; | predict[1] = pred4; | |||
| predict[2] = pred5; | predict[2] = pred5; | |||
| predict[3] = pred6 = (above[6] + 2 * above[7] + above[7] + 2) >> 2; | predict[3] = pred6 = (above[6] + 2 * above[7] + | |||
| } | above[7] + 2) >> 2; | |||
| 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 = | static void | |||
| (left[ 0] + 2 * above[-1] + above[0] + 2) >> 2; | predict_rd_4x4(unsigned char *predict, | |||
| predict[1] = pred1 = | int stride) | |||
| (above[-1] + 2 * above[ 0] + above[1] + 2) >> 2; | { | |||
| predict[2] = pred2 = | unsigned char *left = predict - 1; | |||
| (above[ 0] + 2 * above[ 1] + above[2] + 2) >> 2; | unsigned char *above = predict - stride; | |||
| predict[3] = pred3 = | int pred0, pred1, pred2, pred3, pred4, pred5, pred6; | |||
| (above[ 1] + 2 * above[ 2] + above[3] + 2) >> 2; | ||||
| predict += stride; | ||||
| predict[0] = pred4 = | predict[0] = pred0 = | |||
| (left[stride] + 2 * left[0] + above[-1] + 2) >> 2; | (left[ 0] + 2 * above[-1] + above[0] + 2) >> 2; | |||
| predict[1] = pred0; | predict[1] = pred1 = | |||
| predict[2] = pred1; | (above[-1] + 2 * above[ 0] + above[1] + 2) >> 2; | |||
| predict[3] = pred2; | predict[2] = pred2 = | |||
| predict += stride; | (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] = pred5 = | predict[0] = pred4 = | |||
| (left[stride*2] + 2 * left[stride] + left[0] + 2) >> 2; | (left[stride] + 2 * left[0] + above[-1] + 2) >> 2; | |||
| predict[1] = pred4; | predict[1] = pred0; | |||
| predict[2] = pred0; | predict[2] = pred1; | |||
| predict[3] = pred1; | predict[3] = pred2; | |||
| predict += stride; | predict += stride; | |||
| predict[0] = pred6 = | predict[0] = pred5 = | |||
| (left[stride*3] + 2 * left[stride*2] + left[stride] + 2) >> 2; | (left[stride*2] + 2 * left[stride] + left[0] + 2) >> 2; | |||
| predict[1] = pred5; | predict[1] = pred4; | |||
| predict[2] = pred4; | predict[2] = pred0; | |||
| predict[3] = pred0; | predict[3] = pred1; | |||
| } | predict += stride; | |||
| static void | predict[0] = pred6 = (left[stride*3] + 2 * left[stride*2] + | |||
| predict_vr_4x4(unsigned char *predict, | left[stride] + 2) >> 2; | |||
| int stride) | predict[1] = pred5; | |||
| { | predict[2] = pred4; | |||
| unsigned char *left = predict - 1; | predict[3] = pred0; | |||
| 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; | static void | |||
| predict[1] = pred1 = (above[ 0] + above[1] + 1) >> 1; | predict_vr_4x4(unsigned char *predict, | |||
| predict[2] = pred2 = (above[ 1] + above[2] + 1) >> 1; | int stride) | |||
| predict[3] = pred3 = (above[ 2] + above[3] + 1) >> 1; | { | |||
| predict += stride; | unsigned char *left = predict - 1; | |||
| unsigned char *above = predict - stride; | ||||
| int pred0, pred1, pred2, pred3, pred4, pred5, pred6, | ||||
| pred7, pred8, pred9; | ||||
| predict[0] = pred4 = | predict[0] = pred0 = (above[-1] + above[0] + 1) >> 1; | |||
| (left[ 0] + 2 * above[-1] + above[0] + 2) >> 2; | predict[1] = pred1 = (above[ 0] + above[1] + 1) >> 1; | |||
| predict[1] = pred5 = | predict[2] = pred2 = (above[ 1] + above[2] + 1) >> 1; | |||
| (above[-1] + 2 * above[ 0] + above[1] + 2) >> 2; | predict[3] = pred3 = (above[ 2] + above[3] + 1) >> 1; | |||
| predict[2] = pred6 = | predict += stride; | |||
| (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 = | predict[0] = pred4 = (left[ 0] + 2 * above[-1] + | |||
| (left[stride] + 2 * left[0] + above[-1] + 2) >> 2; | above[0] + 2) >> 2; | |||
| predict[1] = pred0; | predict[1] = pred5 = (above[-1] + 2 * above[ 0] + | |||
| predict[2] = pred1; | above[1] + 2) >> 2; | |||
| predict[3] = pred2; | predict[2] = pred6 = (above[ 0] + 2 * above[ 1] + | |||
| predict += stride; | above[2] + 2) >> 2; | |||
| predict[3] = pred7 = (above[ 1] + 2 * above[ 2] + | ||||
| above[3] + 2) >> 2; | ||||
| predict += stride; | ||||
| predict[0] = pred9 = | predict[0] = pred8 = | |||
| (left[stride*2] + 2 * left[stride] + left[0] + 2) >> 2; | (left[stride] + 2 * left[0] + above[-1] + 2) >> 2; | |||
| predict[1] = pred4; | predict[1] = pred0; | |||
| predict[2] = pred5; | predict[2] = pred1; | |||
| predict[3] = pred6; | predict[3] = pred2; | |||
| } | predict += stride; | |||
| static void | predict[0] = pred9 = | |||
| predict_vl_4x4(unsigned char *predict, | (left[stride*2] + 2 * left[stride] + left[0] + 2) >> 2; | |||
| int stride) | predict[1] = pred4; | |||
| { | predict[2] = pred5; | |||
| unsigned char *above = predict - stride; | predict[3] = pred6; | |||
| int pred0, pred1, pred2, pred3, pred4, pred5, pred6, | } | |||
| pred7, pred8, pred9; | ||||
| predict[0] = pred0 = (above[0] + above[1] + 1) >> 1; | static void | |||
| predict[1] = pred1 = (above[1] + above[2] + 1) >> 1; | predict_vl_4x4(unsigned char *predict, | |||
| predict[2] = pred2 = (above[2] + above[3] + 1) >> 1; | int stride) | |||
| predict[3] = pred3 = (above[3] + above[4] + 1) >> 1; | { | |||
| predict += stride; | unsigned char *above = predict - stride; | |||
| int pred0, pred1, pred2, pred3, pred4, pred5, pred6, | ||||
| pred7, pred8, pred9; | ||||
| predict[0] = pred4 = | predict[0] = pred0 = (above[0] + above[1] + 1) >> 1; | |||
| (above[0] + 2 * above[1] + above[2] + 2) >> 2; | predict[1] = pred1 = (above[1] + above[2] + 1) >> 1; | |||
| predict[1] = pred5 = | predict[2] = pred2 = (above[2] + above[3] + 1) >> 1; | |||
| (above[1] + 2 * above[2] + above[3] + 2) >> 2; | predict[3] = pred3 = (above[3] + above[4] + 1) >> 1; | |||
| predict[2] = pred6 = | predict += stride; | |||
| (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[0] = pred4 = (above[0] + 2 * above[1] + | |||
| predict[1] = pred2; | above[2] + 2) >> 2; | |||
| predict[2] = pred3; | predict[1] = pred5 = (above[1] + 2 * above[2] + | |||
| predict[3] = pred8 = (above[4] + 2 * above[5] + above[6] + 2) >> 2; | above[3] + 2) >> 2; | |||
| predict += stride; | 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] = pred5; | predict[0] = pred1; | |||
| predict[1] = pred6; | predict[1] = pred2; | |||
| predict[2] = pred7; | predict[2] = pred3; | |||
| predict[3] = pred9 = (above[5] + 2 * above[6] + above[7] + 2) >> 2; | predict[3] = pred8 = (above[4] + 2 * above[5] + | |||
| } | above[6] + 2) >> 2; | |||
| predict += stride; | ||||
| static void | predict[0] = pred5; | |||
| predict_hd_4x4(unsigned char *predict, | predict[1] = pred6; | |||
| int stride) | predict[2] = pred7; | |||
| { | predict[3] = pred9 = (above[5] + 2 * above[6] + | |||
| unsigned char *left = predict - 1; | above[7] + 2) >> 2; | |||
| unsigned char *above = predict - stride; | } | |||
| int pred0, pred1, pred2, pred3, pred4, pred5, pred6, | ||||
| pred7, pred8, pred9; | ||||
| predict[0] = pred0 = | static void | |||
| (left[ 0] + above[-1] + 1) >> 1; | predict_hd_4x4(unsigned char *predict, | |||
| predict[1] = pred1 = | int stride) | |||
| (left[ 0] + 2 * above[-1] + above[0] + 2) >> 2; | { | |||
| predict[2] = pred2 = | unsigned char *left = predict - 1; | |||
| (above[-1] + 2 * above[ 0] + above[1] + 2) >> 2; | unsigned char *above = predict - stride; | |||
| predict[3] = pred3 = | int pred0, pred1, pred2, pred3, pred4, pred5, pred6, | |||
| (above[ 0] + 2 * above[ 1] + above[2] + 2) >> 2; | pred7, pred8, pred9; | |||
| predict += stride; | ||||
| predict[0] = pred4 = | predict[0] = pred0 = (left[ 0] + above[-1] + 1) >> 1; | |||
| (left[stride] + left[0] + 1) >> 1; | predict[1] = pred1 = (left[ 0] + 2 * above[-1] + | |||
| predict[1] = pred5 = | above[0] + 2) >> 2; | |||
| (left[stride] + 2 * left[0] + above[-1] + 2) >> 2; | predict[2] = pred2 = (above[-1] + 2 * above[ 0] + | |||
| predict[2] = pred0; | above[1] + 2) >> 2; | |||
| predict[3] = pred1; | predict[3] = pred3 = (above[ 0] + 2 * above[ 1] + | |||
| predict += stride; | above[2] + 2) >> 2; | |||
| predict += stride; | ||||
| predict[0] = pred6 = | predict[0] = pred4 = (left[stride] + left[0] + 1) >> 1; | |||
| (left[stride*2] + left[stride] + 1) >> 1; | predict[1] = pred5 = (left[stride] + 2 * left[0] + | |||
| predict[1] = pred7 = | above[-1] + 2) >> 2; | |||
| (left[stride*2] + 2 * left[stride] + left[0] + 2) >> 2; | predict[2] = pred0; | |||
| predict[2] = pred4; | predict[3] = pred1; | |||
| predict[3] = pred5; | predict += stride; | |||
| predict += stride; | ||||
| predict[0] = pred8 = | predict[0] = pred6 = (left[stride*2] + left[stride] + 1) >> 1; | |||
| (left[stride*3] + left[stride*2] + 1) >> 1; | predict[1] = pred7 = (left[stride*2] + 2 * left[stride] + | |||
| predict[1] = pred9 = | left[0] + 2) >> 2; | |||
| (left[stride*3] + 2 * left[stride*2] + left[stride] + 2) >> 2; | predict[2] = pred4; | |||
| predict[2] = pred6; | predict[3] = pred5; | |||
| predict[3] = pred7; | predict += stride; | |||
| } | ||||
| static void | predict[0] = pred8 = (left[stride*3] + left[stride*2] + 1) >> 1; | |||
| predict_hu_4x4(unsigned char *predict, | predict[1] = pred9 = (left[stride*3] + 2 * left[stride*2] + | |||
| int stride) | left[stride] + 2) >> 2; | |||
| { | predict[2] = pred6; | |||
| unsigned char *left = predict - 1; | predict[3] = pred7; | |||
| int pred0, pred1, pred2, pred3, pred4, pred5, pred6; | } | |||
| predict[0] = pred0 = | static void | |||
| (left[stride*0] + left[stride*1] + 1) >> 1; | predict_hu_4x4(unsigned char *predict, | |||
| predict[1] = pred1 = | int stride) | |||
| (left[stride*0] + 2 * left[stride*1] + left[stride*2] + 2) >> 2; | { | |||
| predict[2] = pred2 = | unsigned char *left = predict - 1; | |||
| (left[stride*1] + left[stride*2] + 1) >> 1; | int pred0, pred1, pred2, pred3, pred4, pred5, pred6; | |||
| predict[3] = pred3 = | ||||
| (left[stride*1] + 2 * left[stride*2] + left[stride*3] + 2) >> 2; | ||||
| predict += stride; | ||||
| predict[0] = pred2; | predict[0] = pred0 = (left[stride*0] + | |||
| predict[1] = pred3; | left[stride*1] + 1) >> 1; | |||
| predict[2] = pred4 = | predict[1] = pred1 = (left[stride*0] + 2 * left[stride*1] + | |||
| (left[stride*2] + left[stride*3] + 1) >> 1; | left[stride*2] + 2) >> 2; | |||
| predict[3] = pred5 = | predict[2] = pred2 = (left[stride*1] + left[stride*2] + 1) >> 1; | |||
| (left[stride*2] + 2 * left[stride*3] + left[stride*3] + 2) >> 2; | predict[3] = pred3 = (left[stride*1] + 2 * left[stride*2] + | |||
| predict += stride; | left[stride*3] + 2) >> 2; | |||
| predict += stride; | ||||
| predict[0] = pred4; | predict[0] = pred2; | |||
| predict[1] = pred5; | predict[1] = pred3; | |||
| predict[2] = pred6 = left[stride*3]; | predict[2] = pred4 = (left[stride*2] + left[stride*3] + 1) >> 1; | |||
| predict[3] = pred6; | predict[3] = pred5 = (left[stride*2] + 2 * left[stride*3] + | |||
| predict += stride; | left[stride*3] + 2) >> 2; | |||
| predict[0] = pred6; | predict += stride; | |||
| predict[1] = pred6; | ||||
| predict[2] = pred6; | ||||
| predict[3] = pred6; | ||||
| } | ||||
| static void | predict[0] = pred4; | |||
| predict_h_16x16(unsigned char *predict, int stride) | predict[1] = pred5; | |||
| { | predict[2] = pred6 = left[stride*3]; | |||
| predict_h_nxn(predict, stride, 16); | predict[3] = pred6; | |||
| } | predict += stride; | |||
| static void | predict[0] = pred6; | |||
| predict_v_16x16(unsigned char *predict, int stride) | predict[1] = pred6; | |||
| { | predict[2] = pred6; | |||
| predict_v_nxn(predict, stride, 16); | predict[3] = pred6; | |||
| } | } | |||
| static void | static void | |||
| predict_tm_16x16(unsigned char *predict, int stride) | predict_h_16x16(unsigned char *predict, int stride) | |||
| { | { | |||
| predict_tm_nxn(predict, stride, 16); | predict_h_nxn(predict, stride, 16); | |||
| } | } | |||
| static void | static void | |||
| predict_h_8x8(unsigned char *predict, int stride) | predict_v_16x16(unsigned char *predict, int stride) | |||
| { | { | |||
| predict_h_nxn(predict, stride, 8); | predict_v_nxn(predict, stride, 16); | |||
| } | } | |||
| static void | static void | |||
| predict_v_8x8(unsigned char *predict, int stride) | predict_tm_16x16(unsigned char *predict, int stride) | |||
| { | { | |||
| predict_v_nxn(predict, stride, 8); | predict_tm_nxn(predict, stride, 16); | |||
| } | } | |||
| static void | static void | |||
| predict_tm_8x8(unsigned char *predict, int stride) | predict_h_8x8(unsigned char *predict, int stride) | |||
| { | { | |||
| predict_tm_nxn(predict, stride, 8); | predict_h_nxn(predict, stride, 8); | |||
| } | } | |||
| static void | ||||
| predict_tm_4x4(unsigned char *predict, int stride) | ||||
| { | ||||
| predict_tm_nxn(predict, stride, 4); | ||||
| } | ||||
| static void | static void | |||
| copy_down(unsigned char *recon, | predict_v_8x8(unsigned char *predict, int stride) | |||
| int stride) | { | |||
| { | predict_v_nxn(predict, stride, 8); | |||
| /* Copy the four pixels above-right of subblock 3 to | } | |||
| * above-right of subblocks 7, 11, and 15 | static void | |||
| */ | predict_tm_8x8(unsigned char *predict, int stride) | |||
| uint32_t tmp, *copy = (void *)(recon + 16 - stride); | { | |||
| predict_tm_nxn(predict, stride, 8); | ||||
| } | ||||
| stride = stride / sizeof(unsigned int); | static void | |||
| tmp = *copy; | predict_tm_4x4(unsigned char *predict, int stride) | |||
| copy += stride * 4; | { | |||
| *copy = tmp; | predict_tm_nxn(predict, stride, 4); | |||
| copy += stride * 4; | } | |||
| *copy = tmp; | ||||
| copy += stride * 4; | ||||
| *copy = tmp; | ||||
| } | ||||
| static void | static void | |||
| b_pred(unsigned char *predict, | copy_down(unsigned char *recon, | |||
| int stride, | int stride) | |||
| struct mb_info *mbi, | { | |||
| short *coeffs) | /* Copy the four pixels above-right of subblock 3 to | |||
| { | * above-right of subblocks 7, 11, and 15 | |||
| int i; | */ | |||
| uint32_t tmp, *copy = (void *)(recon + 16 - stride); | ||||
| copy_down(predict, stride); | stride = stride / sizeof(unsigned int); | |||
| tmp = *copy; | ||||
| copy += stride * 4; | ||||
| *copy = tmp; | ||||
| copy += stride * 4; | ||||
| *copy = tmp; | ||||
| copy += stride * 4; | ||||
| *copy = tmp; | ||||
| } | ||||
| for (i = 0; i < 16; i++) | static void | |||
| { | b_pred(unsigned char *predict, | |||
| unsigned char *b_predict = predict + (i & 3) * 4; | int stride, | |||
| struct mb_info *mbi, | ||||
| short *coeffs) | ||||
| { | ||||
| int i; | ||||
| switch (mbi->split.modes[i]) | copy_down(predict, stride); | |||
| { | ||||
| 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; | ||||
| 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); | for (i = 0; i < 16; i++) | |||
| coeffs += 16; | { | |||
| 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; | ||||
| 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); | ||||
| } | ||||
| if ((i & 3) == 3) | vp8_dixie_idct_add(b_predict, b_predict, stride, coeffs); | |||
| { | coeffs += 16; | |||
| predict += stride * 4; | ||||
| } | ||||
| } | ||||
| } | ||||
| static void | if ((i & 3) == 3) | |||
| fixup_dc_coeffs(struct mb_info *mbi, | { | |||
| short *coeffs) | predict += stride * 4; | |||
| { | } | |||
| short y2[16]; | } | |||
| int i; | } | |||
| vp8_dixie_walsh(coeffs + 24 * 16, y2); | static void | |||
| for (i = 0; i < 16; i++) | fixup_dc_coeffs(struct mb_info *mbi, | |||
| coeffs[i*16] = y2[i]; | short *coeffs) | |||
| } | { | |||
| short y2[16]; | ||||
| int i; | ||||
| static void | vp8_dixie_walsh(coeffs + 24 * 16, y2); | |||
| 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 | ||||
| { | ||||
| int i; | ||||
| switch (mbi->base.y_mode) | for (i = 0; i < 16; i++) | |||
| { | coeffs[i*16] = y2[i]; | |||
| 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); | 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 | ||||
| { | ||||
| int i; | ||||
| for (i = 0; i < 16; i++) | switch (mbi->base.y_mode) | |||
| { | { | |||
| vp8_dixie_idct_add(predict, predict, stride, coeffs); | case DC_PRED: | |||
| coeffs += 16; | predict_dc_nxn(predict, stride, 16); | |||
| predict += 4; | 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); | ||||
| } | ||||
| if ((i & 3) == 3) | fixup_dc_coeffs(mbi, coeffs); | |||
| predict += stride * 4 - 16; | ||||
| } | ||||
| } | 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; | ||||
| switch (mbi->base.uv_mode) | static void | |||
| { | predict_intra_chroma(unsigned char *predict_u, | |||
| case DC_PRED: | unsigned char *predict_v, | |||
| predict_dc_nxn(predict_u, stride, 8); | int stride, | |||
| predict_dc_nxn(predict_v, stride, 8); | struct mb_info *mbi, | |||
| break; | short *coeffs) | |||
| case V_PRED: | { | |||
| predict_v_8x8(predict_u, stride); | int i; | |||
| 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; | 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); | ||||
| } | ||||
| for (i = 16; i < 20; i++) | coeffs += 16 * 16; | |||
| { | ||||
| vp8_dixie_idct_add(predict_u, predict_u, stride, coeffs); | ||||
| coeffs += 16; | ||||
| predict_u += 4; | ||||
| if (i & 1) | for (i = 16; i < 20; i++) | |||
| predict_u += stride * 4 - 8; | { | |||
| } | vp8_dixie_idct_add(predict_u, predict_u, stride, coeffs); | |||
| coeffs += 16; | ||||
| predict_u += 4; | ||||
| for (i = 20; i < 24; i++) | if (i & 1) | |||
| { | predict_u += stride * 4 - 8; | |||
| vp8_dixie_idct_add(predict_v, predict_v, stride, coeffs); | } | |||
| coeffs += 16; | ||||
| predict_v += 4; | ||||
| if (i & 1) | for (i = 20; i < 24; i++) | |||
| predict_v += stride * 4 - 8; | { | |||
| } | vp8_dixie_idct_add(predict_v, predict_v, stride, coeffs); | |||
| coeffs += 16; | ||||
| predict_v += 4; | ||||
| } | if (i & 1) | |||
| predict_v += stride * 4 - 8; | ||||
| } | ||||
| static void | } | |||
| sixtap_horiz(unsigned char *output, | ||||
| 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++) | ||||
| { | ||||
| 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, | int output_stride, | |||
| const unsigned char *reference, | const unsigned char *reference, | |||
| int reference_stride, | int reference_stride, | |||
| int cols, | int cols, | |||
| int rows, | int rows, | |||
| const filter_t filter | int mx, | |||
| int my, | ||||
| const filter_t filters[8] | ||||
| ) | ) | |||
| { | { | |||
| int r, c, temp; | DECLARE_ALIGNED(16, unsigned char, temp[16*(16+5)]); | |||
| 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++) | sixtap_horiz(temp, 16, | |||
| { | reference - 2 * reference_stride, reference_stride, | |||
| for (c = 0; c < cols; c++) | cols, rows + 5, filters[mx]); | |||
| { | sixtap_vert(output, output_stride, | |||
| temp = (reference[-2*reference_stride] * filter[0]) + | temp + 2 * 16, 16, | |||
| (reference[-1*reference_stride] * filter[1]) + | cols, rows, filters[my]); | |||
| (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; | struct img_index | |||
| output += output_stride; | { | |||
| } | unsigned char *y, *u, *v; | |||
| } | int stride, uv_stride; | |||
| }; | ||||
| static void | static const unsigned char * | |||
| sixtap_2d(unsigned char *output, | filter_block(unsigned char *output, | |||
| int output_stride, | const unsigned char *reference, | |||
| const unsigned char *reference, | int stride, | |||
| int reference_stride, | const union mv *mv, | |||
| int cols, | const filter_t filters[8]) | |||
| int rows, | { | |||
| int mx, | int mx, my; | |||
| int my, | ||||
| const filter_t filters[8] | ||||
| ) | ||||
| { | ||||
| DECLARE_ALIGNED(16, unsigned char, temp[16*(16+5)]); | ||||
| sixtap_horiz(temp, 16, | /* Handle 0,0 as a special case. TODO: does this make it any | |||
| reference - 2 * reference_stride, reference_stride, | * faster? | |||
| cols, rows + 5, filters[mx]); | */ | |||
| if (!mv->raw) | ||||
| return reference; | ||||
| sixtap_vert(output, output_stride, | mx = mv->d.x & 7; | |||
| temp + 2 * 16, 16, | my = mv->d.y & 7; | |||
| cols, rows, filters[my]); | reference += ((mv->d.y >> 3) * stride) + (mv->d.x >> 3); | |||
| } | ||||
| struct img_index | if (mx | my) | |||
| { | { | |||
| unsigned char *y, *u, *v; | sixtap_2d(output, stride, reference, stride, 4, 4, mx, my, | |||
| int stride, uv_stride; | filters); | |||
| }; | reference = output; | |||
| } | ||||
| static const unsigned char * | return reference; | |||
| 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; | static void | |||
| my = mv->d.y & 7; | recon_1_block(unsigned char *output, | |||
| reference += ((mv->d.y >> 3) * stride) + (mv->d.x >> 3); | 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; | ||||
| if (mx | my) | predict = filter_block(output, reference, stride, mv, filters); | |||
| { | vp8_dixie_idct_add(output, predict, stride, coeffs + 16 * b); | |||
| sixtap_2d(output, stride, reference, stride, 4, 4, mx, my, | } | |||
| filters); | ||||
| reference = output; | ||||
| } | ||||
| return reference; | static mv_t | |||
| } | calculate_chroma_splitmv(struct mb_info *mbi, | |||
| int b, | ||||
| int full_pixel) | ||||
| { | ||||
| int temp; | ||||
| union mv mv; | ||||
| static void | temp = mbi->split.mvs[b].d.x + | |||
| recon_1_block(unsigned char *output, | mbi->split.mvs[b+1].d.x + | |||
| const unsigned char *reference, | mbi->split.mvs[b+4].d.x + | |||
| int stride, | mbi->split.mvs[b+5].d.x; | |||
| 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); | if (temp < 0) | |||
| vp8_dixie_idct_add(output, predict, stride, coeffs + 16 * b); | temp -= 4; | |||
| } | else | |||
| temp += 4; | ||||
| static mv_t | mv.d.x = temp / 8; | |||
| calculate_chroma_splitmv(struct mb_info *mbi, | ||||
| int b, | ||||
| int full_pixel) | ||||
| { | ||||
| int temp; | ||||
| union mv mv; | ||||
| temp = mbi->split.mvs[b].d.x + | temp = mbi->split.mvs[b].d.y + | |||
| mbi->split.mvs[b+1].d.x + | mbi->split.mvs[b+1].d.y + | |||
| mbi->split.mvs[b+4].d.x + | mbi->split.mvs[b+4].d.y + | |||
| mbi->split.mvs[b+5].d.x; | mbi->split.mvs[b+5].d.y; | |||
| if (temp < 0) | if (temp < 0) | |||
| temp -= 4; | temp -= 4; | |||
| else | ||||
| temp += 4; | ||||
| mv.d.x = temp / 8; | else | |||
| temp += 4; | ||||
| temp = mbi->split.mvs[b].d.y + | mv.d.y = temp / 8; | |||
| mbi->split.mvs[b+1].d.y + | ||||
| mbi->split.mvs[b+4].d.y + | ||||
| mbi->split.mvs[b+5].d.y; | ||||
| if (temp < 0) | if (full_pixel) | |||
| temp -= 4; | { | |||
| else | mv.d.x &= ~7; | |||
| temp += 4; | mv.d.y &= ~7; | |||
| } | ||||
| mv.d.y = temp / 8; | return mv; | |||
| } | ||||
| if (full_pixel) | /* Note: We rely on the reconstructed border having the same stride | |||
| { | * as the reference buffer because the filter_block can't adjust the | |||
| mv.d.x &= ~7; | * stride with its return value, only the reference pointer. | |||
| mv.d.y &= ~7; | */ | |||
| } | 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; | ||||
| return mv; | /* Get a pointer to the start of the real data for this row */ | |||
| } | ref_row = src - x - y * stride; | |||
| /* Note: We rely on the reconstructed border having the same stride as | if (y >= h) | |||
| * the reference buffer because the filter_block can't adjust the | ref_row += (h - 1) * stride; | |||
| * stride with its return value, only the reference pointer. | else if (y > 0) | |||
| */ | ref_row += y * stride; | |||
| 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 */ | do | |||
| ref_row = src - x - y * stride; | { | |||
| int left, right = 0, copy; | ||||
| if (y >= h) | left = x < 0 ? -x : 0; | |||
| ref_row += (h - 1) * stride; | if (left > b_w) | |||
| else if (y > 0) | left = b_w; | |||
| ref_row += y * stride; | ||||
| do | if (x + b_w > w) | |||
| { | right = x + b_w - w; | |||
| int left, right = 0, copy; | ||||
| left = x < 0 ? -x : 0; | if (right > b_w) | |||
| right = b_w; | ||||
| if (left > b_w) | copy = b_w - left - right; | |||
| left = b_w; | ||||
| if (x + b_w > w) | if (left) | |||
| right = x + b_w - w; | memset(dst, ref_row[0], left); | |||
| if (right > b_w) | if (copy) | |||
| right = b_w; | memcpy(dst + left, ref_row + x + left, copy); | |||
| copy = b_w - left - right; | if (right) | |||
| memset(dst + left + copy, ref_row[w-1], right); | ||||
| if (left) | dst += stride; | |||
| memset(dst, ref_row[0], left); | y++; | |||
| if (copy) | if (y < h && y > 0) | |||
| memcpy(dst + left, ref_row + x + left, copy); | ref_row += stride; | |||
| } | ||||
| while (--b_h); | ||||
| } | ||||
| if (right) | static void | |||
| memset(dst + left + copy, ref_row[w-1], right); | 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; | ||||
| dst += stride; | x += mv->d.x >> 3; | |||
| y++; | y += mv->d.y >> 3; | |||
| if (y < h && y > 0) | /* Need two pixels left/above, 3 right/below for 6-tap */ | |||
| ref_row += stride; | if (x < 2 || x + b_w - 1 + 3 >= w || y < 2 || | |||
| } | y + b_h - 1 + 3 >= h) | |||
| while (--b_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; | ||||
| } | ||||
| static void | predict = filter_block(output, reference, stride, mv, filters); | |||
| recon_1_edge_block(unsigned char *output, | vp8_dixie_idct_add(output, predict, stride, coeffs + 16 * b); | |||
| 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; | static void | |||
| y += mv->d.y >> 3; | 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; | ||||
| /* Need two pixels left/above, 3 right/below for 6-tap */ | x = mb_col * 16; | |||
| if (x < 2 || x + b_w - 1 + 3 >= w || y < 2 || y + b_h - 1 + 3 >= h) | y = mb_row * 16; | |||
| { | w = ctx->mb_cols * 16; | |||
| reference += (mv->d.x >> 3) + (mv->d.y >> 3) * stride; | h = ctx->mb_rows * 16; | |||
| build_mc_border(emul_block, | output = img->y; | |||
| reference - 2 - 2 * stride, stride, | reference_offset = ctx->ref_frame_offsets[mbi->base.ref_frame]; | |||
| x - 2, y - 2, b_w + 5, b_h + 5, w, h); | reference = output + reference_offset; | |||
| reference = emul_block + 2 * stride + 2; | ||||
| reference -= (mv->d.x >> 3) + (mv->d.y >> 3) * stride; | ||||
| } | ||||
| predict = filter_block(output, reference, stride, mv, filters); | if (mbi->base.y_mode != SPLITMV) | |||
| vp8_dixie_idct_add(output, predict, stride, coeffs + 16 * b); | { | |||
| } | union mv uvmv; | |||
| static void | uvmv = mbi->base.mv; | |||
| predict_inter_emulated_edge(struct vp8_decoder_ctx *ctx, | uvmv.d.x = (uvmv.d.x + 1 + (uvmv.d.x >> 31) * 2) / 2; | |||
| struct img_index *img, | uvmv.d.y = (uvmv.d.y + 1 + (uvmv.d.y >> 31) * 2) / 2; | |||
| 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; | if (full_pixel) | |||
| y = mb_row * 16; | { | |||
| w = ctx->mb_cols * 16; | uvmv.d.x &= ~7; | |||
| h = ctx->mb_rows * 16; | uvmv.d.y &= ~7; | |||
| output = img->y; | } | |||
| reference_offset = ctx->ref_frame_offsets[mbi->base.ref_frame]; | ||||
| reference = output + reference_offset; | ||||
| if (mbi->base.y_mode != SPLITMV) | chroma_mv[0] = uvmv; | |||
| { | chroma_mv[1] = uvmv; | |||
| union mv 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); | ||||
| } | ||||
| uvmv = mbi->base.mv; | /* Luma */ | |||
| uvmv.d.x = (uvmv.d.x + 1 + (uvmv.d.x >> 31) * 2) / 2; | for (b = 0; b < 16; b++) | |||
| uvmv.d.y = (uvmv.d.y + 1 + (uvmv.d.y >> 31) * 2) / 2; | { | |||
| union mv *ymv; | ||||
| if (full_pixel) | if (mbi->base.y_mode != SPLITMV) | |||
| { | ymv = &mbi->base.mv; | |||
| uvmv.d.x &= ~7; | else | |||
| uvmv.d.y &= ~7; | ymv = mbi->split.mvs + b; | |||
| } | ||||
| chroma_mv[0] = uvmv; | recon_1_edge_block(output, emul_block, reference, | |||
| chroma_mv[1] = uvmv; | img->stride, ymv, ctx->subpixel_filters, coeffs, | |||
| chroma_mv[2] = uvmv; | mbi, x, y, w, h, b); | |||
| 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 */ | x += 4; | |||
| for (b = 0; b < 16; b++) | output += 4; | |||
| { | reference += 4; | |||
| union mv *ymv; | ||||
| if (mbi->base.y_mode != SPLITMV) | if ((b & 3) == 3) | |||
| ymv = &mbi->base.mv; | { | |||
| else | x -= 16; | |||
| ymv = mbi->split.mvs + b; | y += 4; | |||
| output += 4 * img->stride - 16; | ||||
| reference += 4 * img->stride - 16; | ||||
| } | ||||
| } | ||||
| recon_1_edge_block(output, emul_block, reference, img->stride, | x = mb_col * 16; | |||
| ymv, ctx->subpixel_filters, | y = mb_row * 16; | |||
| coeffs, mbi, x, y, w, h, b); | ||||
| x += 4; | /* Chroma */ | |||
| output += 4; | x >>= 1; | |||
| reference += 4; | y >>= 1; | |||
| w >>= 1; | ||||
| h >>= 1; | ||||
| if ((b & 3) == 3) | for (b = 0; b < 4; b++) | |||
| { | { | |||
| x -= 16; | recon_1_edge_block(u, emul_block, u + reference_offset, | |||
| y += 4; | img->uv_stride, | |||
| output += 4 * img->stride - 16; | &chroma_mv[b], ctx->subpixel_filters, | |||
| reference += 4 * img->stride - 16; | coeffs, mbi, x, y, w, h, b + 16); | |||
| } | recon_1_edge_block(v, emul_block, v + reference_offset, | |||
| } | img->uv_stride, | |||
| x = mb_col * 16; | &chroma_mv[b], ctx->subpixel_filters, | |||
| y = mb_row * 16; | coeffs, mbi, x, y, w, h, b + 20); | |||
| u += 4; | ||||
| v += 4; | ||||
| x += 4; | ||||
| /* Chroma */ | if (b & 1) | |||
| x >>= 1; | { | |||
| y >>= 1; | x -= 8; | |||
| w >>= 1; | y += 4; | |||
| h >>= 1; | u += 4 * img->uv_stride - 8; | |||
| v += 4 * img->uv_stride - 8; | ||||
| } | ||||
| } | ||||
| 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) | static void | |||
| { | predict_inter(struct vp8_decoder_ctx *ctx, | |||
| x -= 8; | struct img_index *img, | |||
| y += 4; | short *coeffs, | |||
| u += 4 * img->uv_stride - 8; | struct mb_info *mbi) | |||
| v += 4 * img->uv_stride - 8; | { | |||
| } | 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; | ||||
| static void | uvmv = mbi->base.mv; | |||
| predict_inter(struct vp8_decoder_ctx *ctx, | uvmv.d.x = (uvmv.d.x + 1 + (uvmv.d.x >> 31) * 2) / 2; | |||
| struct img_index *img, | uvmv.d.y = (uvmv.d.y + 1 + (uvmv.d.y >> 31) * 2) / 2; | |||
| short *coeffs, | ||||
| struct mb_info *mbi) | ||||
| { | ||||
| 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; | if (full_pixel) | |||
| 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; | uvmv.d.x &= ~7; | |||
| uvmv.d.y &= ~7; | ||||
| } | ||||
| if (full_pixel) | chroma_mv[0] = | |||
| { | chroma_mv[1] = | |||
| uvmv.d.x &= ~7; | chroma_mv[2] = | |||
| uvmv.d.y &= ~7; | 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); | ||||
| } | ||||
| chroma_mv[0] = | reference_offset = ctx->ref_frame_offsets[mbi->base.ref_frame]; | |||
| 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; | ||||
| for (b = 0; b < 16; b++) | if (mbi->base.y_mode != SPLITMV) | |||
| { | ymv = &mbi->base.mv; | |||
| union mv *ymv; | else | |||
| ymv = mbi->split.mvs + b; | ||||
| if (mbi->base.y_mode != SPLITMV) | recon_1_block(y, y + reference_offset, img->stride, | |||
| ymv = &mbi->base.mv; | ymv, ctx->subpixel_filters, coeffs, mbi, b); | |||
| else | y += 4; | |||
| ymv = mbi->split.mvs + b; | ||||
| recon_1_block(y, y + reference_offset, img->stride, | if ((b & 3) == 3) | |||
| ymv, ctx->subpixel_filters, coeffs, mbi, b); | y += 4 * img->stride - 16; | |||
| y += 4; | } | |||
| if ((b & 3) == 3) | for (b = 0; b < 4; b++) | |||
| y += 4 * img->stride - 16; | { | |||
| } | 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; | ||||
| for (b = 0; b < 4; b++) | if (b & 1) | |||
| { | { | |||
| recon_1_block(u, u + reference_offset, | u += 4 * img->uv_stride - 8; | |||
| img->uv_stride, &chroma_mv[b], | v += 4 * img->uv_stride - 8; | |||
| 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) | void | |||
| { | vp8_dixie_release_ref_frame(struct ref_cnt_img *rcimg) | |||
| u += 4 * img->uv_stride - 8; | { | |||
| v += 4 * img->uv_stride - 8; | if (rcimg) | |||
| } | { | |||
| } | assert(rcimg->ref_cnt); | |||
| } | rcimg->ref_cnt--; | |||
| } | ||||
| } | ||||
| void | struct ref_cnt_img * | |||
| vp8_dixie_release_ref_frame(struct ref_cnt_img *rcimg) | vp8_dixie_ref_frame(struct ref_cnt_img *rcimg) | |||
| { | { | |||
| if (rcimg) | rcimg->ref_cnt++; | |||
| { | return rcimg; | |||
| assert(rcimg->ref_cnt); | } | |||
| rcimg->ref_cnt--; | ||||
| } | ||||
| } | ||||
| struct ref_cnt_img * | struct ref_cnt_img * | |||
| vp8_dixie_ref_frame(struct ref_cnt_img *rcimg) | vp8_dixie_find_free_ref_frame(struct ref_cnt_img *frames) | |||
| { | { | |||
| rcimg->ref_cnt++; | int i; | |||
| return rcimg; | ||||
| } | ||||
| struct ref_cnt_img * | for (i = 0; i < NUM_REF_FRAMES; i++) | |||
| vp8_dixie_find_free_ref_frame(struct ref_cnt_img *frames) | if (frames[i].ref_cnt == 0) | |||
| { | { | |||
| int i; | frames[i].ref_cnt = 1; | |||
| return &frames[i]; | ||||
| } | ||||
| for (i = 0; i < NUM_REF_FRAMES; i++) | assert(0); | |||
| if (frames[i].ref_cnt == 0) | return NULL; | |||
| { | } | |||
| frames[i].ref_cnt = 1; | ||||
| return &frames[i]; | ||||
| } | 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; | ||||
| assert(0); | if (mode == DC_PRED && row) | |||
| return NULL; | { | |||
| } | unsigned char *above = predict - stride; | |||
| static void | for (i = 0; i < width; i++) | |||
| fixup_left(unsigned char *predict, | { | |||
| int width, | *left = above[i]; | |||
| int stride, | left += stride; | |||
| unsigned int row, | } | |||
| enum prediction_mode mode) | } | |||
| { | else | |||
| /* 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 | /* Need to re-set the above row, in case the above MB was | |||
| * above row, unless this is also row 0, in which case we use | * DC_PRED. | |||
| * 129. | */ | |||
| */ | left -= stride; | |||
| unsigned char *left = predict - 1; | for (i = -1; i < width; i++) | |||
| int i; | { | |||
| *left = 129; | ||||
| left += stride; | ||||
| } | ||||
| } | ||||
| } | ||||
| if (mode == DC_PRED && row) | static void | |||
| { | fixup_above(unsigned char *predict, | |||
| unsigned char *above = predict - stride; | 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; | ||||
| for (i = 0; i < width; i++) | if (mode == DC_PRED && col) | |||
| { | { | |||
| *left = above[i]; | unsigned char *left = predict - 1; | |||
| left += stride; | ||||
| } | ||||
| } | ||||
| else | ||||
| { | ||||
| /* Need to re-set the above row, in case the above MB was | ||||
| * DC_PRED. | ||||
| */ | ||||
| left -= stride; | ||||
| for (i = -1; i < width; i++) | for (i = 0; i < width; i++) | |||
| { | { | |||
| *left = 129; | above[i] = *left; | |||
| left += stride; | left += stride; | |||
| } | } | |||
| } | } | |||
| } | else | |||
| static void | /* Need to re-set the left col, in case the last MB was | |||
| fixup_above(unsigned char *predict, | * DC_PRED. | |||
| int width, | */ | |||
| int stride, | memset(above - 1, 127, width + 1); | |||
| 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) | memset(above + width, 127, 4); // for above-right subblock modes | |||
| { | } | |||
| unsigned char *left = predict - 1; | ||||
| for (i = 0; i < width; i++) | void | |||
| { | vp8_dixie_predict_init(struct vp8_decoder_ctx *ctx) | |||
| above[i] = *left; | { | |||
| left += stride; | int i; | |||
| } | unsigned char *this_frame_base; | |||
| } | ||||
| 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 | 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; | ||||
| void | vpx_img_free(&ctx->frame_strg[i].img); | |||
| vp8_dixie_predict_init(struct vp8_decoder_ctx *ctx) | ctx->frame_strg[i].ref_cnt = 0; | |||
| { | ctx->ref_frames[i] = NULL; | |||
| int i; | if (!vpx_img_alloc(&ctx->frame_strg[i].img, | |||
| unsigned char *this_frame_base; | IMG_FMT_I420, w, h, 16)) | |||
| vpx_internal_error(&ctx->error, VPX_CODEC_MEM_ERROR, | ||||
| "Failed to allocate %dx%d" | ||||
| " framebuffer", | ||||
| w, h); | ||||
| if (ctx->frame_hdr.frame_size_updated) | vpx_img_set_rect(&ctx->frame_strg[i].img, BORDER_PIXELS, | |||
| { | BORDER_PIXELS, ctx->frame_hdr.kf.w, | |||
| for (i = 0; i < NUM_REF_FRAMES; i++) | ctx->frame_hdr.kf.h); | |||
| { | ||||
| 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, | if (ctx->frame_hdr.version) | |||
| BORDER_PIXELS, BORDER_PIXELS, | ctx->subpixel_filters = bilinear_filters; | |||
| ctx->frame_hdr.kf.w, ctx->frame_hdr.kf.h); | 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]); | ||||
| if (ctx->frame_hdr.version) | ctx->ref_frames[CURRENT_FRAME] = | |||
| ctx->subpixel_filters = bilinear_filters; | vp8_dixie_find_free_ref_frame(ctx->frame_strg); | |||
| else | this_frame_base = ctx->ref_frames[CURRENT_FRAME]->img.img_data; | |||
| ctx->subpixel_filters = sixtap_filters; | ||||
| } | ||||
| /* Find a free framebuffer to predict into */ | /* Calculate offsets to the other reference frames */ | |||
| if (ctx->ref_frames[CURRENT_FRAME]) | for (i = 0; i < NUM_REF_FRAMES; i++) | |||
| vp8_dixie_release_ref_frame(ctx->ref_frames[CURRENT_FRAME]); | { | |||
| struct ref_cnt_img *ref = ctx->ref_frames[i]; | ||||
| ctx->ref_frames[CURRENT_FRAME] = | ctx->ref_frame_offsets[i] = | |||
| vp8_dixie_find_free_ref_frame(ctx->frame_strg); | ref ? ref->img.img_data - this_frame_base : 0; | |||
| this_frame_base = ctx->ref_frames[CURRENT_FRAME]->img.img_data; | ||||
| /* 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] = | /* TODO: No need to do this on every frame... */ | |||
| 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; | ||||
| void | for (i = 0; i < NUM_REF_FRAMES; i++) | |||
| vp8_dixie_predict_destroy(struct vp8_decoder_ctx *ctx) | { | |||
| { | vpx_img_free(&ctx->frame_strg[i].img); | |||
| int i; | ctx->frame_strg[i].ref_cnt = 0; | |||
| for (i = 0; i < NUM_REF_FRAMES; i++) | ctx->ref_frames[i] = NULL; | |||
| { | } | |||
| vpx_img_free(&ctx->frame_strg[i].img); | } | |||
| ctx->frame_strg[i].ref_cnt = 0; | ||||
| ctx->ref_frames[i] = NULL; | ||||
| } | ||||
| } | ||||
| void | void | |||
| vp8_dixie_predict_process_row(struct vp8_decoder_ctx *ctx, | vp8_dixie_predict_process_row(struct vp8_decoder_ctx *ctx, | |||
| unsigned int row, | unsigned int row, | |||
| unsigned int start_col, | unsigned int start_col, | |||
| unsigned int num_cols) | unsigned int num_cols) | |||
| { | { | |||
| struct img_index img; | struct img_index img; | |||
| struct mb_info *mbi; | struct mb_info *mbi; | |||
| unsigned int col; | unsigned int col; | |||
| short *coeffs; | short *coeffs; | |||
| /* Adjust pointers based on row, start_col */ | /* Adjust pointers based on row, start_col */ | |||
| img.stride = ctx->ref_frames[CURRENT_FRAME]->img.stride[PLANE_Y]; | img.stride = | |||
| img.uv_stride = ctx->ref_frames[CURRENT_FRAME]->img.stride[PLANE_U]; | ctx->ref_frames[CURRENT_FRAME]->img.stride[PLANE_Y]; | |||
| img.y = ctx->ref_frames[CURRENT_FRAME]->img.planes[PLANE_Y]; | img.uv_stride = | |||
| img.u = ctx->ref_frames[CURRENT_FRAME]->img.planes[PLANE_U]; | ctx->ref_frames[CURRENT_FRAME]->img.stride[PLANE_U]; | |||
| img.v = ctx->ref_frames[CURRENT_FRAME]->img.planes[PLANE_V]; | img.y = ctx->ref_frames[CURRENT_FRAME]->img.planes[PLANE_Y]; | |||
| img.y += (img.stride * row + start_col) * 16; | img.u = ctx->ref_frames[CURRENT_FRAME]->img.planes[PLANE_U]; | |||
| img.u += (img.uv_stride * row + start_col) * 8; | img.v = ctx->ref_frames[CURRENT_FRAME]->img.planes[PLANE_V]; | |||
| img.v += (img.uv_stride * row + start_col) * 8; | img.y += (img.stride * row + start_col) * 16; | |||
| mbi = ctx->mb_info_rows[row] + start_col; | img.u += (img.uv_stride * row + start_col) * 8; | |||
| coeffs = ctx->tokens[row & (ctx->token_hdr.partitions - 1)].coeffs | img.v += (img.uv_stride * row + start_col) * 8; | |||
| + 25 * 16 * start_col; | 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 */ | /* Fix up the out-of-frame pixels */ | |||
| if (start_col == 0) | if (start_col == 0) | |||
| { | { | |||
| fixup_left(img.y, 16, img.stride, row, mbi->base.y_mode); | 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.u, 8, img.uv_stride, row, mbi->base.uv_mode); | |||
| fixup_left(img.v, 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) | if (row == 0) | |||
| *(img.y - img.stride - 1) = 127; | *(img.y - img.stride - 1) = 127; | |||
| } | } | |||
| for (col = start_col; col < start_col + num_cols; col++) | for (col = start_col; col < start_col + num_cols; col++) | |||
| { | { | |||
| if (row == 0) | if (row == 0) | |||
| { | { | |||
| fixup_above(img.y, 16, img.stride, col, mbi->base.y_mode); | fixup_above(img.y, 16, img.stride, col, | |||
| fixup_above(img.u, 8, img.uv_stride, col, | mbi->base.y_mode); | |||
| mbi->base.uv_mode); | fixup_above(img.u, 8, img.uv_stride, col, | |||
| fixup_above(img.v, 8, img.uv_stride, col, | mbi->base.uv_mode); | |||
| mbi->base.uv_mode); | fixup_above(img.v, 8, img.uv_stride, col, | |||
| } | mbi->base.uv_mode); | |||
| } | ||||
| if (mbi->base.y_mode <= B_PRED) | if (mbi->base.y_mode <= B_PRED) | |||
| { | { | |||
| predict_intra_luma(img.y, img.stride, mbi, coeffs); | predict_intra_luma(img.y, img.stride, mbi, coeffs); | |||
| predict_intra_chroma(img.u, img.v, img.uv_stride, mbi, | predict_intra_chroma(img.u, img.v, img.uv_stride, mbi, | |||
| coeffs); | coeffs); | |||
| } | } | |||
| else | else | |||
| { | { | |||
| if (mbi->base.y_mode != SPLITMV) // && != BPRED | if (mbi->base.y_mode != SPLITMV) // && != BPRED | |||
| fixup_dc_coeffs(mbi, coeffs); | fixup_dc_coeffs(mbi, coeffs); | |||
| if (mbi->base.need_mc_border) | if (mbi->base.need_mc_border) | |||
| predict_inter_emulated_edge(ctx, &img, coeffs, mbi, col, | predict_inter_emulated_edge(ctx, &img, coeffs, mbi, | |||
| row); | col, row); | |||
| else | else | |||
| predict_inter(ctx, &img, coeffs, mbi); | predict_inter(ctx, &img, coeffs, mbi); | |||
| } | } | |||
| /* Advance to the next macroblock */ | /* Advance to the next macroblock */ | |||
| mbi++; | mbi++; | |||
| img.y += 16; | img.y += 16; | |||
| img.u += 8; | img.u += 8; | |||
| img.v += 8; | img.v += 8; | |||
| coeffs += 25 * 16; | 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; | ||||
| } | ||||
| } | ||||
| if (col == ctx->mb_cols) | ---- End code block ---------------------------------------- | |||
| { | ||||
| /* 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; | ||||
| } | ||||
| } | ||||
| 20.15. predict.h | 20.15. predict.h | |||
| ---- Begin code block -------------------------------------- | ---- Begin code block -------------------------------------- | |||
| /* | /* | |||
| * Copyright (c) 2010 The VP8 project authors. All Rights Reserved. | * Copyright (c) 2010 The VP8 project authors. All Rights Reserved. | |||
| * | * | |||
| * Use of this source code is governed by a BSD-style license | * 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 | * that can be found in the LICENSE file in the root of the source | |||
| * tree. An additional intellectual property rights grant can be | * tree. An additional intellectual property rights grant can be | |||
| skipping to change at page 238, line 47 ¶ | skipping to change at page 239, line 48 ¶ | |||
| struct ref_cnt_img * | struct ref_cnt_img * | |||
| vp8_dixie_find_free_ref_frame(struct ref_cnt_img *frames); | vp8_dixie_find_free_ref_frame(struct ref_cnt_img *frames); | |||
| #endif | #endif | |||
| ---- End code block ---------------------------------------- | ---- End code block ---------------------------------------- | |||
| 20.16. tokens.c | 20.16. tokens.c | |||
| /* | ---- Begin code block -------------------------------------- | |||
| * Copyright (c) 2010 The VP8 project authors. All Rights Reserved. | /* | |||
| * | * Copyright (c) 2010 The VP8 project authors. 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 | * Use of this source code is governed by a BSD-style license | |||
| * tree. An additional intellectual property rights grant can be | * that can be found in the LICENSE file in the root of the source | |||
| * found in the file PATENTS. All contributing project authors may | * tree. An additional intellectual property rights grant can be | |||
| * be found in the AUTHORS file in the root of the source tree. | * 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 "vpx_codec_internal.h" | |||
| #include "tokens.h" | #include "dixie.h" | |||
| #include <stdlib.h> | #include "tokens.h" | |||
| #include <string.h> | #include <stdlib.h> | |||
| #include <malloc.h> | #include <string.h> | |||
| #include <malloc.h> | ||||
| enum | enum | |||
| { | { | |||
| EOB_CONTEXT_NODE, | EOB_CONTEXT_NODE, | |||
| ZERO_CONTEXT_NODE, | ZERO_CONTEXT_NODE, | |||
| ONE_CONTEXT_NODE, | ONE_CONTEXT_NODE, | |||
| LOW_VAL_CONTEXT_NODE, | LOW_VAL_CONTEXT_NODE, | |||
| TWO_CONTEXT_NODE, | TWO_CONTEXT_NODE, | |||
| THREE_CONTEXT_NODE, | THREE_CONTEXT_NODE, | |||
| HIGH_LOW_CONTEXT_NODE, | HIGH_LOW_CONTEXT_NODE, | |||
| CAT_ONE_CONTEXT_NODE, | CAT_ONE_CONTEXT_NODE, | |||
| CAT_THREEFOUR_CONTEXT_NODE, | CAT_THREEFOUR_CONTEXT_NODE, | |||
| CAT_THREE_CONTEXT_NODE, | CAT_THREE_CONTEXT_NODE, | |||
| CAT_FIVE_CONTEXT_NODE | CAT_FIVE_CONTEXT_NODE | |||
| }; | }; | |||
| enum | enum | |||
| { | { | |||
| ZERO_TOKEN, | ZERO_TOKEN, | |||
| ONE_TOKEN, | ONE_TOKEN, | |||
| TWO_TOKEN, | TWO_TOKEN, | |||
| THREE_TOKEN, | THREE_TOKEN, | |||
| FOUR_TOKEN, | FOUR_TOKEN, | |||
| DCT_VAL_CATEGORY1, | DCT_VAL_CATEGORY1, | |||
| DCT_VAL_CATEGORY2, | DCT_VAL_CATEGORY2, | |||
| DCT_VAL_CATEGORY3, | DCT_VAL_CATEGORY3, | |||
| DCT_VAL_CATEGORY4, | DCT_VAL_CATEGORY4, | |||
| DCT_VAL_CATEGORY5, | DCT_VAL_CATEGORY5, | |||
| DCT_VAL_CATEGORY6, | DCT_VAL_CATEGORY6, | |||
| DCT_EOB_TOKEN, | DCT_EOB_TOKEN, | |||
| MAX_ENTROPY_TOKENS | MAX_ENTROPY_TOKENS | |||
| }; | }; | |||
| struct extrabits | struct extrabits | |||
| { | { | |||
| short min_val; | short min_val; | |||
| short length; | short length; | |||
| unsigned char probs[12]; | unsigned char probs[12]; | |||
| }; | }; | |||
| static const unsigned int left_context_index[25] = | static const unsigned int left_context_index[25] = | |||
| { | { | |||
| 0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3, | 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 | 4, 4, 5, 5, 6, 6, 7, 7, 8 | |||
| }; | }; | |||
| static const unsigned int above_context_index[25] = | static const unsigned int above_context_index[25] = | |||
| { | { | |||
| 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, | 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 | 4, 5, 4, 5, 6, 7, 6, 7, 8 | |||
| }; | }; | |||
| #define X(n) ((n) * PREV_COEF_CONTEXTS * ENTROPY_NODES) | #define X(n) ((n) * PREV_COEF_CONTEXTS * ENTROPY_NODES) | |||
| static const unsigned int bands_x[16] = | static const unsigned int bands_x[16] = | |||
| { | { | |||
| X(0), X(1), X(2), X(3), X(6), X(4), X(5), X(6), | 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) | X(6), X(6), X(6), X(6), X(6), X(6), X(6), X(7) | |||
| }; | }; | |||
| #undef X | #undef X | |||
| static const struct extrabits extrabits[MAX_ENTROPY_TOKENS] = | static const struct extrabits extrabits[MAX_ENTROPY_TOKENS] = | |||
| { | { | |||
| { 0, -1, { 0, 0, 0, 0, 0, 0, | { 0, -1, { 0, 0, 0, 0, 0, 0, | |||
| 0, 0, 0, 0, 0, 0 } }, //ZERO_TOKEN | 0, 0, 0, 0, 0, 0 } }, //ZERO_TOKEN | |||
| { 1, 0, { 0, 0, 0, 0, 0, 0, | { 1, 0, { 0, 0, 0, 0, 0, 0, | |||
| 0, 0, 0, 0, 0, 0 } }, //ONE_TOKEN | 0, 0, 0, 0, 0, 0 } }, //ONE_TOKEN | |||
| { 2, 0, { 0, 0, 0, 0, 0, 0, | { 2, 0, { 0, 0, 0, 0, 0, 0, | |||
| 0, 0, 0, 0, 0, 0 } }, //TWO_TOKEN | 0, 0, 0, 0, 0, 0 } }, //TWO_TOKEN | |||
| { 3, 0, { 0, 0, 0, 0, 0, 0, | { 3, 0, { 0, 0, 0, 0, 0, 0, | |||
| 0, 0, 0, 0, 0, 0 } }, //THREE_TOKEN | 0, 0, 0, 0, 0, 0 } }, //THREE_TOKEN | |||
| { 4, 0, { 0, 0, 0, 0, 0, 0, | { 4, 0, { 0, 0, 0, 0, 0, 0, | |||
| 0, 0, 0, 0, 0, 0 } }, //FOUR_TOKEN | 0, 0, 0, 0, 0, 0 } }, //FOUR_TOKEN | |||
| { 5, 0, { 159, 0, 0, 0, 0, 0, | { 5, 0, {159, 0, 0, 0, 0, 0, | |||
| 0, 0, 0, 0, 0, 0 } }, //DCT_VAL_CATEGORY1 | 0, 0, 0, 0, 0, 0 } }, //DCT_VAL_CATEGORY1 | |||
| { 7, 1, { 145, 165, 0, 0, 0, 0, | { 7, 1, {145, 165, 0, 0, 0, 0, | |||
| 0, 0, 0, 0, 0, 0 } }, //DCT_VAL_CATEGORY2 | 0, 0, 0, 0, 0, 0 } }, //DCT_VAL_CATEGORY2 | |||
| { 11, 2, { 140, 148, 173, 0, 0, 0, | {11, 2, {140, 148, 173, 0, 0, 0, | |||
| 0, 0, 0, 0, 0, 0 } }, //DCT_VAL_CATEGORY3 | 0, 0, 0, 0, 0, 0 } }, //DCT_VAL_CATEGORY3 | |||
| { 19, 3, { 135, 140, 155, 176, 0, 0, | {19, 3, {135, 140, 155, 176, 0, 0, | |||
| 0, 0, 0, 0, 0, 0 } }, //DCT_VAL_CATEGORY4 | 0, 0, 0, 0, 0, 0 } }, //DCT_VAL_CATEGORY4 | |||
| { 35, 4, { 130, 134, 141, 157, 180, 0, | {35, 4, {130, 134, 141, 157, 180, 0, | |||
| 0, 0, 0, 0, 0, 0 } }, //DCT_VAL_CATEGORY5 | 0, 0, 0, 0, 0, 0 } }, //DCT_VAL_CATEGORY5 | |||
| { 67, 10, { 129, 130, 133, 140, 153, 177, | {67, 10, {129, 130, 133, 140, 153, 177, | |||
| 196, 230, 243, 254, 254, 0 } }, //DCT_VAL_CATEGORY6 | 196, 230, 243, 254, 254, 0 } }, //DCT_VAL_CATEGORY6 | |||
| { 0, -1, { 0, 0, 0, 0, 0, 0, | { 0, -1, { 0, 0, 0, 0, 0, 0, | |||
| 0, 0, 0, 0, 0, 0 } }, // EOB TOKEN | 0, 0, 0, 0, 0, 0 } }, // EOB TOKEN | |||
| }; | }; | |||
| static const unsigned int zigzag[16] = | static const unsigned int zigzag[16] = | |||
| { | { | |||
| 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 | 0, 1, 4, 8, 5, 2, 3, 6, 9, 12, 13, 10, 7, 11, 14, 15 | |||
| }; | }; | |||
| #define DECODE_AND_APPLYSIGN(value_to_sign) \ | #define DECODE_AND_APPLYSIGN(value_to_sign) \ | |||
| v = (bool_get_bit(bool) ? -value_to_sign \ | v = (bool_get_bit(bool) ? -value_to_sign \ | |||
| : value_to_sign) * dqf[!!c]; | : value_to_sign) * dqf[!!c]; | |||
| #define DECODE_AND_BRANCH_IF_ZERO(probability,branch) \ | #define DECODE_AND_BRANCH_IF_ZERO(probability,branch) \ | |||
| if (!bool_get(bool, probability)) goto branch; | if (!bool_get(bool, probability)) goto branch; | |||
| #define DECODE_AND_LOOP_IF_ZERO(probability,branch) \ | #define DECODE_AND_LOOP_IF_ZERO(probability,branch) \ | |||
| if (!bool_get(bool, probability)) \ | if (!bool_get(bool, probability)) \ | |||
| { \ | { \ | |||
| prob = type_probs; \ | prob = type_probs; \ | |||
| if(c<15) {\ | if(c<15) {\ | |||
| ++c; \ | ++c; \ | |||
| prob += bands_x[c]; \ | prob += bands_x[c]; \ | |||
| goto branch; \ | goto branch; \ | |||
| }\ | }\ | |||
| else \ | else \ | |||
| goto BLOCK_FINISHED; /*for malformed input */\ | goto BLOCK_FINISHED; /* for malformed input */\ | |||
| } | } | |||
| #define DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val) \ | #define DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val) \ | |||
| DECODE_AND_APPLYSIGN(val) \ | DECODE_AND_APPLYSIGN(val) \ | |||
| prob = type_probs + (ENTROPY_NODES*2); \ | prob = type_probs + (ENTROPY_NODES*2); \ | |||
| if(c < 15){\ | if(c < 15){\ | |||
| b_tokens[zigzag[c]] = v; \ | b_tokens[zigzag[c]] = v; \ | |||
| ++c; \ | ++c; \ | |||
| goto DO_WHILE; }\ | goto DO_WHILE; }\ | |||
| b_tokens[zigzag[15]] = v; \ | b_tokens[zigzag[15]] = v; \ | |||
| goto BLOCK_FINISHED; | goto BLOCK_FINISHED; | |||
| #define DECODE_EXTRABIT_AND_ADJUST_VAL(t,bits_count)\ | #define DECODE_EXTRABIT_AND_ADJUST_VAL(t,bits_count)\ | |||
| val += bool_get(bool, extrabits[t].probs[bits_count]) << bits_count; | val += bool_get(bool, extrabits[t].probs[bits_count]) << \ | |||
| bits_count; | ||||
| static int | static int | |||
| decode_mb_tokens(struct bool_decoder *bool, | decode_mb_tokens(struct bool_decoder *bool, | |||
| token_entropy_ctx_t left, | token_entropy_ctx_t left, | |||
| token_entropy_ctx_t above, | token_entropy_ctx_t above, | |||
| short *tokens, | short *tokens, | |||
| enum prediction_mode mode, | enum prediction_mode mode, | |||
| coeff_probs_table_t probs, | coeff_probs_table_t probs, | |||
| short factor[TOKEN_BLOCK_TYPES][2]) | short factor[TOKEN_BLOCK_TYPES][2]) | |||
| { | { | |||
| int i, stop, type; | int i, stop, type; | |||
| int c, t, v; | int c, t, v; | |||
| int val, bits_count; | int val, bits_count; | |||
| int eob_mask; | int eob_mask; | |||
| short *b_tokens; /* tokens for this block */ | short *b_tokens; // tokens for this block | |||
| unsigned char *type_probs; /* probabilities for this block type */ | unsigned char *type_probs; // probabilities for this block type | |||
| unsigned char *prob; | unsigned char *prob; | |||
| short *dqf; | short *dqf; | |||
| eob_mask = 0; | eob_mask = 0; | |||
| if (mode != B_PRED && mode != SPLITMV) | if (mode != B_PRED && mode != SPLITMV) | |||
| { | { | |||
| i = 24; | i = 24; | |||
| stop = 24; | stop = 24; | |||
| type = 1; | type = 1; | |||
| b_tokens = tokens + 24 * 16; | b_tokens = tokens + 24 * 16; | |||
| dqf = factor[TOKEN_BLOCK_Y2]; | dqf = factor[TOKEN_BLOCK_Y2]; | |||
| } | } | |||
| else | else | |||
| { | { | |||
| i = 0; | i = 0; | |||
| stop = 16; | stop = 16; | |||
| type = 3; | type = 3; | |||
| b_tokens = tokens; | b_tokens = tokens; | |||
| dqf = factor[TOKEN_BLOCK_Y1]; | dqf = factor[TOKEN_BLOCK_Y1]; | |||
| } | } | |||
| /* Save a pointer to the coefficient probs for the current type. | /* Save a pointer to the coefficient probs for the current type. | |||
| * Need to repeat this whenever type changes. | * Need to repeat this whenever type changes. | |||
| */ | */ | |||
| type_probs = probs[type][0][0]; | type_probs = probs[type][0][0]; | |||
| BLOCK_LOOP: | BLOCK_LOOP: | |||
| t = left[left_context_index[i]] + above[above_context_index[i]]; | t = left[left_context_index[i]] + above[above_context_index[i]]; | |||
| c = !type; /* all blocks start at 0 except type 0, which starts | c = !type; /* all blocks start at 0 except type 0, which starts | |||
| * at 1. */ | * at 1. */ | |||
| prob = type_probs; | prob = type_probs; | |||
| prob += t * ENTROPY_NODES; | prob += t * ENTROPY_NODES; | |||
| DO_WHILE: | DO_WHILE: | |||
| prob += bands_x[c]; | prob += bands_x[c]; | |||
| DECODE_AND_BRANCH_IF_ZERO(prob[EOB_CONTEXT_NODE], BLOCK_FINISHED); | DECODE_AND_BRANCH_IF_ZERO(prob[EOB_CONTEXT_NODE], | |||
| BLOCK_FINISHED); | ||||
| CHECK_0_: | 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; | ||||
| DECODE_AND_LOOP_IF_ZERO(prob[ZERO_CONTEXT_NODE], CHECK_0_); | do | |||
| DECODE_AND_BRANCH_IF_ZERO(prob[ONE_CONTEXT_NODE], | { | |||
| ONE_CONTEXT_NODE_0_); | DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY6, | |||
| DECODE_AND_BRANCH_IF_ZERO(prob[LOW_VAL_CONTEXT_NODE], | bits_count); | |||
| LOW_VAL_CONTEXT_NODE_0_); | bits_count -- ; | |||
| DECODE_AND_BRANCH_IF_ZERO(prob[HIGH_LOW_CONTEXT_NODE], | } | |||
| HIGH_LOW_CONTEXT_NODE_0_); | while (bits_count >= 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_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val); | |||
| { | ||||
| 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); | ||||
| CAT_FIVE_CONTEXT_NODE_0_: | CAT_THREEFOUR_CONTEXT_NODE_0_: | |||
| val = extrabits[DCT_VAL_CATEGORY5].min_val; | DECODE_AND_BRANCH_IF_ZERO(prob[CAT_THREE_CONTEXT_NODE], | |||
| DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY5, 4); | CAT_THREE_CONTEXT_NODE_0_); | |||
| DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY5, 3); | val = extrabits[DCT_VAL_CATEGORY4].min_val; | |||
| DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY5, 2); | DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY4, 3); | |||
| DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY5, 1); | DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY4, 2); | |||
| DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY5, 0); | DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY4, 1); | |||
| DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val); | DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY4, 0); | |||
| DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val); | ||||
| CAT_THREEFOUR_CONTEXT_NODE_0_: | CAT_THREE_CONTEXT_NODE_0_: | |||
| DECODE_AND_BRANCH_IF_ZERO(prob[CAT_THREE_CONTEXT_NODE], | val = extrabits[DCT_VAL_CATEGORY3].min_val; | |||
| CAT_THREE_CONTEXT_NODE_0_); | DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY3, 2); | |||
| val = extrabits[DCT_VAL_CATEGORY4].min_val; | DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY3, 1); | |||
| DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY4, 3); | DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY3, 0); | |||
| DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY4, 2); | DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val); | |||
| 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_: | HIGH_LOW_CONTEXT_NODE_0_: | |||
| val = extrabits[DCT_VAL_CATEGORY3].min_val; | DECODE_AND_BRANCH_IF_ZERO(prob[CAT_ONE_CONTEXT_NODE], | |||
| DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY3, 2); | CAT_ONE_CONTEXT_NODE_0_); | |||
| 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_: | val = extrabits[DCT_VAL_CATEGORY2].min_val; | |||
| DECODE_AND_BRANCH_IF_ZERO(prob[CAT_ONE_CONTEXT_NODE], | DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY2, 1); | |||
| CAT_ONE_CONTEXT_NODE_0_); | DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY2, 0); | |||
| DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val); | ||||
| val = extrabits[DCT_VAL_CATEGORY2].min_val; | CAT_ONE_CONTEXT_NODE_0_: | |||
| DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY2, 1); | val = extrabits[DCT_VAL_CATEGORY1].min_val; | |||
| DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY2, 0); | DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY1, 0); | |||
| DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val); | DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val); | |||
| CAT_ONE_CONTEXT_NODE_0_: | LOW_VAL_CONTEXT_NODE_0_: | |||
| val = extrabits[DCT_VAL_CATEGORY1].min_val; | DECODE_AND_BRANCH_IF_ZERO(prob[TWO_CONTEXT_NODE], | |||
| DECODE_EXTRABIT_AND_ADJUST_VAL(DCT_VAL_CATEGORY1, 0); | TWO_CONTEXT_NODE_0_); | |||
| DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(val); | DECODE_AND_BRANCH_IF_ZERO(prob[THREE_CONTEXT_NODE], | |||
| THREE_CONTEXT_NODE_0_); | ||||
| DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(4); | ||||
| LOW_VAL_CONTEXT_NODE_0_: | THREE_CONTEXT_NODE_0_: | |||
| DECODE_AND_BRANCH_IF_ZERO(prob[TWO_CONTEXT_NODE], | DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(3); | |||
| 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_: | TWO_CONTEXT_NODE_0_: | |||
| DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(3); | DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(2); | |||
| TWO_CONTEXT_NODE_0_: | ONE_CONTEXT_NODE_0_: | |||
| DECODE_SIGN_WRITE_COEFF_AND_CHECK_EXIT(2); | DECODE_AND_APPLYSIGN(1); | |||
| prob = type_probs + ENTROPY_NODES; | ||||
| ONE_CONTEXT_NODE_0_: | if (c < 15) | |||
| DECODE_AND_APPLYSIGN(1); | { | |||
| prob = type_probs + ENTROPY_NODES; | b_tokens[zigzag[c]] = v; | |||
| ++c; | ||||
| goto DO_WHILE; | ||||
| } | ||||
| if (c < 15) | b_tokens[zigzag[15]] = v; | |||
| { | BLOCK_FINISHED: | |||
| b_tokens[zigzag[c]] = v; | eob_mask |= (c > 1) << i; | |||
| ++c; | t = (c != !type); // any nonzero data? | |||
| goto DO_WHILE; | eob_mask |= t << 31; | |||
| } | ||||
| b_tokens[zigzag[15]] = v; | left[left_context_index[i]] = above[above_context_index[i]] = t; | |||
| BLOCK_FINISHED: | b_tokens += 16; | |||
| eob_mask |= (c > 1) << i; | ||||
| t = (c != !type); // any nonzero data? | ||||
| eob_mask |= t << 31; | ||||
| left[left_context_index[i]] = above[above_context_index[i]] = t; | i++; | |||
| b_tokens += 16; | ||||
| i++; | if (i < stop) | |||
| if (i < stop) | goto BLOCK_LOOP; | |||
| goto BLOCK_LOOP; | ||||
| if (i == 25) | if (i == 25) | |||
| { | { | |||
| type = 0; | type = 0; | |||
| i = 0; | i = 0; | |||
| stop = 16; | stop = 16; | |||
| type_probs = probs[type][0][0]; | type_probs = probs[type][0][0]; | |||
| b_tokens = tokens; | b_tokens = tokens; | |||
| dqf = factor[TOKEN_BLOCK_Y1]; | dqf = factor[TOKEN_BLOCK_Y1]; | |||
| goto BLOCK_LOOP; | goto BLOCK_LOOP; | |||
| } | } | |||
| if (i == 16) | if (i == 16) | |||
| { | { | |||
| type = 2; | type = 2; | |||
| type_probs = probs[type][0][0]; | type_probs = probs[type][0][0]; | |||
| stop = 24; | stop = 24; | |||
| dqf = factor[TOKEN_BLOCK_UV]; | dqf = factor[TOKEN_BLOCK_UV]; | |||
| goto BLOCK_LOOP; | goto BLOCK_LOOP; | |||
| } | } | |||
| return eob_mask; | return eob_mask; | |||
| } | } | |||
| static void | static void | |||
| reset_row_context(token_entropy_ctx_t *left) | reset_row_context(token_entropy_ctx_t *left) | |||
| { | { | |||
| memset(left, 0, sizeof(*left)); | memset(left, 0, sizeof(*left)); | |||
| } | } | |||
| static void | static void | |||
| reset_above_context(token_entropy_ctx_t *above, unsigned int cols) | reset_above_context(token_entropy_ctx_t *above, unsigned int cols) | |||
| { | { | |||
| memset(above, 0, cols * sizeof(*above)); | memset(above, 0, cols * sizeof(*above)); | |||
| } | } | |||
| static void | static void | |||
| reset_mb_context(token_entropy_ctx_t *left, | reset_mb_context(token_entropy_ctx_t *left, | |||
| token_entropy_ctx_t *above, | token_entropy_ctx_t *above, | |||
| enum prediction_mode mode) | enum prediction_mode mode) | |||
| { | { | |||
| /* Reset the macroblock context on the left and right. We have to | /* Reset the macroblock context on the left and right. We have to | |||
| * preserve the context of the second order block if this mode | * preserve the context of the second order block if this mode | |||
| * would not have updated it. | * would not have updated it. | |||
| */ | */ | |||
| memset(left, 0, sizeof((*left)[0]) * 8); | memset(left, 0, sizeof((*left)[0]) * 8); | |||
| memset(above, 0, sizeof((*above)[0]) * 8); | memset(above, 0, sizeof((*above)[0]) * 8); | |||
| if (mode != B_PRED && mode != SPLITMV) | if (mode != B_PRED && mode != SPLITMV) | |||
| { | { | |||
| (*left)[8] = 0; | (*left)[8] = 0; | |||
| (*above)[8] = 0; | (*above)[8] = 0; | |||
| } | } | |||
| } | } | |||
| void | void | |||
| vp8_dixie_tokens_process_row(struct vp8_decoder_ctx *ctx, | vp8_dixie_tokens_process_row(struct vp8_decoder_ctx *ctx, | |||
| unsigned int partition, | unsigned int partition, | |||
| unsigned int row, | unsigned int row, | |||
| unsigned int start_col, | unsigned int start_col, | |||
| unsigned int num_cols) | unsigned int num_cols) | |||
| { | { | |||
| struct token_decoder *tokens = &ctx->tokens[partition]; | struct token_decoder *tokens = &ctx->tokens[partition]; | |||
| short *coeffs = tokens->coeffs + 25 * 16 * start_col; | short coeffs = tokens->coeffs + 25 * 16 * start_col; | |||
| unsigned int col; | unsigned int col; | |||
| token_entropy_ctx_t *above = ctx->above_token_entropy_ctx | token_entropy_ctx_t *above = ctx->above_token_entropy_ctx | |||
| + start_col; | + start_col; | |||
| token_entropy_ctx_t *left = &tokens->left_token_entropy_ctx; | token_entropy_ctx_t *left = &tokens->left_token_entropy_ctx; | |||
| struct mb_info *mbi = ctx->mb_info_rows[row] + start_col; | struct mb_info *mbi = ctx->mb_info_rows[row] + start_col; | |||
| if (row == 0) | if (row == 0) | |||
| reset_above_context(above, num_cols); | reset_above_context(above, num_cols); | |||
| if (start_col == 0) | if (start_col == 0) | |||
| reset_row_context(left); | reset_row_context(left); | |||
| for (col = start_col; col < start_col + num_cols; col++) | for (col = start_col; col < start_col + num_cols; col++) | |||
| { | { | |||
| memset(coeffs, 0, 25 * 16 * sizeof(short)); | memset(coeffs, 0, 25 * 16 * sizeof(short)); | |||
| if (mbi->base.skip_coeff) | if (mbi->base.skip_coeff) | |||
| { | { | |||
| reset_mb_context(left, above, mbi->base.y_mode); | reset_mb_context(left, above, mbi->base.y_mode); | |||
| mbi->base.eob_mask = 0; | mbi->base.eob_mask = 0; | |||
| } | } | |||
| else | else | |||
| { | { | |||
| struct dequant_factors *dqf; | struct dequant_factors *dqf; | |||
| dqf = ctx->dequant_factors + mbi->base.segment_id; | dqf = ctx->dequant_factors + mbi->base.segment_id; | |||
| mbi->base.eob_mask = | mbi->base.eob_mask = | |||
| decode_mb_tokens(&tokens->bool, | decode_mb_tokens(&tokens->bool, | |||
| *left, *above, | *left, *above, | |||
| coeffs, | coeffs, | |||
| mbi->base.y_mode, | mbi->base.y_mode, | |||
| ctx->entropy_hdr.coeff_probs, | ctx->entropy_hdr.coeff_probs, | |||
| dqf->factor); | dqf->factor); | |||
| } | } | |||
| above++; | above++; | |||
| mbi++; | mbi++; | |||
| coeffs += 25 * 16; | coeffs += 25 * 16; | |||
| } | } | |||
| } | } | |||
| void | void | |||
| vp8_dixie_tokens_init(struct vp8_decoder_ctx *ctx) | vp8_dixie_tokens_init(struct vp8_decoder_ctx *ctx) | |||
| { | { | |||
| unsigned int partitions = ctx->token_hdr.partitions; | unsigned int partitions = ctx->token_hdr.partitions; | |||
| if (ctx->frame_hdr.frame_size_updated) | if (ctx->frame_hdr.frame_size_updated) | |||
| { | { | |||
| unsigned int i; | unsigned int i; | |||
| unsigned int coeff_row_sz = | unsigned int coeff_row_sz = | |||
| ctx->mb_cols * 25 * 16 * sizeof(short); | ctx->mb_cols * 25 * 16 * sizeof(short); | |||
| for (i = 0; i < partitions; i++) | for (i = 0; i < partitions; i++) | |||
| { | { | |||
| free(ctx->tokens[i].coeffs); | free(ctx->tokens[i].coeffs); | |||
| ctx->tokens[i].coeffs = memalign(16, coeff_row_sz); | ctx->tokens[i].coeffs = memalign(16, coeff_row_sz); | |||
| if (!ctx->tokens[i].coeffs) | if (!ctx->tokens[i].coeffs) | |||
| vpx_internal_error(&ctx->error, VPX_CODEC_MEM_ERROR, | vpx_internal_error(&ctx->error, VPX_CODEC_MEM_ERROR, | |||
| NULL); | NULL); | |||
| } | } | |||
| free(ctx->above_token_entropy_ctx); | free(ctx->above_token_entropy_ctx); | |||
| ctx->above_token_entropy_ctx = | ctx->above_token_entropy_ctx = | |||
| calloc(ctx->mb_cols, sizeof(*ctx->above_token_entropy_ctx)); | calloc(ctx->mb_cols, | |||
| sizeof(*ctx->above_token_entropy_ctx)); | ||||
| if (!ctx->above_token_entropy_ctx) | if (!ctx->above_token_entropy_ctx) | |||
| vpx_internal_error(&ctx->error, VPX_CODEC_MEM_ERROR, NULL); | vpx_internal_error(&ctx->error, | |||
| } | VPX_CODEC_MEM_ERROR, NULL); | |||
| } | } | |||
| } | ||||
| void | void | |||
| vp8_dixie_tokens_destroy(struct vp8_decoder_ctx *ctx) | vp8_dixie_tokens_destroy(struct vp8_decoder_ctx *ctx) | |||
| { | { | |||
| int i; | int i; | |||
| for (i = 0; i < MAX_PARTITIONS; i++) | for (i = 0; i < MAX_PARTITIONS; i++) | |||
| free(ctx->tokens[i].coeffs); | free(ctx->tokens[i].coeffs); | |||
| free(ctx->above_token_entropy_ctx); | free(ctx->above_token_entropy_ctx); | |||
| } | } | |||
| ---- End code block ---------------------------------------- | ||||
| 20.17. tokens.h | 20.17. tokens.h | |||
| ---- Begin code block -------------------------------------- | ||||
| /* | ||||
| * Copyright (c) 2010 The VP8 project authors. 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, | ||||
| 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_COEF_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 | ||||
| { 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; | ||||
| #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]; | ||||
| 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); | ||||
| 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; | ||||
| 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 nonzero 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; | ||||
| } | ||||
| 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; | ||||
| 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); | ||||
| 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 = | * Copyright (c) 2010 The VP8 project authors. All Rights Reserved. | |||
| calloc(ctx->mb_cols, sizeof(*ctx->above_token_entropy_ctx)); | * | |||
| * 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 | ||||
| if (!ctx->above_token_entropy_ctx) | void | |||
| vpx_internal_error(&ctx->error, VPX_CODEC_MEM_ERROR, NULL); | vp8_dixie_tokens_init(struct vp8_decoder_ctx *ctx); | |||
| } | ||||
| } | ||||
| void | void | |||
| vp8_dixie_tokens_destroy(struct vp8_decoder_ctx *ctx) | vp8_dixie_tokens_destroy(struct vp8_decoder_ctx *ctx); | |||
| { | ||||
| int i; | ||||
| for (i = 0; i < MAX_PARTITIONS; i++) | void | |||
| free(ctx->tokens[i].coeffs); | vp8_dixie_tokens_process_row(struct vp8_decoder_ctx *ctx, | |||
| unsigned int partition, | ||||
| unsigned int row, | ||||
| unsigned int start_col, | ||||
| unsigned int num_cols); | ||||
| free(ctx->above_token_entropy_ctx); | #endif | |||
| } | ||||
| ---- End code block ---------------------------------------- | ||||
| 20.18. vp8_prob_data.h | 20.18. vp8_prob_data.h | |||
| ---- Begin code block -------------------------------------- | ||||
| static const | static const | |||
| unsigned char k_coeff_entropy_update_probs[BLOCK_TYPES][COEF_BANDS] | unsigned char k_coeff_entropy_update_probs[BLOCK_TYPES][COEF_BANDS] | |||
| [PREV_COEF_CONTEXTS] | [PREV_COEF_CONTEXTS] | |||
| [ENTROPY_NODES] = | [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, }, | {255, 255, 255, 255, 255, 255, 255, 255, 255, 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, }, | {176, 246, 255, 255, 255, 255, 255, 255, 255, 255, 255}, | |||
| {223, 241, 252, 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, }, | {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}, | ||||
| }, | ||||
| }, | ||||
| { | ||||
| { | ||||
| {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}, | ||||
| }, | ||||
| { | ||||
| {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, 244, 252, 255, 255, 255, 255, 255, 255, 255, 255, }, | {255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255}, | |||
| {234, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, | {254, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255}, | |||
| {253, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, | {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, | |||
| }, | }, | |||
| { | { | |||
| {255, 246, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, | {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, | |||
| {239, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, | {254, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, | |||
| {254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, | {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, | |||
| }, | }, | |||
| { | { | |||
| {255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, | {255, 255, 255, 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, 255, 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, }, | {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, | |||
| {251, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, | {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, | |||
| {254, 255, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, | {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, | |||
| }, | }, | |||
| { | { | |||
| {255, 254, 253, 255, 254, 255, 255, 255, 255, 255, 255, }, | {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255}, | |||
| {250, 255, 254, 255, 254, 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, }, | {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}, | |||
| { | }, | |||
| { | { | |||
| {217, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, | {255, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255}, | |||
| {225, 252, 241, 253, 255, 255, 254, 255, 255, 255, 255, }, | {246, 253, 253, 255, 255, 255, 255, 255, 255, 255, 255}, | |||
| {234, 250, 241, 250, 253, 255, 253, 254, 255, 255, 255, }, | {252, 254, 251, 254, 254, 255, 255, 255, 255, 255, 255}, | |||
| }, | }, | |||
| { | { | |||
| {255, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, | {255, 254, 252, 255, 255, 255, 255, 255, 255, 255, 255}, | |||
| {223, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, | {248, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255}, | |||
| {238, 253, 254, 254, 255, 255, 255, 255, 255, 255, 255, }, | {253, 255, 254, 254, 255, 255, 255, 255, 255, 255, 255}, | |||
| }, | }, | |||
| { | { | |||
| {255, 248, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, | {255, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255}, | |||
| {249, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, | {245, 251, 254, 255, 255, 255, 255, 255, 255, 255, 255}, | |||
| {255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, | {253, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255}, | |||
| }, | }, | |||
| { | { | |||
| {255, 253, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, | {255, 251, 253, 255, 255, 255, 255, 255, 255, 255, 255}, | |||
| {247, 254, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, | {252, 253, 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}, | |||
| }, | }, | |||
| { | { | |||
| {255, 253, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, | {255, 252, 255, 255, 255, 255, 255, 255, 255, 255, 255}, | |||
| {252, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, }, | {249, 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, 254, 254, 255, 255, 255, 255, 255, 255, 255, 255, }, | {255, 255, 253, 255, 255, 255, 255, 255, 255, 255, 255}, | |||
| {253, 255, 255, 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}, | |||
| }, | }, | |||
| { | { | |||
| {255, 254, 253, 255, 255, 255, 255, 255, 255, 255, 255, }, | {255, 255, 255, 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}, | |||
| {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, }, | ||||
| }, | ||||
| }, | ||||
| { | ||||
| { | ||||
| {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, }, | ||||
| }, | ||||
| { | ||||
| {255, 255, 255, 255, 255, 255, 255, 255, 255, 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, }, | ||||
| }, | ||||
| { | ||||
| {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 | static const | |||
| unsigned char k_default_y_mode_probs [] = | unsigned char k_default_y_mode_probs [] = | |||
| { 112, 86, 140, 37}; | { 112, 86, 140, 37}; | |||
| static const | static const | |||
| unsigned char k_default_uv_mode_probs [] = | unsigned char k_default_uv_mode_probs [] = | |||
| { 162, 101, 204}; | { 162, 101, 204}; | |||
| static const | static const | |||
| unsigned char k_default_coeff_probs [BLOCK_TYPES][COEF_BANDS] | unsigned char k_default_coeff_probs [BLOCK_TYPES][COEF_BANDS] | |||
| [PREV_COEF_CONTEXTS][ENTROPY_NODES] = | [PREV_COEF_CONTEXTS][ENTROPY_NODES] = | |||
| { | { | |||
| { /* block type 0 */ | { /* block type 0 */ | |||
| { /* coeff band 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}, | { 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 */ | { /* coeff band 1 */ | |||
| { 253, 136, 254, 255, 228, 219, 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}, | { 189, 129, 242, 255, 227, 213, 255, 219, 128, 128, 128}, | |||
| { 106, 126, 227, 252, 214, 209, 255, 255, 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} | ||||
| }, | ||||
| { /* 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} | ||||
| }, | ||||
| { /* 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} | ||||
| }, | ||||
| { /* 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} | ||||
| }, | }, | |||
| { /* coeff band 7 */ | { /* coeff band 2 */ | |||
| { 1, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, | { 1, 98, 248, 255, 236, 226, 255, 255, 128, 128, 128}, | |||
| { 244, 1, 255, 128, 128, 128, 128, 128, 128, 128, 128}, | { 181, 133, 238, 254, 221, 234, 255, 154, 128, 128, 128}, | |||
| { 238, 1, 255, 128, 128, 128, 128, 128, 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} | ||||
| }, | ||||
| { /* 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} | ||||
| }, | ||||
| { /* 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} | ||||
| }, | ||||
| { /* 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} | ||||
| }, | ||||
| { /* 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 | static const | |||
| unsigned char k_mv_entropy_update_probs[2][MV_PROB_CNT] = | unsigned char k_mv_entropy_update_probs[2][MV_PROB_CNT] = | |||
| { | { | |||
| { | { | |||
| 237, | 237, | |||
| 246, | 246, | |||
| 253, 253, 254, 254, 254, 254, 254, | 253, 253, 254, 254, 254, 254, 254, | |||
| 254, 254, 254, 254, 254, 250, 250, 252, 254, 254 | 254, 254, 254, 254, 254, 250, 250, 252, 254, 254 | |||
| }, | }, | |||
| { | { | |||
| 231, | 231, | |||
| 243, | 243, | |||
| 245, 253, 254, 254, 254, 254, 254, | 245, 253, 254, 254, 254, 254, 254, | |||
| 254, 254, 254, 254, 254, 251, 251, 254, 254, 254 | 254, 254, 254, 254, 254, 251, 251, 254, 254, 254 | |||
| } | } | |||
| }; | }; | |||
| static const | static const | |||
| unsigned char k_default_mv_probs[2][MV_PROB_CNT] = | unsigned char k_default_mv_probs[2][MV_PROB_CNT] = | |||
| { | { | |||
| { /* row */ | { // row | |||
| 162, /* is short */ | 162, // is short | |||
| 128, /* sign */ | 128, // sign | |||
| 225, 146, 172, 147, 214, 39, 156, /* short tree */ | 225, 146, 172, 147, 214, 39, 156, // short tree | |||
| 128, 129, 132, 75, 145, 178, 206, 239, 254, 254 /* long bits */ | 128, 129, 132, 75, 145, 178, 206, 239, 254, 254 // long bits | |||
| }, | }, | |||
| { | { | |||
| 164, | 164, | |||
| 128, | 128, | |||
| 204, 170, 119, 235, 140, 230, 228, | 204, 170, 119, 235, 140, 230, 228, | |||
| 128, 130, 130, 74, 148, 180, 203, 236, 254, 254 | 128, 130, 130, 74, 148, 180, 203, 236, 254, 254 | |||
| } | } | |||
| }; | }; | |||
| ---- End code block ---------------------------------------- | ||||
| 20.19. vpx_codec_internal.h | 20.19. vpx_codec_internal.h | |||
| ---- Begin code block -------------------------------------- | ---- Begin code block -------------------------------------- | |||
| /* | /* | |||
| * Copyright (c) 2010 The VP8 project authors. All Rights Reserved. | * Copyright (c) 2010 The VP8 project authors. All Rights Reserved. | |||
| * | * | |||
| * Use of this source code is governed by a BSD-style license | * 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 | * that can be found in the LICENSE file in the root of the source | |||
| * tree. An additional intellectual property rights grant can be | * tree. An additional intellectual property rights grant can be | |||
| * found in the file PATENTS. All contributing project authors may | * found in the file PATENTS. All contributing project authors may | |||
| * be found in the AUTHORS file in the root of the source tree. | * be found in the AUTHORS file in the root of the source tree. | |||
| */ | */ | |||
| /*!\file decoder_impl.h | /*!\file vpx_codec_internal.h | |||
| * \brief Describes the decoder algorithm interface for algorithm | * \brief Describes the decoder algorithm interface for algorithm | |||
| * implementations. | * implementations. | |||
| * | * | |||
| * This file defines the private structures and data types that are | * This file defines the private structures and data types that are | |||
| * only relevant to implementing an algorithm, as opposed to using | * only relevant to implementing an algorithm, as opposed to using | |||
| * it. | * it. | |||
| * | * | |||
| * To create a decoder algorithm class, an interface structure is put | * To create a decoder algorithm class, an interface structure is put | |||
| * into the global namespace: | * into the global namespace: | |||
| * <pre> | * <pre> | |||
| skipping to change at page 283, line 35 ¶ | skipping to change at page 276, line 38 ¶ | |||
| #ifdef __cplusplus | #ifdef __cplusplus | |||
| } | } | |||
| #endif | #endif | |||
| #if !defined(VPX_CODEC_DISABLE_COMPAT) || !VPX_CODEC_DISABLE_COMPAT | #if !defined(VPX_CODEC_DISABLE_COMPAT) || !VPX_CODEC_DISABLE_COMPAT | |||
| #include "vpx_decoder_compat.h" | #include "vpx_decoder_compat.h" | |||
| #endif | #endif | |||
| ---- End code block ---------------------------------------- | ---- End code block ---------------------------------------- | |||
| 20.21. vpx_integer.h | 20.21. vpx_decoder_compat.h | |||
| ---- Begin code block -------------------------------------- | ||||
| /* | ||||
| * Copyright (c) 2010 The WebM project authors. 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 | ||||
| /*!\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 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, | ||||
| /*!\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; | ||||
| #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; | ||||
| /*!\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. | ||||
| * | ||||
| * \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. | ||||
| * \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; | ||||
| /*!\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; | ||||
| /*!\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 | ||||
| * | ||||
| * \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; | ||||
| /*!@} - 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. The | ||||
| */ | ||||
| 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*/ | ||||
| /*!\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 */ | ||||
| /* 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. | ||||
| * | ||||
| * \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. | ||||
| */ | ||||
| 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 The WebM project authors. 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) | ||||
| { | ||||
| 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; | ||||
| } | ||||
| /* 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; | ||||
| } | ||||
| 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); | ||||
| } | ||||
| 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]; | ||||
| 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 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]; | ||||
| 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 The WebM project authors. 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 | ||||
| * | ||||
| */ | ||||
| #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, | ||||
| 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 | ||||
| /** \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 | ||||
| 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. | ||||
| */ | ||||
| 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 | ||||
| * | ||||
| * \return 0 if the requested rectangle is valid, nonzero | ||||
| * 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 ---------------------------------------- | ||||
| 20.24. vpx_integer.h | ||||
| ---- Begin code block -------------------------------------- | ---- Begin code block -------------------------------------- | |||
| /* | /* | |||
| * Copyright (c) 2010 The VP8 project authors. All Rights Reserved. | * Copyright (c) 2010 The VP8 project authors. All Rights Reserved. | |||
| * | * | |||
| * Use of this source code is governed by a BSD-style license | * 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 | * that can be found in the LICENSE file in the root of the source | |||
| * tree. An additional intellectual property rights grant can be | * tree. An additional intellectual property rights grant can be | |||
| * found in the file PATENTS. All contributing project authors may | * found in the file PATENTS. All contributing project authors may | |||
| skipping to change at page 285, line 4 ¶ | skipping to change at page 303, line 39 ¶ | |||
| #if defined(__cplusplus) && !defined(__STDC_FORMAT_MACROS) | #if defined(__cplusplus) && !defined(__STDC_FORMAT_MACROS) | |||
| #define __STDC_FORMAT_MACROS | #define __STDC_FORMAT_MACROS | |||
| #endif | #endif | |||
| #include <stdint.h> | #include <stdint.h> | |||
| #include <inttypes.h> | #include <inttypes.h> | |||
| #endif | #endif | |||
| #endif | #endif | |||
| ---- End code block ---------------------------------------- | ---- End code block ---------------------------------------- | |||
| 20.22. AUTHORS | 20.25. AUTHORS | |||
| Aaron Watry <awatry@gmail.com> | Aaron Watry <awatry@gmail.com> | |||
| Adrian Grange <agrange@google.com> | Adrian Grange <agrange@google.com> | |||
| Alex Converse <alex.converse@gmail.com> | Alex Converse <alex.converse@gmail.com> | |||
| Andoni Morales Alastruey <ylatuya@gmail.com> | Andoni Morales Alastruey <ylatuya@gmail.com> | |||
| Andres Mejia <mcitadel@gmail.com> | Andres Mejia <mcitadel@gmail.com> | |||
| Attila Nagy <attilanagy@google.com> | Attila Nagy <attilanagy@google.com> | |||
| Fabio Pedretti <fabio.ped@libero.it> | Fabio Pedretti <fabio.ped@libero.it> | |||
| Frank Galligan <fgalligan@google.com> | Frank Galligan <fgalligan@google.com> | |||
| Fredrik Soederquist <fs@opera.com> | Fredrik Soederquist <fs@opera.com> | |||
| skipping to change at page 286, line 44 ¶ | skipping to change at page 305, line 32 ¶ | |||
| Yaowu Xu <yaowu@google.com> | Yaowu Xu <yaowu@google.com> | |||
| Yunqing Wang <yunqingwang@google.com> | Yunqing Wang <yunqingwang@google.com> | |||
| Google Inc. | Google Inc. | |||
| The Mozilla Foundation | The Mozilla Foundation | |||
| The Xiph.Org Foundation | The Xiph.Org Foundation | |||
| 20.23. LICENSE | 20.26. LICENSE | |||
| Copyright (c) 2010, Google Inc. All rights reserved. | Copyright (c) 2010, Google Inc. All rights reserved. | |||
| Redistribution and use in source and binary forms, with or without | Redistribution and use in source and binary forms, with or without | |||
| modification, are permitted provided that the following conditions | modification, are permitted provided that the following conditions | |||
| are met: | are met: | |||
| o Redistributions of source code must retain the above copyright | o Redistributions of source code must retain the above copyright | |||
| notice, this list of conditions and the following disclaimer. | notice, this list of conditions and the following disclaimer. | |||
| skipping to change at page 287, line 30 ¶ | skipping to change at page 306, line 18 ¶ | |||
| A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | |||
| HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, | |||
| INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, | |||
| BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS | BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS | |||
| OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED | |||
| AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT | |||
| LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY | LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY | |||
| WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE | |||
| POSSIBILITY OF SUCH DAMAGE. | POSSIBILITY OF SUCH DAMAGE. | |||
| 20.24. PATENTS | 20.27. PATENTS | |||
| Additional IP Rights Grant (Patents) | Additional IP Rights Grant (Patents) | |||
| "This implementation" means the copyrightable works distributed by | "This implementation" means the copyrightable works distributed by | |||
| Google as part of the WebM Project. | Google as part of the WebM Project. | |||
| Google hereby grants to you a perpetual, worldwide, non-exclusive, | Google hereby grants to you a perpetual, worldwide, non-exclusive, | |||
| no-charge, royalty-free, irrevocable (except as stated in this | no-charge, royalty-free, irrevocable (except as stated in this | |||
| section) patent license to make, have made, use, offer to sell, sell, | section) patent license to make, have made, use, offer to sell, sell, | |||
| import, transfer, and otherwise run, modify and propagate the | import, transfer, and otherwise run, modify and propagate the | |||
| skipping to change at page 289, line 5 ¶ | skipping to change at page 307, line 5 ¶ | |||
| modification of this implementation. If you or your agent or | modification of this implementation. If you or your agent or | |||
| exclusive licensee institute or order or agree to the institution of | exclusive licensee institute or order or agree to the institution of | |||
| patent litigation against any entity (including a cross-claim or | patent litigation against any entity (including a cross-claim or | |||
| counterclaim in a lawsuit) alleging that this implementation of VP8 | counterclaim in a lawsuit) alleging that this implementation of VP8 | |||
| or any code incorporated within this implementation of VP8 | or any code incorporated within this implementation of VP8 | |||
| constitutes direct or contributory patent infringement, or inducement | constitutes direct or contributory patent infringement, or inducement | |||
| of patent infringement, then any patent rights granted to you under | of patent infringement, then any patent rights granted to you under | |||
| this License for this implementation of VP8 shall terminate as of the | this License for this implementation of VP8 shall terminate as of the | |||
| date such litigation is filed. | date such litigation is filed. | |||
| 21. References | 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. | ||||
| 22. IANA Considerations | ||||
| This document has no actions for IANA. | ||||
| 23. Informative References | ||||
| [Bell] Bell, T., Cleary, J., and I. Witten, "Text Compression", | ||||
| 1990. | ||||
| [ITU-R_BT.601] | [ITU-R_BT.601] | |||
| International Telecommunication Union, "ITU BT.601: Studio | International Telecommunication Union, "ITU BT.601: Studio | |||
| encoding parameters of digital television for standard 4:3 | encoding parameters of digital television for standard 4:3 | |||
| and wide screen 16:9 aspect ratios", January 2007. | and wide screen 16:9 aspect ratios", January 2007. | |||
| [Bell] Bell, T., Cleary, J., and I. Witten, "Text Compression", | ||||
| 1990. | ||||
| [Kernighan] | [Kernighan] | |||
| Kernighan, B. and D. Ritchie, "The C Programming Language | Kernighan, B. and D. Ritchie, "The C Programming Language | |||
| (2nd edition)", April 1988. | (2nd edition)", April 1988. | |||
| [Loeffler] | [Loeffler] | |||
| Loeffler, C., Ligtenberg , A., and G. Moschytz, "Practical | Loeffler, C., Ligtenberg , A., and G. Moschytz, "Practical | |||
| Fast 1-D DCT Algorithms with 11 Multiplications", | Fast 1-D DCT Algorithms with 11 Multiplications", | |||
| May 1989. | May 1989. | |||
| [RFC2119] Bradner, S., "Key words for use in RFCs to Indicate | ||||
| Requirement Levels", BCP 14, RFC 2119, March 1997. | ||||
| [RFC3552] Rescorla, E. and B. Korver, "Guidelines for Writing RFC | ||||
| Text on Security Considerations", BCP 72, RFC 3552, | ||||
| July 2003. | ||||
| [RFC3979] Bradner, S., "Intellectual Property Rights in IETF | ||||
| Technology", BCP 79, RFC 3979, March 2005. | ||||
| [RFC4732] Handley, M., Rescorla, E., and IAB, "Internet Denial-of- | ||||
| Service Considerations", RFC 4732, December 2006. | ||||
| [RFC5378] Bradner, S. and J. Contreras, "Rights Contributors Provide | ||||
| to the IETF Trust", BCP 78, RFC 5378, November 2008. | ||||
| [Shannon] Shannon, C., "A Mathematical Theory of Communication", | [Shannon] Shannon, C., "A Mathematical Theory of Communication", | |||
| Bell System Technical Journal Vol. 27, pp. 379-423, 623- | Bell System Technical Journal Vol. 27, pp. 379-423, 623- | |||
| 656, July, October 1948. | 656, July, October 1948. | |||
| Authors' Addresses | Authors' Addresses | |||
| James Bankoski | James Bankoski | |||
| Google Inc. | Google Inc. | |||
| Email: jimbankoski@google.com | Email: jimbankoski@google.com | |||
| End of changes. 488 change blocks. | ||||
| 3648 lines changed or deleted | 4534 lines changed or added | |||
This html diff was produced by rfcdiff 1.48. The latest version is available from http://tools.ietf.org/tools/rfcdiff/ | ||||