/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 | 771M | #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 | 439k | #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 | 9.15M | 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 | 9.15M | return r->count > BD_VALUE_SIZE && r->count < LOTS_OF_BITS; |
75 | 9.15M | } Unexecuted instantiation: vp9_dx_iface.c:vpx_reader_has_error vp9_decodeframe.c:vpx_reader_has_error Line | Count | Source | 59 | 9.15M | 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 | 9.15M | return r->count > BD_VALUE_SIZE && r->count < LOTS_OF_BITS; | 75 | 9.15M | } |
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 | 174M | static INLINE int vpx_read(vpx_reader *r, int prob) { |
78 | 174M | unsigned int bit = 0; |
79 | 174M | BD_VALUE value; |
80 | 174M | BD_VALUE bigsplit; |
81 | 174M | int count; |
82 | 174M | unsigned int range; |
83 | 174M | unsigned int split = (r->range * prob + (256 - prob)) >> CHAR_BIT; |
84 | | |
85 | 174M | if (r->count < 0) vpx_reader_fill(r); |
86 | | |
87 | 174M | value = r->value; |
88 | 174M | count = r->count; |
89 | | |
90 | 174M | bigsplit = (BD_VALUE)split << (BD_VALUE_SIZE - CHAR_BIT); |
91 | | |
92 | 174M | range = split; |
93 | | |
94 | 174M | if (value >= bigsplit) { |
95 | 69.3M | range = r->range - split; |
96 | 69.3M | value = value - bigsplit; |
97 | 69.3M | bit = 1; |
98 | 69.3M | } |
99 | | |
100 | 174M | { |
101 | 174M | const unsigned char shift = vpx_norm[(unsigned char)range]; |
102 | 174M | range <<= shift; |
103 | 174M | value <<= shift; |
104 | 174M | count -= shift; |
105 | 174M | } |
106 | 174M | r->value = value; |
107 | 174M | r->count = count; |
108 | 174M | 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 | 174M | return bit; |
136 | 174M | } Unexecuted instantiation: vp9_dx_iface.c:vpx_read vp9_decodeframe.c:vpx_read Line | Count | Source | 77 | 23.5M | static INLINE int vpx_read(vpx_reader *r, int prob) { | 78 | 23.5M | unsigned int bit = 0; | 79 | 23.5M | BD_VALUE value; | 80 | 23.5M | BD_VALUE bigsplit; | 81 | 23.5M | int count; | 82 | 23.5M | unsigned int range; | 83 | 23.5M | unsigned int split = (r->range * prob + (256 - prob)) >> CHAR_BIT; | 84 | | | 85 | 23.5M | if (r->count < 0) vpx_reader_fill(r); | 86 | | | 87 | 23.5M | value = r->value; | 88 | 23.5M | count = r->count; | 89 | | | 90 | 23.5M | bigsplit = (BD_VALUE)split << (BD_VALUE_SIZE - CHAR_BIT); | 91 | | | 92 | 23.5M | range = split; | 93 | | | 94 | 23.5M | if (value >= bigsplit) { | 95 | 10.7M | range = r->range - split; | 96 | 10.7M | value = value - bigsplit; | 97 | 10.7M | bit = 1; | 98 | 10.7M | } | 99 | | | 100 | 23.5M | { | 101 | 23.5M | const unsigned char shift = vpx_norm[(unsigned char)range]; | 102 | 23.5M | range <<= shift; | 103 | 23.5M | value <<= shift; | 104 | 23.5M | count -= shift; | 105 | 23.5M | } | 106 | 23.5M | r->value = value; | 107 | 23.5M | r->count = count; | 108 | 23.5M | 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 | 23.5M | return bit; | 136 | 23.5M | } |
Unexecuted instantiation: vp9_detokenize.c:vpx_read Unexecuted instantiation: vp9_decoder.c:vpx_read Line | Count | Source | 77 | 52.4M | static INLINE int vpx_read(vpx_reader *r, int prob) { | 78 | 52.4M | unsigned int bit = 0; | 79 | 52.4M | BD_VALUE value; | 80 | 52.4M | BD_VALUE bigsplit; | 81 | 52.4M | int count; | 82 | 52.4M | unsigned int range; | 83 | 52.4M | unsigned int split = (r->range * prob + (256 - prob)) >> CHAR_BIT; | 84 | | | 85 | 52.4M | if (r->count < 0) vpx_reader_fill(r); | 86 | | | 87 | 52.4M | value = r->value; | 88 | 52.4M | count = r->count; | 89 | | | 90 | 52.4M | bigsplit = (BD_VALUE)split << (BD_VALUE_SIZE - CHAR_BIT); | 91 | | | 92 | 52.4M | range = split; | 93 | | | 94 | 52.4M | if (value >= bigsplit) { | 95 | 3.83M | range = r->range - split; | 96 | 3.83M | value = value - bigsplit; | 97 | 3.83M | bit = 1; | 98 | 3.83M | } | 99 | | | 100 | 52.4M | { | 101 | 52.4M | const unsigned char shift = vpx_norm[(unsigned char)range]; | 102 | 52.4M | range <<= shift; | 103 | 52.4M | value <<= shift; | 104 | 52.4M | count -= shift; | 105 | 52.4M | } | 106 | 52.4M | r->value = value; | 107 | 52.4M | r->count = count; | 108 | 52.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 | 52.4M | return bit; | 136 | 52.4M | } |
Line | Count | Source | 77 | 332k | static INLINE int vpx_read(vpx_reader *r, int prob) { | 78 | 332k | unsigned int bit = 0; | 79 | 332k | BD_VALUE value; | 80 | 332k | BD_VALUE bigsplit; | 81 | 332k | int count; | 82 | 332k | unsigned int range; | 83 | 332k | unsigned int split = (r->range * prob + (256 - prob)) >> CHAR_BIT; | 84 | | | 85 | 332k | if (r->count < 0) vpx_reader_fill(r); | 86 | | | 87 | 332k | value = r->value; | 88 | 332k | count = r->count; | 89 | | | 90 | 332k | bigsplit = (BD_VALUE)split << (BD_VALUE_SIZE - CHAR_BIT); | 91 | | | 92 | 332k | range = split; | 93 | | | 94 | 332k | if (value >= bigsplit) { | 95 | 13.8k | range = r->range - split; | 96 | 13.8k | value = value - bigsplit; | 97 | 13.8k | bit = 1; | 98 | 13.8k | } | 99 | | | 100 | 332k | { | 101 | 332k | const unsigned char shift = vpx_norm[(unsigned char)range]; | 102 | 332k | range <<= shift; | 103 | 332k | value <<= shift; | 104 | 332k | count -= shift; | 105 | 332k | } | 106 | 332k | r->value = value; | 107 | 332k | r->count = count; | 108 | 332k | 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 | 332k | return bit; | 136 | 332k | } |
Line | Count | Source | 77 | 98.0M | static INLINE int vpx_read(vpx_reader *r, int prob) { | 78 | 98.0M | unsigned int bit = 0; | 79 | 98.0M | BD_VALUE value; | 80 | 98.0M | BD_VALUE bigsplit; | 81 | 98.0M | int count; | 82 | 98.0M | unsigned int range; | 83 | 98.0M | unsigned int split = (r->range * prob + (256 - prob)) >> CHAR_BIT; | 84 | | | 85 | 98.0M | if (r->count < 0) vpx_reader_fill(r); | 86 | | | 87 | 98.0M | value = r->value; | 88 | 98.0M | count = r->count; | 89 | | | 90 | 98.0M | bigsplit = (BD_VALUE)split << (BD_VALUE_SIZE - CHAR_BIT); | 91 | | | 92 | 98.0M | range = split; | 93 | | | 94 | 98.0M | if (value >= bigsplit) { | 95 | 54.8M | range = r->range - split; | 96 | 54.8M | value = value - bigsplit; | 97 | 54.8M | bit = 1; | 98 | 54.8M | } | 99 | | | 100 | 98.0M | { | 101 | 98.0M | const unsigned char shift = vpx_norm[(unsigned char)range]; | 102 | 98.0M | range <<= shift; | 103 | 98.0M | value <<= shift; | 104 | 98.0M | count -= shift; | 105 | 98.0M | } | 106 | 98.0M | r->value = value; | 107 | 98.0M | r->count = count; | 108 | 98.0M | 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 | 98.0M | return bit; | 136 | 98.0M | } |
|
137 | | |
138 | 6.94M | static INLINE int vpx_read_bit(vpx_reader *r) { |
139 | 6.94M | return vpx_read(r, 128); // vpx_prob_half |
140 | 6.94M | } Unexecuted instantiation: vp9_dx_iface.c:vpx_read_bit vp9_decodeframe.c:vpx_read_bit Line | Count | Source | 138 | 1.38M | static INLINE int vpx_read_bit(vpx_reader *r) { | 139 | 1.38M | return vpx_read(r, 128); // vpx_prob_half | 140 | 1.38M | } |
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 | 5.22M | static INLINE int vpx_read_bit(vpx_reader *r) { | 139 | 5.22M | return vpx_read(r, 128); // vpx_prob_half | 140 | 5.22M | } |
Line | Count | Source | 138 | 332k | static INLINE int vpx_read_bit(vpx_reader *r) { | 139 | 332k | return vpx_read(r, 128); // vpx_prob_half | 140 | 332k | } |
Unexecuted instantiation: vp9_decodemv.c:vpx_read_bit |
141 | | |
142 | 1.03M | static INLINE int vpx_read_literal(vpx_reader *r, int bits) { |
143 | 1.03M | int literal = 0, bit; |
144 | | |
145 | 5.62M | for (bit = bits - 1; bit >= 0; bit--) literal |= vpx_read_bit(r) << bit; |
146 | | |
147 | 1.03M | return literal; |
148 | 1.03M | } Unexecuted instantiation: vp9_dx_iface.c:vpx_read_literal vp9_decodeframe.c:vpx_read_literal Line | Count | Source | 142 | 229k | static INLINE int vpx_read_literal(vpx_reader *r, int bits) { | 143 | 229k | int literal = 0, bit; | 144 | | | 145 | 1.14M | for (bit = bits - 1; bit >= 0; bit--) literal |= vpx_read_bit(r) << bit; | 146 | | | 147 | 229k | return literal; | 148 | 229k | } |
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 | 802k | static INLINE int vpx_read_literal(vpx_reader *r, int bits) { | 143 | 802k | int literal = 0, bit; | 144 | | | 145 | 4.47M | for (bit = bits - 1; bit >= 0; bit--) literal |= vpx_read_bit(r) << bit; | 146 | | | 147 | 802k | return literal; | 148 | 802k | } |
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 | 38.7M | const vpx_prob *probs) { |
152 | 38.7M | vpx_tree_index i = 0; |
153 | | |
154 | 87.3M | while ((i = tree[i + vpx_read(r, probs[i >> 1])]) > 0) continue; |
155 | | |
156 | 38.7M | return -i; |
157 | 38.7M | } Unexecuted instantiation: vp9_dx_iface.c:vpx_read_tree vp9_decodeframe.c:vpx_read_tree Line | Count | Source | 151 | 8.95M | const vpx_prob *probs) { | 152 | 8.95M | vpx_tree_index i = 0; | 153 | | | 154 | 15.5M | while ((i = tree[i + vpx_read(r, probs[i >> 1])]) > 0) continue; | 155 | | | 156 | 8.95M | return -i; | 157 | 8.95M | } |
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 | 29.7M | const vpx_prob *probs) { | 152 | 29.7M | vpx_tree_index i = 0; | 153 | | | 154 | 71.7M | while ((i = tree[i + vpx_read(r, probs[i >> 1])]) > 0) continue; | 155 | | | 156 | 29.7M | return -i; | 157 | 29.7M | } |
|
158 | | |
159 | | #ifdef __cplusplus |
160 | | } // extern "C" |
161 | | #endif |
162 | | |
163 | | #endif // VPX_VPX_DSP_BITREADER_H_ |