annotate src/ffmpeg/libavcodec/cabac.h @ 821:66caee79ecc0 trunk

[svn] - make a dumb makefile for libavcodec so that it can be a make clean target.
author nenolod
date Mon, 12 Mar 2007 14:03:42 -0700
parents e8776388b02a
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
808
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
1 /*
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
2 * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
3 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at>
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
4 *
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
5 * This file is part of FFmpeg.
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
6 *
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
7 * FFmpeg is free software; you can redistribute it and/or
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
8 * modify it under the terms of the GNU Lesser General Public
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
9 * License as published by the Free Software Foundation; either
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
10 * version 2.1 of the License, or (at your option) any later version.
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
11 *
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
12 * FFmpeg is distributed in the hope that it will be useful,
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
15 * Lesser General Public License for more details.
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
16 *
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
17 * You should have received a copy of the GNU Lesser General Public
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
18 * License along with FFmpeg; if not, write to the Free Software
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
20 *
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
21 */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
22
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
23 /**
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
24 * @file cabac.h
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
25 * Context Adaptive Binary Arithmetic Coder.
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
26 */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
27
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
28
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
29 //#undef NDEBUG
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
30 #include <assert.h>
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
31
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
32 #define CABAC_BITS 16
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
33 #define CABAC_MASK ((1<<CABAC_BITS)-1)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
34 #define BRANCHLESS_CABAC_DECODER 1
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
35 //#define ARCH_X86_DISABLED 1
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
36
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
37 typedef struct CABACContext{
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
38 int low;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
39 int range;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
40 int outstanding_count;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
41 #ifdef STRICT_LIMITS
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
42 int symCount;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
43 #endif
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
44 const uint8_t *bytestream_start;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
45 const uint8_t *bytestream;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
46 const uint8_t *bytestream_end;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
47 PutBitContext pb;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
48 }CABACContext;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
49
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
50 extern uint8_t ff_h264_mlps_state[4*64];
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
51 extern uint8_t ff_h264_lps_range[4*2*64]; ///< rangeTabLPS
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
52 extern uint8_t ff_h264_mps_state[2*64]; ///< transIdxMPS
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
53 extern uint8_t ff_h264_lps_state[2*64]; ///< transIdxLPS
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
54 extern const uint8_t ff_h264_norm_shift[512];
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
55
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
56
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
57 void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
58 void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
59 void ff_init_cabac_states(CABACContext *c);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
60
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
61
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
62 static inline void put_cabac_bit(CABACContext *c, int b){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
63 put_bits(&c->pb, 1, b);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
64 for(;c->outstanding_count; c->outstanding_count--){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
65 put_bits(&c->pb, 1, 1-b);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
66 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
67 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
68
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
69 static inline void renorm_cabac_encoder(CABACContext *c){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
70 while(c->range < 0x100){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
71 //FIXME optimize
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
72 if(c->low<0x100){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
73 put_cabac_bit(c, 0);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
74 }else if(c->low<0x200){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
75 c->outstanding_count++;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
76 c->low -= 0x100;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
77 }else{
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
78 put_cabac_bit(c, 1);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
79 c->low -= 0x200;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
80 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
81
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
82 c->range+= c->range;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
83 c->low += c->low;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
84 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
85 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
86
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
87 static void put_cabac(CABACContext *c, uint8_t * const state, int bit){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
88 int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + *state];
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
89
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
90 if(bit == ((*state)&1)){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
91 c->range -= RangeLPS;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
92 *state= ff_h264_mps_state[*state];
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
93 }else{
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
94 c->low += c->range - RangeLPS;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
95 c->range = RangeLPS;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
96 *state= ff_h264_lps_state[*state];
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
97 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
98
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
99 renorm_cabac_encoder(c);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
100
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
101 #ifdef STRICT_LIMITS
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
102 c->symCount++;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
103 #endif
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
104 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
105
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
106 static void put_cabac_static(CABACContext *c, int RangeLPS, int bit){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
107 assert(c->range > RangeLPS);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
108
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
109 if(!bit){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
110 c->range -= RangeLPS;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
111 }else{
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
112 c->low += c->range - RangeLPS;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
113 c->range = RangeLPS;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
114 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
115
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
116 renorm_cabac_encoder(c);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
117
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
118 #ifdef STRICT_LIMITS
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
119 c->symCount++;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
120 #endif
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
121 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
122
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
123 /**
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
124 * @param bit 0 -> write zero bit, !=0 write one bit
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
125 */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
126 static void put_cabac_bypass(CABACContext *c, int bit){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
127 c->low += c->low;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
128
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
129 if(bit){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
130 c->low += c->range;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
131 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
132 //FIXME optimize
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
133 if(c->low<0x200){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
134 put_cabac_bit(c, 0);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
135 }else if(c->low<0x400){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
136 c->outstanding_count++;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
137 c->low -= 0x200;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
138 }else{
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
139 put_cabac_bit(c, 1);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
140 c->low -= 0x400;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
141 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
142
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
143 #ifdef STRICT_LIMITS
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
144 c->symCount++;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
145 #endif
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
146 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
147
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
148 /**
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
149 *
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
150 * @return the number of bytes written
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
151 */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
152 static int put_cabac_terminate(CABACContext *c, int bit){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
153 c->range -= 2;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
154
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
155 if(!bit){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
156 renorm_cabac_encoder(c);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
157 }else{
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
158 c->low += c->range;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
159 c->range= 2;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
160
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
161 renorm_cabac_encoder(c);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
162
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
163 assert(c->low <= 0x1FF);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
164 put_cabac_bit(c, c->low>>9);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
165 put_bits(&c->pb, 2, ((c->low>>7)&3)|1);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
166
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
167 flush_put_bits(&c->pb); //FIXME FIXME FIXME XXX wrong
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
168 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
169
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
170 #ifdef STRICT_LIMITS
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
171 c->symCount++;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
172 #endif
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
173
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
174 return (put_bits_count(&c->pb)+7)>>3;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
175 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
176
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
177 /**
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
178 * put (truncated) unary binarization.
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
179 */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
180 static void put_cabac_u(CABACContext *c, uint8_t * state, int v, int max, int max_index, int truncated){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
181 int i;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
182
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
183 assert(v <= max);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
184
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
185 #if 1
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
186 for(i=0; i<v; i++){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
187 put_cabac(c, state, 1);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
188 if(i < max_index) state++;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
189 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
190 if(truncated==0 || v<max)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
191 put_cabac(c, state, 0);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
192 #else
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
193 if(v <= max_index){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
194 for(i=0; i<v; i++){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
195 put_cabac(c, state+i, 1);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
196 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
197 if(truncated==0 || v<max)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
198 put_cabac(c, state+i, 0);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
199 }else{
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
200 for(i=0; i<=max_index; i++){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
201 put_cabac(c, state+i, 1);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
202 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
203 for(; i<v; i++){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
204 put_cabac(c, state+max_index, 1);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
205 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
206 if(truncated==0 || v<max)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
207 put_cabac(c, state+max_index, 0);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
208 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
209 #endif
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
210 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
211
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
212 /**
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
213 * put unary exp golomb k-th order binarization.
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
214 */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
215 static void put_cabac_ueg(CABACContext *c, uint8_t * state, int v, int max, int is_signed, int k, int max_index){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
216 int i;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
217
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
218 if(v==0)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
219 put_cabac(c, state, 0);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
220 else{
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
221 const int sign= v < 0;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
222
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
223 if(is_signed) v= FFABS(v);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
224
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
225 if(v<max){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
226 for(i=0; i<v; i++){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
227 put_cabac(c, state, 1);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
228 if(i < max_index) state++;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
229 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
230
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
231 put_cabac(c, state, 0);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
232 }else{
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
233 int m= 1<<k;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
234
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
235 for(i=0; i<max; i++){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
236 put_cabac(c, state, 1);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
237 if(i < max_index) state++;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
238 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
239
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
240 v -= max;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
241 while(v >= m){ //FIXME optimize
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
242 put_cabac_bypass(c, 1);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
243 v-= m;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
244 m+= m;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
245 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
246 put_cabac_bypass(c, 0);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
247 while(m>>=1){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
248 put_cabac_bypass(c, v&m);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
249 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
250 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
251
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
252 if(is_signed)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
253 put_cabac_bypass(c, sign);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
254 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
255 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
256
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
257 static void refill(CABACContext *c){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
258 #if CABAC_BITS == 16
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
259 c->low+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
260 #else
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
261 c->low+= c->bytestream[0]<<1;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
262 #endif
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
263 c->low -= CABAC_MASK;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
264 c->bytestream+= CABAC_BITS/8;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
265 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
266
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
267 static void refill2(CABACContext *c){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
268 int i, x;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
269
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
270 x= c->low ^ (c->low-1);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
271 i= 7 - ff_h264_norm_shift[x>>(CABAC_BITS-1)];
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
272
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
273 x= -CABAC_MASK;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
274
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
275 #if CABAC_BITS == 16
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
276 x+= (c->bytestream[0]<<9) + (c->bytestream[1]<<1);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
277 #else
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
278 x+= c->bytestream[0]<<1;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
279 #endif
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
280
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
281 c->low += x<<i;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
282 c->bytestream+= CABAC_BITS/8;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
283 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
284
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
285 static inline void renorm_cabac_decoder(CABACContext *c){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
286 while(c->range < 0x100){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
287 c->range+= c->range;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
288 c->low+= c->low;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
289 if(!(c->low & CABAC_MASK))
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
290 refill(c);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
291 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
292 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
293
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
294 static inline void renorm_cabac_decoder_once(CABACContext *c){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
295 #ifdef ARCH_X86_DISABLED
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
296 int temp;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
297 #if 0
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
298 //P3:683 athlon:475
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
299 asm(
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
300 "lea -0x100(%0), %2 \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
301 "shr $31, %2 \n\t" //FIXME 31->63 for x86-64
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
302 "shl %%cl, %0 \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
303 "shl %%cl, %1 \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
304 : "+r"(c->range), "+r"(c->low), "+c"(temp)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
305 );
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
306 #elif 0
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
307 //P3:680 athlon:474
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
308 asm(
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
309 "cmp $0x100, %0 \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
310 "setb %%cl \n\t" //FIXME 31->63 for x86-64
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
311 "shl %%cl, %0 \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
312 "shl %%cl, %1 \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
313 : "+r"(c->range), "+r"(c->low), "+c"(temp)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
314 );
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
315 #elif 1
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
316 int temp2;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
317 //P3:665 athlon:517
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
318 asm(
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
319 "lea -0x100(%0), %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
320 "cdq \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
321 "mov %0, %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
322 "and %%edx, %0 \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
323 "and %1, %%edx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
324 "add %%eax, %0 \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
325 "add %%edx, %1 \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
326 : "+r"(c->range), "+r"(c->low), "+a"(temp), "+d"(temp2)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
327 );
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
328 #elif 0
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
329 int temp2;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
330 //P3:673 athlon:509
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
331 asm(
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
332 "cmp $0x100, %0 \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
333 "sbb %%edx, %%edx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
334 "mov %0, %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
335 "and %%edx, %0 \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
336 "and %1, %%edx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
337 "add %%eax, %0 \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
338 "add %%edx, %1 \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
339 : "+r"(c->range), "+r"(c->low), "+a"(temp), "+d"(temp2)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
340 );
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
341 #else
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
342 int temp2;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
343 //P3:677 athlon:511
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
344 asm(
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
345 "cmp $0x100, %0 \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
346 "lea (%0, %0), %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
347 "lea (%1, %1), %%edx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
348 "cmovb %%eax, %0 \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
349 "cmovb %%edx, %1 \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
350 : "+r"(c->range), "+r"(c->low), "+a"(temp), "+d"(temp2)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
351 );
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
352 #endif
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
353 #else
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
354 //P3:675 athlon:476
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
355 int shift= (uint32_t)(c->range - 0x100)>>31;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
356 c->range<<= shift;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
357 c->low <<= shift;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
358 #endif
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
359 if(!(c->low & CABAC_MASK))
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
360 refill(c);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
361 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
362
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
363 static int always_inline get_cabac_inline(CABACContext *c, uint8_t * const state){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
364 //FIXME gcc generates duplicate load/stores for c->low and c->range
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
365 #define LOW "0"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
366 #define RANGE "4"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
367 #define BYTESTART "12"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
368 #define BYTE "16"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
369 #define BYTEEND "20"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
370 #if defined(ARCH_X86) && !(defined(PIC) && defined(__GNUC__))
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
371 int bit;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
372
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
373 #ifndef BRANCHLESS_CABAC_DECODER
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
374 asm volatile(
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
375 "movzbl (%1), %0 \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
376 "movl "RANGE "(%2), %%ebx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
377 "movl "RANGE "(%2), %%edx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
378 "andl $0xC0, %%ebx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
379 "movzbl "MANGLE(ff_h264_lps_range)"(%0, %%ebx, 2), %%esi\n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
380 "movl "LOW "(%2), %%ebx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
381 //eax:state ebx:low, edx:range, esi:RangeLPS
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
382 "subl %%esi, %%edx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
383 "movl %%edx, %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
384 "shll $17, %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
385 "cmpl %%ecx, %%ebx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
386 " ja 1f \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
387
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
388 #if 1
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
389 //athlon:4067 P3:4110
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
390 "lea -0x100(%%edx), %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
391 "shr $31, %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
392 "shl %%cl, %%edx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
393 "shl %%cl, %%ebx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
394 #else
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
395 //athlon:4057 P3:4130
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
396 "cmp $0x100, %%edx \n\t" //FIXME avoidable
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
397 "setb %%cl \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
398 "shl %%cl, %%edx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
399 "shl %%cl, %%ebx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
400 #endif
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
401 "movzbl "MANGLE(ff_h264_mps_state)"(%0), %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
402 "movb %%cl, (%1) \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
403 //eax:state ebx:low, edx:range, esi:RangeLPS
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
404 "test %%bx, %%bx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
405 " jnz 2f \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
406 "movl "BYTE "(%2), %%esi \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
407 "subl $0xFFFF, %%ebx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
408 "movzwl (%%esi), %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
409 "bswap %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
410 "shrl $15, %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
411 "addl $2, %%esi \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
412 "addl %%ecx, %%ebx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
413 "movl %%esi, "BYTE "(%2) \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
414 "jmp 2f \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
415 "1: \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
416 //eax:state ebx:low, edx:range, esi:RangeLPS
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
417 "subl %%ecx, %%ebx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
418 "movl %%esi, %%edx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
419 "movzbl " MANGLE(ff_h264_norm_shift) "(%%esi), %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
420 "shll %%cl, %%ebx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
421 "shll %%cl, %%edx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
422 "movzbl "MANGLE(ff_h264_lps_state)"(%0), %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
423 "movb %%cl, (%1) \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
424 "addl $1, %0 \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
425 "test %%bx, %%bx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
426 " jnz 2f \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
427
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
428 "movl "BYTE "(%2), %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
429 "movzwl (%%ecx), %%esi \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
430 "bswap %%esi \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
431 "shrl $15, %%esi \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
432 "subl $0xFFFF, %%esi \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
433 "addl $2, %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
434 "movl %%ecx, "BYTE "(%2) \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
435
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
436 "leal -1(%%ebx), %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
437 "xorl %%ebx, %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
438 "shrl $15, %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
439 "movzbl " MANGLE(ff_h264_norm_shift) "(%%ecx), %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
440 "neg %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
441 "add $7, %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
442
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
443 "shll %%cl , %%esi \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
444 "addl %%esi, %%ebx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
445 "2: \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
446 "movl %%edx, "RANGE "(%2) \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
447 "movl %%ebx, "LOW "(%2) \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
448 :"=&a"(bit) //FIXME this is fragile gcc either runs out of registers or misscompiles it (for example if "+a"(bit) or "+m"(*state) is used
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
449 :"r"(state), "r"(c)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
450 : "%ecx", "%ebx", "%edx", "%esi", "memory"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
451 );
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
452 bit&=1;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
453 #else /* BRANCHLESS_CABAC_DECODER */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
454
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
455
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
456 #if defined CMOV_IS_FAST
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
457 #define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
458 "mov "tmp" , %%ecx \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
459 "shl $17 , "tmp" \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
460 "cmp "low" , "tmp" \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
461 "cmova %%ecx , "range" \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
462 "sbb %%ecx , %%ecx \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
463 "and %%ecx , "tmp" \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
464 "sub "tmp" , "low" \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
465 "xor %%ecx , "ret" \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
466 #else /* CMOV_IS_FAST */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
467 #define BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
468 "mov "tmp" , %%ecx \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
469 "shl $17 , "tmp" \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
470 "sub "low" , "tmp" \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
471 "sar $31 , "tmp" \n\t" /*lps_mask*/\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
472 "sub %%ecx , "range" \n\t" /*RangeLPS - range*/\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
473 "and "tmp" , "range" \n\t" /*(RangeLPS - range)&lps_mask*/\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
474 "add %%ecx , "range" \n\t" /*new range*/\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
475 "shl $17 , %%ecx \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
476 "and "tmp" , %%ecx \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
477 "sub %%ecx , "low" \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
478 "xor "tmp" , "ret" \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
479 #endif /* CMOV_IS_FAST */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
480
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
481
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
482 #define BRANCHLESS_GET_CABAC(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
483 "movzbl "statep" , "ret" \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
484 "mov "range" , "tmp" \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
485 "and $0xC0 , "range" \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
486 "movzbl "MANGLE(ff_h264_lps_range)"("ret", "range", 2), "range" \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
487 "sub "range" , "tmp" \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
488 BRANCHLESS_GET_CABAC_UPDATE(ret, cabac, statep, low, lowword, range, tmp, tmpbyte)\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
489 "movzbl " MANGLE(ff_h264_norm_shift) "("range"), %%ecx \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
490 "shl %%cl , "range" \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
491 "movzbl "MANGLE(ff_h264_mlps_state)"+128("ret"), "tmp" \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
492 "mov "tmpbyte" , "statep" \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
493 "shl %%cl , "low" \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
494 "test "lowword" , "lowword" \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
495 " jnz 1f \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
496 "mov "BYTE"("cabac"), %%ecx \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
497 "movzwl (%%ecx) , "tmp" \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
498 "bswap "tmp" \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
499 "shr $15 , "tmp" \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
500 "sub $0xFFFF , "tmp" \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
501 "add $2 , %%ecx \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
502 "mov %%ecx , "BYTE "("cabac") \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
503 "lea -1("low") , %%ecx \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
504 "xor "low" , %%ecx \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
505 "shr $15 , %%ecx \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
506 "movzbl " MANGLE(ff_h264_norm_shift) "(%%ecx), %%ecx \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
507 "neg %%ecx \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
508 "add $7 , %%ecx \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
509 "shl %%cl , "tmp" \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
510 "add "tmp" , "low" \n\t"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
511 "1: \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
512
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
513 asm volatile(
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
514 "movl "RANGE "(%2), %%esi \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
515 "movl "LOW "(%2), %%ebx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
516 BRANCHLESS_GET_CABAC("%0", "%2", "(%1)", "%%ebx", "%%bx", "%%esi", "%%edx", "%%dl")
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
517 "movl %%esi, "RANGE "(%2) \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
518 "movl %%ebx, "LOW "(%2) \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
519
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
520 :"=&a"(bit)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
521 :"r"(state), "r"(c)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
522 : "%ecx", "%ebx", "%edx", "%esi", "memory"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
523 );
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
524 bit&=1;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
525 #endif /* BRANCHLESS_CABAC_DECODER */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
526 #else /* defined(ARCH_X86) && !(defined(PIC) && defined(__GNUC__)) */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
527 int s = *state;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
528 int RangeLPS= ff_h264_lps_range[2*(c->range&0xC0) + s];
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
529 int bit, lps_mask attribute_unused;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
530
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
531 c->range -= RangeLPS;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
532 #ifndef BRANCHLESS_CABAC_DECODER
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
533 if(c->low < (c->range<<17)){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
534 bit= s&1;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
535 *state= ff_h264_mps_state[s];
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
536 renorm_cabac_decoder_once(c);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
537 }else{
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
538 bit= ff_h264_norm_shift[RangeLPS];
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
539 c->low -= (c->range<<17);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
540 *state= ff_h264_lps_state[s];
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
541 c->range = RangeLPS<<bit;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
542 c->low <<= bit;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
543 bit= (s&1)^1;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
544
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
545 if(!(c->low & 0xFFFF)){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
546 refill2(c);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
547 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
548 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
549 #else /* BRANCHLESS_CABAC_DECODER */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
550 lps_mask= ((c->range<<17) - c->low)>>31;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
551
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
552 c->low -= (c->range<<17) & lps_mask;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
553 c->range += (RangeLPS - c->range) & lps_mask;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
554
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
555 s^=lps_mask;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
556 *state= (ff_h264_mlps_state+128)[s];
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
557 bit= s&1;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
558
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
559 lps_mask= ff_h264_norm_shift[c->range];
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
560 c->range<<= lps_mask;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
561 c->low <<= lps_mask;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
562 if(!(c->low & CABAC_MASK))
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
563 refill2(c);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
564 #endif /* BRANCHLESS_CABAC_DECODER */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
565 #endif /* defined(ARCH_X86) && !(defined(PIC) && defined(__GNUC__)) */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
566 return bit;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
567 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
568
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
569 static int __attribute((noinline)) get_cabac_noinline(CABACContext *c, uint8_t * const state){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
570 return get_cabac_inline(c,state);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
571 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
572
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
573 static int get_cabac(CABACContext *c, uint8_t * const state){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
574 return get_cabac_inline(c,state);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
575 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
576
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
577 static int get_cabac_bypass(CABACContext *c){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
578 #if 0 //not faster
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
579 int bit;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
580 asm volatile(
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
581 "movl "RANGE "(%1), %%ebx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
582 "movl "LOW "(%1), %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
583 "shl $17, %%ebx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
584 "add %%eax, %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
585 "sub %%ebx, %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
586 "cdq \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
587 "and %%edx, %%ebx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
588 "add %%ebx, %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
589 "test %%ax, %%ax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
590 " jnz 1f \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
591 "movl "BYTE "(%1), %%ebx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
592 "subl $0xFFFF, %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
593 "movzwl (%%ebx), %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
594 "bswap %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
595 "shrl $15, %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
596 "addl $2, %%ebx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
597 "addl %%ecx, %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
598 "movl %%ebx, "BYTE "(%1) \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
599 "1: \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
600 "movl %%eax, "LOW "(%1) \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
601
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
602 :"=&d"(bit)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
603 :"r"(c)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
604 : "%eax", "%ebx", "%ecx", "memory"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
605 );
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
606 return bit+1;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
607 #else
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
608 int range;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
609 c->low += c->low;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
610
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
611 if(!(c->low & CABAC_MASK))
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
612 refill(c);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
613
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
614 range= c->range<<17;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
615 if(c->low < range){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
616 return 0;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
617 }else{
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
618 c->low -= range;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
619 return 1;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
620 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
621 #endif
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
622 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
623
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
624
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
625 static always_inline int get_cabac_bypass_sign(CABACContext *c, int val){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
626 #ifdef ARCH_X86
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
627 asm volatile(
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
628 "movl "RANGE "(%1), %%ebx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
629 "movl "LOW "(%1), %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
630 "shl $17, %%ebx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
631 "add %%eax, %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
632 "sub %%ebx, %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
633 "cdq \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
634 "and %%edx, %%ebx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
635 "add %%ebx, %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
636 "xor %%edx, %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
637 "sub %%edx, %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
638 "test %%ax, %%ax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
639 " jnz 1f \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
640 "movl "BYTE "(%1), %%ebx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
641 "subl $0xFFFF, %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
642 "movzwl (%%ebx), %%edx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
643 "bswap %%edx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
644 "shrl $15, %%edx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
645 "addl $2, %%ebx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
646 "addl %%edx, %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
647 "movl %%ebx, "BYTE "(%1) \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
648 "1: \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
649 "movl %%eax, "LOW "(%1) \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
650
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
651 :"+c"(val)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
652 :"r"(c)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
653 : "%eax", "%ebx", "%edx", "memory"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
654 );
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
655 return val;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
656 #else
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
657 int range, mask;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
658 c->low += c->low;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
659
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
660 if(!(c->low & CABAC_MASK))
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
661 refill(c);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
662
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
663 range= c->range<<17;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
664 c->low -= range;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
665 mask= c->low >> 31;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
666 range &= mask;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
667 c->low += range;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
668 return (val^mask)-mask;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
669 #endif
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
670 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
671
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
672 //FIXME the x86 code from this file should be moved into i386/h264 or cabac something.c/h (note ill kill you if you move my code away from under my fingers before iam finished with it!)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
673 //FIXME use some macros to avoid duplicatin get_cabac (cant be done yet as that would make optimization work hard)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
674 #ifdef ARCH_X86
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
675 static int decode_significance_x86(CABACContext *c, int max_coeff, uint8_t *significant_coeff_ctx_base, int *index){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
676 void *end= significant_coeff_ctx_base + max_coeff - 1;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
677 int minusstart= -(int)significant_coeff_ctx_base;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
678 int minusindex= 4-(int)index;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
679 int coeff_count;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
680 asm volatile(
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
681 "movl "RANGE "(%3), %%esi \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
682 "movl "LOW "(%3), %%ebx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
683
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
684 "2: \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
685
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
686 BRANCHLESS_GET_CABAC("%%edx", "%3", "(%1)", "%%ebx", "%%bx", "%%esi", "%%eax", "%%al")
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
687
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
688 "test $1, %%edx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
689 " jz 3f \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
690
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
691 BRANCHLESS_GET_CABAC("%%edx", "%3", "61(%1)", "%%ebx", "%%bx", "%%esi", "%%eax", "%%al")
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
692
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
693 "movl %2, %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
694 "movl %4, %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
695 "addl %1, %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
696 "movl %%ecx, (%%eax) \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
697
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
698 "test $1, %%edx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
699 " jnz 4f \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
700
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
701 "addl $4, %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
702 "movl %%eax, %2 \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
703
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
704 "3: \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
705 "addl $1, %1 \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
706 "cmpl %5, %1 \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
707 " jb 2b \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
708 "movl %2, %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
709 "movl %4, %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
710 "addl %1, %%ecx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
711 "movl %%ecx, (%%eax) \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
712 "4: \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
713 "addl %6, %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
714 "shr $2, %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
715
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
716 "movl %%esi, "RANGE "(%3) \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
717 "movl %%ebx, "LOW "(%3) \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
718 :"=&a"(coeff_count), "+r"(significant_coeff_ctx_base), "+m"(index)\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
719 :"r"(c), "m"(minusstart), "m"(end), "m"(minusindex)\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
720 : "%ecx", "%ebx", "%edx", "%esi", "memory"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
721 );
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
722 return coeff_count;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
723 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
724
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
725 static int decode_significance_8x8_x86(CABACContext *c, uint8_t *significant_coeff_ctx_base, int *index, uint8_t *sig_off){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
726 int minusindex= 4-(int)index;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
727 int coeff_count;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
728 int last=0;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
729 asm volatile(
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
730 "movl "RANGE "(%3), %%esi \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
731 "movl "LOW "(%3), %%ebx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
732
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
733 "mov %1, %%edi \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
734 "2: \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
735
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
736 "mov %6, %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
737 "movzbl (%%eax, %%edi), %%edi \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
738 "add %5, %%edi \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
739
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
740 BRANCHLESS_GET_CABAC("%%edx", "%3", "(%%edi)", "%%ebx", "%%bx", "%%esi", "%%eax", "%%al")
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
741
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
742 "mov %1, %%edi \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
743 "test $1, %%edx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
744 " jz 3f \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
745
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
746 "movzbl "MANGLE(last_coeff_flag_offset_8x8)"(%%edi), %%edi\n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
747 "add %5, %%edi \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
748
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
749 BRANCHLESS_GET_CABAC("%%edx", "%3", "15(%%edi)", "%%ebx", "%%bx", "%%esi", "%%eax", "%%al")
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
750
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
751 "movl %2, %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
752 "mov %1, %%edi \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
753 "movl %%edi, (%%eax) \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
754
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
755 "test $1, %%edx \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
756 " jnz 4f \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
757
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
758 "addl $4, %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
759 "movl %%eax, %2 \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
760
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
761 "3: \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
762 "addl $1, %%edi \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
763 "mov %%edi, %1 \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
764 "cmpl $63, %%edi \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
765 " jb 2b \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
766 "movl %2, %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
767 "movl %%edi, (%%eax) \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
768 "4: \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
769 "addl %4, %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
770 "shr $2, %%eax \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
771
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
772 "movl %%esi, "RANGE "(%3) \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
773 "movl %%ebx, "LOW "(%3) \n\t"
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
774 :"=&a"(coeff_count),"+m"(last), "+m"(index)\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
775 :"r"(c), "m"(minusindex), "m"(significant_coeff_ctx_base), "m"(sig_off)\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
776 : "%ecx", "%ebx", "%edx", "%esi", "%edi", "memory"\
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
777 );
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
778 return coeff_count;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
779 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
780 #endif
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
781
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
782 /**
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
783 *
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
784 * @return the number of bytes read or 0 if no end
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
785 */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
786 static int get_cabac_terminate(CABACContext *c){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
787 c->range -= 2;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
788 if(c->low < c->range<<17){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
789 renorm_cabac_decoder_once(c);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
790 return 0;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
791 }else{
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
792 return c->bytestream - c->bytestream_start;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
793 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
794 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
795
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
796 /**
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
797 * get (truncated) unnary binarization.
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
798 */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
799 static int get_cabac_u(CABACContext *c, uint8_t * state, int max, int max_index, int truncated){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
800 int i;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
801
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
802 for(i=0; i<max; i++){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
803 if(get_cabac(c, state)==0)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
804 return i;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
805
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
806 if(i< max_index) state++;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
807 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
808
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
809 return truncated ? max : -1;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
810 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
811
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
812 /**
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
813 * get unary exp golomb k-th order binarization.
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
814 */
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
815 static int get_cabac_ueg(CABACContext *c, uint8_t * state, int max, int is_signed, int k, int max_index){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
816 int i, v;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
817 int m= 1<<k;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
818
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
819 if(get_cabac(c, state)==0)
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
820 return 0;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
821
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
822 if(0 < max_index) state++;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
823
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
824 for(i=1; i<max; i++){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
825 if(get_cabac(c, state)==0){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
826 if(is_signed && get_cabac_bypass(c)){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
827 return -i;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
828 }else
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
829 return i;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
830 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
831
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
832 if(i < max_index) state++;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
833 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
834
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
835 while(get_cabac_bypass(c)){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
836 i+= m;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
837 m+= m;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
838 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
839
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
840 v=0;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
841 while(m>>=1){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
842 v+= v + get_cabac_bypass(c);
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
843 }
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
844 i += v;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
845
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
846 if(is_signed && get_cabac_bypass(c)){
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
847 return -i;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
848 }else
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
849 return i;
e8776388b02a [svn] - add ffmpeg
nenolod
parents:
diff changeset
850 }