/src/libvpx/vpx_dsp/bitreader.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) 2010 The WebM project authors. All Rights Reserved. |
3 | | * |
4 | | * Use of this source code is governed by a BSD-style license |
5 | | * that can be found in the LICENSE file in the root of the source |
6 | | * tree. An additional intellectual property rights grant can be found |
7 | | * in the file PATENTS. All contributing project authors may |
8 | | * be found in the AUTHORS file in the root of the source tree. |
9 | | */ |
10 | | |
11 | | #ifndef VPX_VPX_DSP_BITREADER_H_ |
12 | | #define VPX_VPX_DSP_BITREADER_H_ |
13 | | |
14 | | #include <stddef.h> |
15 | | #include <stdio.h> |
16 | | #include <limits.h> |
17 | | |
18 | | #include "./vpx_config.h" |
19 | | #include "vpx_ports/mem.h" |
20 | | #include "vpx/vp8dx.h" |
21 | | #include "vpx/vpx_integer.h" |
22 | | #include "vpx_dsp/prob.h" |
23 | | #if CONFIG_BITSTREAM_DEBUG |
24 | | #include "vpx_util/vpx_debug_util.h" |
25 | | #endif // CONFIG_BITSTREAM_DEBUG |
26 | | |
27 | | #ifdef __cplusplus |
28 | | extern "C" { |
29 | | #endif |
30 | | |
31 | | typedef size_t BD_VALUE; |
32 | | |
33 | 525M | #define BD_VALUE_SIZE ((int)sizeof(BD_VALUE) * CHAR_BIT) |
34 | | |
35 | | // This is meant to be a large, positive constant that can still be efficiently |
36 | | // loaded as an immediate (on platforms like ARM, for example). |
37 | | // Even relatively modest values like 100 would work fine. |
38 | 388k | #define LOTS_OF_BITS 0x40000000 |
39 | | |
40 | | typedef struct { |
41 | | // Be careful when reordering this struct, it may impact the cache negatively. |
42 | | BD_VALUE value; |
43 | | unsigned int range; |
44 | | int count; |
45 | | const uint8_t *buffer_end; |
46 | | const uint8_t *buffer; |
47 | | vpx_decrypt_cb decrypt_cb; |
48 | | void *decrypt_state; |
49 | | uint8_t clear_buffer[sizeof(BD_VALUE) + 1]; |
50 | | } vpx_reader; |
51 | | |
52 | | int vpx_reader_init(vpx_reader *r, const uint8_t *buffer, size_t size, |
53 | | vpx_decrypt_cb decrypt_cb, void *decrypt_state); |
54 | | |
55 | | void vpx_reader_fill(vpx_reader *r); |
56 | | |
57 | | const uint8_t *vpx_reader_find_end(vpx_reader *r); |
58 | | |
59 | 6.73M | static INLINE int vpx_reader_has_error(vpx_reader *r) { |
60 | | // Check if we have reached the end of the buffer. |
61 | | // |
62 | | // Variable 'count' stores the number of bits in the 'value' buffer, minus |
63 | | // 8. The top byte is part of the algorithm, and the remainder is buffered |
64 | | // to be shifted into it. So if count == 8, the top 16 bits of 'value' are |
65 | | // occupied, 8 for the algorithm and 8 in the buffer. |
66 | | // |
67 | | // When reading a byte from the user's buffer, count is filled with 8 and |
68 | | // one byte is filled into the value buffer. When we reach the end of the |
69 | | // data, count is additionally filled with LOTS_OF_BITS. So when |
70 | | // count == LOTS_OF_BITS - 1, the user's data has been exhausted. |
71 | | // |
72 | | // 1 if we have tried to decode bits after the end of stream was encountered. |
73 | | // 0 No error. |
74 | 6.73M | return r->count > BD_VALUE_SIZE && r->count < LOTS_OF_BITS; |
75 | 6.73M | } Unexecuted instantiation: vp9_dx_iface.c:vpx_reader_has_error vp9_decodeframe.c:vpx_reader_has_error Line | Count | Source | 59 | 6.73M | static INLINE int vpx_reader_has_error(vpx_reader *r) { | 60 | | // Check if we have reached the end of the buffer. | 61 | | // | 62 | | // Variable 'count' stores the number of bits in the 'value' buffer, minus | 63 | | // 8. The top byte is part of the algorithm, and the remainder is buffered | 64 | | // to be shifted into it. So if count == 8, the top 16 bits of 'value' are | 65 | | // occupied, 8 for the algorithm and 8 in the buffer. | 66 | | // | 67 | | // When reading a byte from the user's buffer, count is filled with 8 and | 68 | | // one byte is filled into the value buffer. When we reach the end of the | 69 | | // data, count is additionally filled with LOTS_OF_BITS. So when | 70 | | // count == LOTS_OF_BITS - 1, the user's data has been exhausted. | 71 | | // | 72 | | // 1 if we have tried to decode bits after the end of stream was encountered. | 73 | | // 0 No error. | 74 | 6.73M | return r->count > BD_VALUE_SIZE && r->count < LOTS_OF_BITS; | 75 | 6.73M | } |
Unexecuted instantiation: vp9_detokenize.c:vpx_reader_has_error Unexecuted instantiation: vp9_decoder.c:vpx_reader_has_error Unexecuted instantiation: vp9_dsubexp.c:vpx_reader_has_error Unexecuted instantiation: bitreader.c:vpx_reader_has_error Unexecuted instantiation: vp9_decodemv.c:vpx_reader_has_error |
76 | | |
77 | 140M | static INLINE int vpx_read(vpx_reader *r, int prob) { |
78 | 140M | unsigned int bit = 0; |
79 | 140M | BD_VALUE value; |
80 | 140M | BD_VALUE bigsplit; |
81 | 140M | int count; |
82 | 140M | unsigned int range; |
83 | 140M | unsigned int split = (r->range * prob + (256 - prob)) >> CHAR_BIT; |
84 | | |
85 | 140M | if (r->count < 0) vpx_reader_fill(r); |
86 | | |
87 | 140M | value = r->value; |
88 | 140M | count = r->count; |
89 | | |
90 | 140M | bigsplit = (BD_VALUE)split << (BD_VALUE_SIZE - CHAR_BIT); |
91 | | |
92 | 140M | range = split; |
93 | | |
94 | 140M | if (value >= bigsplit) { |
95 | 50.8M | range = r->range - split; |
96 | 50.8M | value = value - bigsplit; |
97 | 50.8M | bit = 1; |
98 | 50.8M | } |
99 | | |
100 | 140M | { |
101 | 140M | const unsigned char shift = vpx_norm[(unsigned char)range]; |
102 | 140M | range <<= shift; |
103 | 140M | value <<= shift; |
104 | 140M | count -= shift; |
105 | 140M | } |
106 | 140M | r->value = value; |
107 | 140M | r->count = count; |
108 | 140M | r->range = range; |
109 | | |
110 | | #if CONFIG_BITSTREAM_DEBUG |
111 | | { |
112 | | const int queue_r = bitstream_queue_get_read(); |
113 | | const int frame_idx = bitstream_queue_get_frame_read(); |
114 | | int ref_result, ref_prob; |
115 | | bitstream_queue_pop(&ref_result, &ref_prob); |
116 | | if ((int)bit != ref_result) { |
117 | | fprintf(stderr, |
118 | | "\n *** [bit] result error, frame_idx_r %d bit %d ref_result %d " |
119 | | "queue_r %d\n", |
120 | | frame_idx, bit, ref_result, queue_r); |
121 | | |
122 | | assert(0); |
123 | | } |
124 | | if (prob != ref_prob) { |
125 | | fprintf(stderr, |
126 | | "\n *** [bit] prob error, frame_idx_r %d prob %d ref_prob %d " |
127 | | "queue_r %d\n", |
128 | | frame_idx, prob, ref_prob, queue_r); |
129 | | |
130 | | assert(0); |
131 | | } |
132 | | } |
133 | | #endif |
134 | | |
135 | 140M | return bit; |
136 | 140M | } Unexecuted instantiation: vp9_dx_iface.c:vpx_read vp9_decodeframe.c:vpx_read Line | Count | Source | 77 | 18.8M | static INLINE int vpx_read(vpx_reader *r, int prob) { | 78 | 18.8M | unsigned int bit = 0; | 79 | 18.8M | BD_VALUE value; | 80 | 18.8M | BD_VALUE bigsplit; | 81 | 18.8M | int count; | 82 | 18.8M | unsigned int range; | 83 | 18.8M | unsigned int split = (r->range * prob + (256 - prob)) >> CHAR_BIT; | 84 | | | 85 | 18.8M | if (r->count < 0) vpx_reader_fill(r); | 86 | | | 87 | 18.8M | value = r->value; | 88 | 18.8M | count = r->count; | 89 | | | 90 | 18.8M | bigsplit = (BD_VALUE)split << (BD_VALUE_SIZE - CHAR_BIT); | 91 | | | 92 | 18.8M | range = split; | 93 | | | 94 | 18.8M | if (value >= bigsplit) { | 95 | 7.85M | range = r->range - split; | 96 | 7.85M | value = value - bigsplit; | 97 | 7.85M | bit = 1; | 98 | 7.85M | } | 99 | | | 100 | 18.8M | { | 101 | 18.8M | const unsigned char shift = vpx_norm[(unsigned char)range]; | 102 | 18.8M | range <<= shift; | 103 | 18.8M | value <<= shift; | 104 | 18.8M | count -= shift; | 105 | 18.8M | } | 106 | 18.8M | r->value = value; | 107 | 18.8M | r->count = count; | 108 | 18.8M | r->range = range; | 109 | | | 110 | | #if CONFIG_BITSTREAM_DEBUG | 111 | | { | 112 | | const int queue_r = bitstream_queue_get_read(); | 113 | | const int frame_idx = bitstream_queue_get_frame_read(); | 114 | | int ref_result, ref_prob; | 115 | | bitstream_queue_pop(&ref_result, &ref_prob); | 116 | | if ((int)bit != ref_result) { | 117 | | fprintf(stderr, | 118 | | "\n *** [bit] result error, frame_idx_r %d bit %d ref_result %d " | 119 | | "queue_r %d\n", | 120 | | frame_idx, bit, ref_result, queue_r); | 121 | | | 122 | | assert(0); | 123 | | } | 124 | | if (prob != ref_prob) { | 125 | | fprintf(stderr, | 126 | | "\n *** [bit] prob error, frame_idx_r %d prob %d ref_prob %d " | 127 | | "queue_r %d\n", | 128 | | frame_idx, prob, ref_prob, queue_r); | 129 | | | 130 | | assert(0); | 131 | | } | 132 | | } | 133 | | #endif | 134 | | | 135 | 18.8M | return bit; | 136 | 18.8M | } |
Unexecuted instantiation: vp9_detokenize.c:vpx_read Unexecuted instantiation: vp9_decoder.c:vpx_read Line | Count | Source | 77 | 48.4M | static INLINE int vpx_read(vpx_reader *r, int prob) { | 78 | 48.4M | unsigned int bit = 0; | 79 | 48.4M | BD_VALUE value; | 80 | 48.4M | BD_VALUE bigsplit; | 81 | 48.4M | int count; | 82 | 48.4M | unsigned int range; | 83 | 48.4M | unsigned int split = (r->range * prob + (256 - prob)) >> CHAR_BIT; | 84 | | | 85 | 48.4M | if (r->count < 0) vpx_reader_fill(r); | 86 | | | 87 | 48.4M | value = r->value; | 88 | 48.4M | count = r->count; | 89 | | | 90 | 48.4M | bigsplit = (BD_VALUE)split << (BD_VALUE_SIZE - CHAR_BIT); | 91 | | | 92 | 48.4M | range = split; | 93 | | | 94 | 48.4M | if (value >= bigsplit) { | 95 | 3.00M | range = r->range - split; | 96 | 3.00M | value = value - bigsplit; | 97 | 3.00M | bit = 1; | 98 | 3.00M | } | 99 | | | 100 | 48.4M | { | 101 | 48.4M | const unsigned char shift = vpx_norm[(unsigned char)range]; | 102 | 48.4M | range <<= shift; | 103 | 48.4M | value <<= shift; | 104 | 48.4M | count -= shift; | 105 | 48.4M | } | 106 | 48.4M | r->value = value; | 107 | 48.4M | r->count = count; | 108 | 48.4M | r->range = range; | 109 | | | 110 | | #if CONFIG_BITSTREAM_DEBUG | 111 | | { | 112 | | const int queue_r = bitstream_queue_get_read(); | 113 | | const int frame_idx = bitstream_queue_get_frame_read(); | 114 | | int ref_result, ref_prob; | 115 | | bitstream_queue_pop(&ref_result, &ref_prob); | 116 | | if ((int)bit != ref_result) { | 117 | | fprintf(stderr, | 118 | | "\n *** [bit] result error, frame_idx_r %d bit %d ref_result %d " | 119 | | "queue_r %d\n", | 120 | | frame_idx, bit, ref_result, queue_r); | 121 | | | 122 | | assert(0); | 123 | | } | 124 | | if (prob != ref_prob) { | 125 | | fprintf(stderr, | 126 | | "\n *** [bit] prob error, frame_idx_r %d prob %d ref_prob %d " | 127 | | "queue_r %d\n", | 128 | | frame_idx, prob, ref_prob, queue_r); | 129 | | | 130 | | assert(0); | 131 | | } | 132 | | } | 133 | | #endif | 134 | | | 135 | 48.4M | return bit; | 136 | 48.4M | } |
Line | Count | Source | 77 | 312k | static INLINE int vpx_read(vpx_reader *r, int prob) { | 78 | 312k | unsigned int bit = 0; | 79 | 312k | BD_VALUE value; | 80 | 312k | BD_VALUE bigsplit; | 81 | 312k | int count; | 82 | 312k | unsigned int range; | 83 | 312k | unsigned int split = (r->range * prob + (256 - prob)) >> CHAR_BIT; | 84 | | | 85 | 312k | if (r->count < 0) vpx_reader_fill(r); | 86 | | | 87 | 312k | value = r->value; | 88 | 312k | count = r->count; | 89 | | | 90 | 312k | bigsplit = (BD_VALUE)split << (BD_VALUE_SIZE - CHAR_BIT); | 91 | | | 92 | 312k | range = split; | 93 | | | 94 | 312k | if (value >= bigsplit) { | 95 | 10.5k | range = r->range - split; | 96 | 10.5k | value = value - bigsplit; | 97 | 10.5k | bit = 1; | 98 | 10.5k | } | 99 | | | 100 | 312k | { | 101 | 312k | const unsigned char shift = vpx_norm[(unsigned char)range]; | 102 | 312k | range <<= shift; | 103 | 312k | value <<= shift; | 104 | 312k | count -= shift; | 105 | 312k | } | 106 | 312k | r->value = value; | 107 | 312k | r->count = count; | 108 | 312k | r->range = range; | 109 | | | 110 | | #if CONFIG_BITSTREAM_DEBUG | 111 | | { | 112 | | const int queue_r = bitstream_queue_get_read(); | 113 | | const int frame_idx = bitstream_queue_get_frame_read(); | 114 | | int ref_result, ref_prob; | 115 | | bitstream_queue_pop(&ref_result, &ref_prob); | 116 | | if ((int)bit != ref_result) { | 117 | | fprintf(stderr, | 118 | | "\n *** [bit] result error, frame_idx_r %d bit %d ref_result %d " | 119 | | "queue_r %d\n", | 120 | | frame_idx, bit, ref_result, queue_r); | 121 | | | 122 | | assert(0); | 123 | | } | 124 | | if (prob != ref_prob) { | 125 | | fprintf(stderr, | 126 | | "\n *** [bit] prob error, frame_idx_r %d prob %d ref_prob %d " | 127 | | "queue_r %d\n", | 128 | | frame_idx, prob, ref_prob, queue_r); | 129 | | | 130 | | assert(0); | 131 | | } | 132 | | } | 133 | | #endif | 134 | | | 135 | 312k | return bit; | 136 | 312k | } |
Line | Count | Source | 77 | 72.4M | static INLINE int vpx_read(vpx_reader *r, int prob) { | 78 | 72.4M | unsigned int bit = 0; | 79 | 72.4M | BD_VALUE value; | 80 | 72.4M | BD_VALUE bigsplit; | 81 | 72.4M | int count; | 82 | 72.4M | unsigned int range; | 83 | 72.4M | unsigned int split = (r->range * prob + (256 - prob)) >> CHAR_BIT; | 84 | | | 85 | 72.4M | if (r->count < 0) vpx_reader_fill(r); | 86 | | | 87 | 72.4M | value = r->value; | 88 | 72.4M | count = r->count; | 89 | | | 90 | 72.4M | bigsplit = (BD_VALUE)split << (BD_VALUE_SIZE - CHAR_BIT); | 91 | | | 92 | 72.4M | range = split; | 93 | | | 94 | 72.4M | if (value >= bigsplit) { | 95 | 40.0M | range = r->range - split; | 96 | 40.0M | value = value - bigsplit; | 97 | 40.0M | bit = 1; | 98 | 40.0M | } | 99 | | | 100 | 72.4M | { | 101 | 72.4M | const unsigned char shift = vpx_norm[(unsigned char)range]; | 102 | 72.4M | range <<= shift; | 103 | 72.4M | value <<= shift; | 104 | 72.4M | count -= shift; | 105 | 72.4M | } | 106 | 72.4M | r->value = value; | 107 | 72.4M | r->count = count; | 108 | 72.4M | r->range = range; | 109 | | | 110 | | #if CONFIG_BITSTREAM_DEBUG | 111 | | { | 112 | | const int queue_r = bitstream_queue_get_read(); | 113 | | const int frame_idx = bitstream_queue_get_frame_read(); | 114 | | int ref_result, ref_prob; | 115 | | bitstream_queue_pop(&ref_result, &ref_prob); | 116 | | if ((int)bit != ref_result) { | 117 | | fprintf(stderr, | 118 | | "\n *** [bit] result error, frame_idx_r %d bit %d ref_result %d " | 119 | | "queue_r %d\n", | 120 | | frame_idx, bit, ref_result, queue_r); | 121 | | | 122 | | assert(0); | 123 | | } | 124 | | if (prob != ref_prob) { | 125 | | fprintf(stderr, | 126 | | "\n *** [bit] prob error, frame_idx_r %d prob %d ref_prob %d " | 127 | | "queue_r %d\n", | 128 | | frame_idx, prob, ref_prob, queue_r); | 129 | | | 130 | | assert(0); | 131 | | } | 132 | | } | 133 | | #endif | 134 | | | 135 | 72.4M | return bit; | 136 | 72.4M | } |
|
137 | | |
138 | 5.70M | static INLINE int vpx_read_bit(vpx_reader *r) { |
139 | 5.70M | return vpx_read(r, 128); // vpx_prob_half |
140 | 5.70M | } Unexecuted instantiation: vp9_dx_iface.c:vpx_read_bit vp9_decodeframe.c:vpx_read_bit Line | Count | Source | 138 | 1.13M | static INLINE int vpx_read_bit(vpx_reader *r) { | 139 | 1.13M | return vpx_read(r, 128); // vpx_prob_half | 140 | 1.13M | } |
Unexecuted instantiation: vp9_detokenize.c:vpx_read_bit Unexecuted instantiation: vp9_decoder.c:vpx_read_bit vp9_dsubexp.c:vpx_read_bit Line | Count | Source | 138 | 4.25M | static INLINE int vpx_read_bit(vpx_reader *r) { | 139 | 4.25M | return vpx_read(r, 128); // vpx_prob_half | 140 | 4.25M | } |
Line | Count | Source | 138 | 312k | static INLINE int vpx_read_bit(vpx_reader *r) { | 139 | 312k | return vpx_read(r, 128); // vpx_prob_half | 140 | 312k | } |
Unexecuted instantiation: vp9_decodemv.c:vpx_read_bit |
141 | | |
142 | 857k | static INLINE int vpx_read_literal(vpx_reader *r, int bits) { |
143 | 857k | int literal = 0, bit; |
144 | | |
145 | 4.57M | for (bit = bits - 1; bit >= 0; bit--) literal |= vpx_read_bit(r) << bit; |
146 | | |
147 | 857k | return literal; |
148 | 857k | } Unexecuted instantiation: vp9_dx_iface.c:vpx_read_literal vp9_decodeframe.c:vpx_read_literal Line | Count | Source | 142 | 187k | static INLINE int vpx_read_literal(vpx_reader *r, int bits) { | 143 | 187k | int literal = 0, bit; | 144 | | | 145 | 897k | for (bit = bits - 1; bit >= 0; bit--) literal |= vpx_read_bit(r) << bit; | 146 | | | 147 | 187k | return literal; | 148 | 187k | } |
Unexecuted instantiation: vp9_detokenize.c:vpx_read_literal Unexecuted instantiation: vp9_decoder.c:vpx_read_literal vp9_dsubexp.c:vpx_read_literal Line | Count | Source | 142 | 670k | static INLINE int vpx_read_literal(vpx_reader *r, int bits) { | 143 | 670k | int literal = 0, bit; | 144 | | | 145 | 3.67M | for (bit = bits - 1; bit >= 0; bit--) literal |= vpx_read_bit(r) << bit; | 146 | | | 147 | 670k | return literal; | 148 | 670k | } |
Unexecuted instantiation: bitreader.c:vpx_read_literal Unexecuted instantiation: vp9_decodemv.c:vpx_read_literal |
149 | | |
150 | | static INLINE int vpx_read_tree(vpx_reader *r, const vpx_tree_index *tree, |
151 | 28.7M | const vpx_prob *probs) { |
152 | 28.7M | vpx_tree_index i = 0; |
153 | | |
154 | 64.3M | while ((i = tree[i + vpx_read(r, probs[i >> 1])]) > 0) continue; |
155 | | |
156 | 28.7M | return -i; |
157 | 28.7M | } Unexecuted instantiation: vp9_dx_iface.c:vpx_read_tree vp9_decodeframe.c:vpx_read_tree Line | Count | Source | 151 | 6.44M | const vpx_prob *probs) { | 152 | 6.44M | vpx_tree_index i = 0; | 153 | | | 154 | 11.1M | while ((i = tree[i + vpx_read(r, probs[i >> 1])]) > 0) continue; | 155 | | | 156 | 6.44M | return -i; | 157 | 6.44M | } |
Unexecuted instantiation: vp9_detokenize.c:vpx_read_tree Unexecuted instantiation: vp9_decoder.c:vpx_read_tree Unexecuted instantiation: vp9_dsubexp.c:vpx_read_tree Unexecuted instantiation: bitreader.c:vpx_read_tree vp9_decodemv.c:vpx_read_tree Line | Count | Source | 151 | 22.3M | const vpx_prob *probs) { | 152 | 22.3M | vpx_tree_index i = 0; | 153 | | | 154 | 53.1M | while ((i = tree[i + vpx_read(r, probs[i >> 1])]) > 0) continue; | 155 | | | 156 | 22.3M | return -i; | 157 | 22.3M | } |
|
158 | | |
159 | | #ifdef __cplusplus |
160 | | } // extern "C" |
161 | | #endif |
162 | | |
163 | | #endif // VPX_VPX_DSP_BITREADER_H_ |