Mercurial > libavcodec.hg
annotate cabac.c @ 3295:8c9825dbea20 libavcodec
add outcommented chunk of code to handle stuffing MBs at the end of slices (IMHO the standard doesnt allow this and there are no real world files which need it)
author | michael |
---|---|
date | Mon, 08 May 2006 13:44:54 +0000 |
parents | 0b546eab515d |
children | c8c591fe26f8 |
rev | line source |
---|---|
1287 | 1 /* |
2 * H.26L/H.264/AVC/JVT/14496-10/... encoder/decoder | |
3 * Copyright (c) 2003 Michael Niedermayer <michaelni@gmx.at> | |
4 * | |
5 * This library is free software; you can redistribute it and/or | |
6 * modify it under the terms of the GNU Lesser General Public | |
7 * License as published by the Free Software Foundation; either | |
8 * version 2 of the License, or (at your option) any later version. | |
9 * | |
10 * This library is distributed in the hope that it will be useful, | |
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | |
13 * Lesser General Public License for more details. | |
14 * | |
15 * You should have received a copy of the GNU Lesser General Public | |
16 * License along with this library; if not, write to the Free Software | |
3036
0b546eab515d
Update licensing information: The FSF changed postal address.
diego
parents:
2967
diff
changeset
|
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
1287 | 18 * |
19 */ | |
20 | |
21 /** | |
22 * @file cabac.c | |
23 * Context Adaptive Binary Arithmetic Coder. | |
24 */ | |
25 | |
26 #include <string.h> | |
27 | |
28 #include "common.h" | |
2398
582e635cfa08
common.c -> bitstream.c (and the single non bitstream func -> utils.c)
michael
parents:
2323
diff
changeset
|
29 #include "bitstream.h" |
1287 | 30 #include "cabac.h" |
31 | |
32 const uint8_t ff_h264_lps_range[64][4]= { | |
33 {128,176,208,240}, {128,167,197,227}, {128,158,187,216}, {123,150,178,205}, | |
34 {116,142,169,195}, {111,135,160,185}, {105,128,152,175}, {100,122,144,166}, | |
35 { 95,116,137,158}, { 90,110,130,150}, { 85,104,123,142}, { 81, 99,117,135}, | |
36 { 77, 94,111,128}, { 73, 89,105,122}, { 69, 85,100,116}, { 66, 80, 95,110}, | |
37 { 62, 76, 90,104}, { 59, 72, 86, 99}, { 56, 69, 81, 94}, { 53, 65, 77, 89}, | |
38 { 51, 62, 73, 85}, { 48, 59, 69, 80}, { 46, 56, 66, 76}, { 43, 53, 63, 72}, | |
39 { 41, 50, 59, 69}, { 39, 48, 56, 65}, { 37, 45, 54, 62}, { 35, 43, 51, 59}, | |
40 { 33, 41, 48, 56}, { 32, 39, 46, 53}, { 30, 37, 43, 50}, { 29, 35, 41, 48}, | |
41 { 27, 33, 39, 45}, { 26, 31, 37, 43}, { 24, 30, 35, 41}, { 23, 28, 33, 39}, | |
42 { 22, 27, 32, 37}, { 21, 26, 30, 35}, { 20, 24, 29, 33}, { 19, 23, 27, 31}, | |
43 { 18, 22, 26, 30}, { 17, 21, 25, 28}, { 16, 20, 23, 27}, { 15, 19, 22, 25}, | |
44 { 14, 18, 21, 24}, { 14, 17, 20, 23}, { 13, 16, 19, 22}, { 12, 15, 18, 21}, | |
45 { 12, 14, 17, 20}, { 11, 14, 16, 19}, { 11, 13, 15, 18}, { 10, 12, 15, 17}, | |
46 { 10, 12, 14, 16}, { 9, 11, 13, 15}, { 9, 11, 12, 14}, { 8, 10, 12, 14}, | |
47 { 8, 9, 11, 13}, { 7, 9, 11, 12}, { 7, 9, 10, 12}, { 7, 8, 10, 11}, | |
48 { 6, 8, 9, 11}, { 6, 7, 9, 10}, { 6, 7, 8, 9}, { 2, 2, 2, 2}, | |
49 }; | |
50 | |
51 const uint8_t ff_h264_mps_state[64]= { | |
52 1, 2, 3, 4, 5, 6, 7, 8, | |
53 9,10,11,12,13,14,15,16, | |
54 17,18,19,20,21,22,23,24, | |
55 25,26,27,28,29,30,31,32, | |
56 33,34,35,36,37,38,39,40, | |
57 41,42,43,44,45,46,47,48, | |
58 49,50,51,52,53,54,55,56, | |
59 57,58,59,60,61,62,62,63, | |
60 }; | |
61 | |
62 const uint8_t ff_h264_lps_state[64]= { | |
63 0, 0, 1, 2, 2, 4, 4, 5, | |
64 6, 7, 8, 9, 9,11,11,12, | |
65 13,13,15,15,16,16,18,18, | |
66 19,19,21,21,22,22,23,24, | |
67 24,25,26,26,27,27,28,29, | |
68 29,30,30,30,31,32,32,33, | |
69 33,33,34,34,35,35,35,36, | |
70 36,36,37,37,37,38,38,63, | |
71 }; | |
72 | |
2323 | 73 const uint8_t ff_h264_norm_shift[256]= { |
74 8,7,6,6,5,5,5,5,4,4,4,4,4,4,4,4, | |
75 3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3, | |
76 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, | |
77 2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2, | |
78 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, | |
79 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, | |
80 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, | |
81 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, | |
2967 | 82 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, |
83 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | |
84 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | |
85 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | |
86 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | |
87 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | |
88 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | |
89 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, | |
2323 | 90 }; |
91 | |
1287 | 92 /** |
93 * | |
94 * @param buf_size size of buf in bits | |
95 */ | |
96 void ff_init_cabac_encoder(CABACContext *c, uint8_t *buf, int buf_size){ | |
1522
79dddc5cd990
removed the obsolete and unused parameters of init_put_bits
alex
parents:
1300
diff
changeset
|
97 init_put_bits(&c->pb, buf, buf_size); |
1287 | 98 |
99 c->low= 0; | |
100 c->range= 0x1FE; | |
101 c->outstanding_count= 0; | |
102 #ifdef STRICT_LIMITS | |
103 c->sym_count =0; | |
104 #endif | |
2967 | 105 |
1287 | 106 c->pb.bit_left++; //avoids firstBitFlag |
107 } | |
108 | |
109 /** | |
110 * | |
111 * @param buf_size size of buf in bits | |
112 */ | |
2024
f65d87bfdd5a
some of the warning fixes by (Michael Roitzsch <mroi at users dot sourceforge dot net>)
michael
parents:
1908
diff
changeset
|
113 void ff_init_cabac_decoder(CABACContext *c, const uint8_t *buf, int buf_size){ |
2967 | 114 c->bytestream_start= |
1287 | 115 c->bytestream= buf; |
2116 | 116 c->bytestream_end= buf + buf_size; |
1287 | 117 |
2323 | 118 #if CABAC_BITS == 16 |
119 c->low = (*c->bytestream++)<<18; | |
120 c->low+= (*c->bytestream++)<<10; | |
121 #else | |
122 c->low = (*c->bytestream++)<<10; | |
123 #endif | |
124 c->low+= ((*c->bytestream++)<<2) + 2; | |
125 c->range= 0x1FE<<(CABAC_BITS + 1); | |
1287 | 126 } |
127 | |
2967 | 128 void ff_init_cabac_states(CABACContext *c, uint8_t const (*lps_range)[4], |
1287 | 129 uint8_t const *mps_state, uint8_t const *lps_state, int state_count){ |
130 int i, j; | |
2967 | 131 |
1287 | 132 for(i=0; i<state_count; i++){ |
133 for(j=0; j<4; j++){ //FIXME check if this is worth the 1 shift we save | |
2323 | 134 c->lps_range[2*i+0][j+4]= |
135 c->lps_range[2*i+1][j+4]= lps_range[i][j]; | |
1287 | 136 } |
137 | |
138 c->mps_state[2*i+0]= 2*mps_state[i]; | |
139 c->mps_state[2*i+1]= 2*mps_state[i]+1; | |
140 | |
1908
e20fd60b215c
h264 - progressive I frame CABAC support patch by (Laurent Aimar <fenrir at via dot ecp dot fr>)
michael
parents:
1522
diff
changeset
|
141 if( i ){ |
1287 | 142 c->lps_state[2*i+0]= 2*lps_state[i]; |
143 c->lps_state[2*i+1]= 2*lps_state[i]+1; | |
144 }else{ | |
145 c->lps_state[2*i+0]= 1; | |
146 c->lps_state[2*i+1]= 0; | |
147 } | |
148 } | |
149 } | |
150 | |
151 #if 0 //selftest | |
152 #define SIZE 10240 | |
2420 | 153 |
154 #include "avcodec.h" | |
155 | |
1287 | 156 int main(){ |
157 CABACContext c; | |
158 uint8_t b[9*SIZE]; | |
1290 | 159 uint8_t r[9*SIZE]; |
1287 | 160 int i; |
1290 | 161 uint8_t state[10]= {0}; |
2967 | 162 |
1287 | 163 ff_init_cabac_encoder(&c, b, SIZE); |
164 ff_init_cabac_states(&c, ff_h264_lps_range, ff_h264_mps_state, ff_h264_lps_state, 64); | |
2967 | 165 |
1287 | 166 for(i=0; i<SIZE; i++){ |
1290 | 167 r[i]= random()%7; |
1287 | 168 } |
2967 | 169 |
1287 | 170 for(i=0; i<SIZE; i++){ |
171 START_TIMER | |
1290 | 172 put_cabac_bypass(&c, r[i]&1); |
1287 | 173 STOP_TIMER("put_cabac_bypass") |
174 } | |
2967 | 175 |
1287 | 176 for(i=0; i<SIZE; i++){ |
177 START_TIMER | |
1290 | 178 put_cabac(&c, state, r[i]&1); |
1287 | 179 STOP_TIMER("put_cabac") |
180 } | |
181 | |
1290 | 182 for(i=0; i<SIZE; i++){ |
183 START_TIMER | |
184 put_cabac_u(&c, state, r[i], 6, 3, i&1); | |
185 STOP_TIMER("put_cabac_u") | |
2967 | 186 } |
1290 | 187 |
188 for(i=0; i<SIZE; i++){ | |
189 START_TIMER | |
1298 | 190 put_cabac_ueg(&c, state, r[i], 3, 0, 1, 2); |
1290 | 191 STOP_TIMER("put_cabac_ueg") |
2967 | 192 } |
193 | |
1287 | 194 put_cabac_terminate(&c, 1); |
2967 | 195 |
1287 | 196 ff_init_cabac_decoder(&c, b, SIZE); |
2967 | 197 |
1290 | 198 memset(state, 0, sizeof(state)); |
2967 | 199 |
1287 | 200 for(i=0; i<SIZE; i++){ |
201 START_TIMER | |
1290 | 202 if( (r[i]&1) != get_cabac_bypass(&c) ) |
2420 | 203 av_log(NULL, AV_LOG_ERROR, "CABAC bypass failure at %d\n", i); |
1287 | 204 STOP_TIMER("get_cabac_bypass") |
205 } | |
2967 | 206 |
1287 | 207 for(i=0; i<SIZE; i++){ |
208 START_TIMER | |
1290 | 209 if( (r[i]&1) != get_cabac(&c, state) ) |
2420 | 210 av_log(NULL, AV_LOG_ERROR, "CABAC failure at %d\n", i); |
1287 | 211 STOP_TIMER("get_cabac") |
212 } | |
2420 | 213 #if 0 |
1290 | 214 for(i=0; i<SIZE; i++){ |
215 START_TIMER | |
216 if( r[i] != get_cabac_u(&c, state, (i&1) ? 6 : 7, 3, i&1) ) | |
2420 | 217 av_log(NULL, AV_LOG_ERROR, "CABAC unary (truncated) binarization failure at %d\n", i); |
1290 | 218 STOP_TIMER("get_cabac_u") |
219 } | |
220 | |
221 for(i=0; i<SIZE; i++){ | |
222 START_TIMER | |
223 if( r[i] != get_cabac_ueg(&c, state, 3, 0, 1, 2)) | |
2420 | 224 av_log(NULL, AV_LOG_ERROR, "CABAC unary (truncated) binarization failure at %d\n", i); |
1290 | 225 STOP_TIMER("get_cabac_ueg") |
226 } | |
2420 | 227 #endif |
1287 | 228 if(!get_cabac_terminate(&c)) |
2420 | 229 av_log(NULL, AV_LOG_ERROR, "where's the Terminator?\n"); |
2967 | 230 |
1287 | 231 return 0; |
232 } | |
233 | |
234 #endif |