/src/x264/encoder/cavlc.c
Line | Count | Source |
1 | | /***************************************************************************** |
2 | | * cavlc.c: cavlc bitstream writing |
3 | | ***************************************************************************** |
4 | | * Copyright (C) 2003-2025 x264 project |
5 | | * |
6 | | * Authors: Laurent Aimar <fenrir@via.ecp.fr> |
7 | | * Loren Merritt <lorenm@u.washington.edu> |
8 | | * Fiona Glaser <fiona@x264.com> |
9 | | * |
10 | | * This program is free software; you can redistribute it and/or modify |
11 | | * it under the terms of the GNU General Public License as published by |
12 | | * the Free Software Foundation; either version 2 of the License, or |
13 | | * (at your option) any later version. |
14 | | * |
15 | | * This program is distributed in the hope that it will be useful, |
16 | | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
17 | | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
18 | | * GNU General Public License for more details. |
19 | | * |
20 | | * You should have received a copy of the GNU General Public License |
21 | | * along with this program; if not, write to the Free Software |
22 | | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111, USA. |
23 | | * |
24 | | * This program is also available under a commercial proprietary license. |
25 | | * For more information, contact us at licensing@x264.com. |
26 | | *****************************************************************************/ |
27 | | |
28 | | #include "common/common.h" |
29 | | #include "macroblock.h" |
30 | | |
31 | | #ifndef RDO_SKIP_BS |
32 | | #define RDO_SKIP_BS 0 |
33 | | #endif |
34 | | |
35 | | /* [400,420][inter,intra] */ |
36 | | static const uint8_t cbp_to_golomb[2][2][48] = |
37 | | { |
38 | | {{ 0, 1, 2, 5, 3, 6, 14, 10, 4, 15, 7, 11, 8, 12, 13, 9 }, |
39 | | { 1, 10, 11, 6, 12, 7, 14, 2, 13, 15, 8, 3, 9, 4, 5, 0 }}, |
40 | | {{ 0, 2, 3, 7, 4, 8, 17, 13, 5, 18, 9, 14, 10, 15, 16, 11, |
41 | | 1, 32, 33, 36, 34, 37, 44, 40, 35, 45, 38, 41, 39, 42, 43, 19, |
42 | | 6, 24, 25, 20, 26, 21, 46, 28, 27, 47, 22, 29, 23, 30, 31, 12 }, |
43 | | { 3, 29, 30, 17, 31, 18, 37, 8, 32, 38, 19, 9, 20, 10, 11, 2, |
44 | | 16, 33, 34, 21, 35, 22, 39, 4, 36, 40, 23, 5, 24, 6, 7, 1, |
45 | | 41, 42, 43, 25, 44, 26, 46, 12, 45, 47, 27, 13, 28, 14, 15, 0 }} |
46 | | }; |
47 | | |
48 | | static const uint8_t mb_type_b_to_golomb[3][9]= |
49 | | { |
50 | | { 4, 8, 12, 10, 6, 14, 16, 18, 20 }, /* D_16x8 */ |
51 | | { 5, 9, 13, 11, 7, 15, 17, 19, 21 }, /* D_8x16 */ |
52 | | { 1, -1, -1, -1, 2, -1, -1, -1, 3 } /* D_16x16 */ |
53 | | }; |
54 | | |
55 | | static const uint8_t subpartition_p_to_golomb[4]= |
56 | | { |
57 | | 3, 1, 2, 0 |
58 | | }; |
59 | | |
60 | | static const uint8_t subpartition_b_to_golomb[13]= |
61 | | { |
62 | | 10, 4, 5, 1, 11, 6, 7, 2, 12, 8, 9, 3, 0 |
63 | | }; |
64 | | |
65 | 0 | #define bs_write_vlc(s,v) bs_write( s, (v).i_size, (v).i_bits ) |
66 | | |
67 | | /**************************************************************************** |
68 | | * x264_cavlc_block_residual: |
69 | | ****************************************************************************/ |
70 | | static inline int cavlc_block_residual_escape( x264_t *h, int i_suffix_length, int level ) |
71 | 0 | { |
72 | 0 | bs_t *s = &h->out.bs; |
73 | 0 | static const uint16_t next_suffix[7] = { 0, 3, 6, 12, 24, 48, 0xffff }; |
74 | 0 | int i_level_prefix = 15; |
75 | 0 | int mask = level >> 31; |
76 | 0 | int abs_level = (level^mask)-mask; |
77 | 0 | int i_level_code = abs_level*2-mask-2; |
78 | 0 | if( ( i_level_code >> i_suffix_length ) < 15 ) |
79 | 0 | { |
80 | 0 | bs_write( s, (i_level_code >> i_suffix_length) + 1 + i_suffix_length, |
81 | 0 | (1<<i_suffix_length) + (i_level_code & ((1<<i_suffix_length)-1)) ); |
82 | 0 | } |
83 | 0 | else |
84 | 0 | { |
85 | 0 | i_level_code -= 15 << i_suffix_length; |
86 | 0 | if( i_suffix_length == 0 ) |
87 | 0 | i_level_code -= 15; |
88 | | |
89 | | /* If the prefix size exceeds 15, High Profile is required. */ |
90 | 0 | if( i_level_code >= 1<<12 ) |
91 | 0 | { |
92 | 0 | if( h->sps->i_profile_idc >= PROFILE_HIGH ) |
93 | 0 | { |
94 | 0 | while( i_level_code >= 1<<(i_level_prefix-3) ) |
95 | 0 | { |
96 | 0 | i_level_code -= 1<<(i_level_prefix-3); |
97 | 0 | i_level_prefix++; |
98 | 0 | } |
99 | 0 | } |
100 | 0 | else |
101 | 0 | { |
102 | | #if RDO_SKIP_BS |
103 | | /* Weight highly against overflows. */ |
104 | | s->i_bits_encoded += 2000; |
105 | | #else |
106 | | /* We've had an overflow; note it down and re-encode the MB later. */ |
107 | | h->mb.b_overflow = 1; |
108 | | #endif |
109 | 0 | } |
110 | 0 | } |
111 | 0 | bs_write( s, i_level_prefix + 1, 1 ); |
112 | 0 | bs_write( s, i_level_prefix - 3, i_level_code & ((1<<(i_level_prefix-3))-1) ); |
113 | 0 | } |
114 | 0 | if( i_suffix_length == 0 ) |
115 | 0 | i_suffix_length++; |
116 | 0 | if( abs_level > next_suffix[i_suffix_length] ) |
117 | 0 | i_suffix_length++; |
118 | 0 | return i_suffix_length; |
119 | 0 | } Unexecuted instantiation: analyse.c:cavlc_block_residual_escape Unexecuted instantiation: cavlc.c:cavlc_block_residual_escape |
120 | | |
121 | | static int cavlc_block_residual_internal( x264_t *h, int ctx_block_cat, dctcoef *l, int nC ) |
122 | 0 | { |
123 | 0 | bs_t *s = &h->out.bs; |
124 | 0 | static const uint8_t ctz_index[8] = {3,0,1,0,2,0,1,0}; |
125 | 0 | static const uint8_t count_cat[14] = {16, 15, 16, 0, 15, 64, 16, 15, 16, 64, 16, 15, 16, 64}; |
126 | 0 | x264_run_level_t runlevel; |
127 | 0 | int i_total, i_trailing, i_total_zero, i_suffix_length; |
128 | 0 | unsigned int i_sign; |
129 | | |
130 | | /* level and run and total */ |
131 | 0 | i_total = h->quantf.coeff_level_run[ctx_block_cat]( l, &runlevel ); |
132 | 0 | x264_prefetch( &x264_run_before[runlevel.mask] ); |
133 | 0 | i_total_zero = runlevel.last + 1 - i_total; |
134 | | |
135 | | /* branchless i_trailing calculation */ |
136 | 0 | runlevel.level[i_total+0] = 2; |
137 | 0 | runlevel.level[i_total+1] = 2; |
138 | 0 | i_trailing = ((((runlevel.level[0]+1) | (1-runlevel.level[0])) >> 31) & 1) // abs(runlevel.level[0])>1 |
139 | 0 | | ((((runlevel.level[1]+1) | (1-runlevel.level[1])) >> 31) & 2) |
140 | 0 | | ((((runlevel.level[2]+1) | (1-runlevel.level[2])) >> 31) & 4); |
141 | 0 | i_trailing = ctz_index[i_trailing]; |
142 | 0 | i_sign = ((runlevel.level[2] >> 31) & 1) |
143 | 0 | | ((runlevel.level[1] >> 31) & 2) |
144 | 0 | | ((runlevel.level[0] >> 31) & 4); |
145 | 0 | i_sign >>= 3-i_trailing; |
146 | | |
147 | | /* total/trailing */ |
148 | 0 | bs_write_vlc( s, x264_coeff_token[nC][i_total-1][i_trailing] ); |
149 | |
|
150 | 0 | i_suffix_length = i_total > 10 && i_trailing < 3; |
151 | 0 | bs_write( s, i_trailing, i_sign ); |
152 | |
|
153 | 0 | if( i_trailing < i_total ) |
154 | 0 | { |
155 | 0 | int val = runlevel.level[i_trailing]; |
156 | 0 | int val_original = runlevel.level[i_trailing]+LEVEL_TABLE_SIZE/2; |
157 | 0 | val -= ((val>>31)|1) & -(i_trailing < 3); /* as runlevel.level[i] can't be 1 for the first one if i_trailing < 3 */ |
158 | 0 | val += LEVEL_TABLE_SIZE/2; |
159 | |
|
160 | 0 | if( (unsigned)val_original < LEVEL_TABLE_SIZE ) |
161 | 0 | { |
162 | 0 | bs_write_vlc( s, x264_level_token[i_suffix_length][val] ); |
163 | 0 | i_suffix_length = x264_level_token[i_suffix_length][val_original].i_next; |
164 | 0 | } |
165 | 0 | else |
166 | 0 | i_suffix_length = cavlc_block_residual_escape( h, i_suffix_length, val-LEVEL_TABLE_SIZE/2 ); |
167 | 0 | for( int i = i_trailing+1; i < i_total; i++ ) |
168 | 0 | { |
169 | 0 | val = runlevel.level[i] + LEVEL_TABLE_SIZE/2; |
170 | 0 | if( (unsigned)val < LEVEL_TABLE_SIZE ) |
171 | 0 | { |
172 | 0 | bs_write_vlc( s, x264_level_token[i_suffix_length][val] ); |
173 | 0 | i_suffix_length = x264_level_token[i_suffix_length][val].i_next; |
174 | 0 | } |
175 | 0 | else |
176 | 0 | i_suffix_length = cavlc_block_residual_escape( h, i_suffix_length, val-LEVEL_TABLE_SIZE/2 ); |
177 | 0 | } |
178 | 0 | } |
179 | |
|
180 | 0 | if( ctx_block_cat == DCT_CHROMA_DC ) |
181 | 0 | { |
182 | 0 | if( i_total < 8>>CHROMA_V_SHIFT ) |
183 | 0 | { |
184 | 0 | vlc_t total_zeros = CHROMA_FORMAT == CHROMA_420 ? x264_total_zeros_2x2_dc[i_total-1][i_total_zero] |
185 | 0 | : x264_total_zeros_2x4_dc[i_total-1][i_total_zero]; |
186 | 0 | bs_write_vlc( s, total_zeros ); |
187 | 0 | } |
188 | 0 | } |
189 | 0 | else if( (uint8_t)i_total < count_cat[ctx_block_cat] ) |
190 | 0 | bs_write_vlc( s, x264_total_zeros[i_total-1][i_total_zero] ); |
191 | |
|
192 | 0 | int zero_run_code = x264_run_before[runlevel.mask]; |
193 | 0 | bs_write( s, zero_run_code&0x1f, zero_run_code>>5 ); |
194 | |
|
195 | 0 | return i_total; |
196 | 0 | } Unexecuted instantiation: analyse.c:cavlc_block_residual_internal Unexecuted instantiation: cavlc.c:cavlc_block_residual_internal |
197 | | |
198 | | static const uint8_t ct_index[17] = {0,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,3}; |
199 | | |
200 | 0 | #define x264_cavlc_block_residual(h,cat,idx,l)\ |
201 | 0 | {\ |
202 | 0 | int nC = cat == DCT_CHROMA_DC ? 5 - CHROMA_V_SHIFT\ |
203 | 0 | : ct_index[x264_mb_predict_non_zero_code( h, cat == DCT_LUMA_DC ? (idx - LUMA_DC)*16 : idx )];\ |
204 | 0 | uint8_t *nnz = &h->mb.cache.non_zero_count[x264_scan8[idx]];\ |
205 | 0 | if( !*nnz )\ |
206 | 0 | bs_write_vlc( &h->out.bs, x264_coeff0_token[nC] );\ |
207 | 0 | else\ |
208 | 0 | *nnz = cavlc_block_residual_internal(h,cat,l,nC);\ |
209 | 0 | } |
210 | | |
211 | | static void cavlc_qp_delta( x264_t *h ) |
212 | 0 | { |
213 | 0 | bs_t *s = &h->out.bs; |
214 | 0 | int i_dqp = h->mb.i_qp - h->mb.i_last_qp; |
215 | | |
216 | | /* Avoid writing a delta quant if we have an empty i16x16 block, e.g. in a completely |
217 | | * flat background area. Don't do this if it would raise the quantizer, since that could |
218 | | * cause unexpected deblocking artifacts. */ |
219 | 0 | if( h->mb.i_type == I_16x16 && !(h->mb.i_cbp_luma | h->mb.i_cbp_chroma) |
220 | 0 | && !h->mb.cache.non_zero_count[x264_scan8[LUMA_DC]] |
221 | 0 | && !h->mb.cache.non_zero_count[x264_scan8[CHROMA_DC+0]] |
222 | 0 | && !h->mb.cache.non_zero_count[x264_scan8[CHROMA_DC+1]] |
223 | 0 | && h->mb.i_qp > h->mb.i_last_qp ) |
224 | 0 | { |
225 | | #if !RDO_SKIP_BS |
226 | | h->mb.i_qp = h->mb.i_last_qp; |
227 | | #endif |
228 | 0 | i_dqp = 0; |
229 | 0 | } |
230 | |
|
231 | 0 | if( i_dqp ) |
232 | 0 | { |
233 | 0 | if( i_dqp < -(QP_MAX_SPEC+1)/2 ) |
234 | 0 | i_dqp += QP_MAX_SPEC+1; |
235 | 0 | else if( i_dqp > QP_MAX_SPEC/2 ) |
236 | 0 | i_dqp -= QP_MAX_SPEC+1; |
237 | 0 | } |
238 | 0 | bs_write_se( s, i_dqp ); |
239 | 0 | } Unexecuted instantiation: analyse.c:cavlc_qp_delta Unexecuted instantiation: cavlc.c:cavlc_qp_delta |
240 | | |
241 | | static void cavlc_mvd( x264_t *h, int i_list, int idx, int width ) |
242 | 0 | { |
243 | 0 | bs_t *s = &h->out.bs; |
244 | 0 | ALIGNED_4( int16_t mvp[2] ); |
245 | 0 | x264_mb_predict_mv( h, i_list, idx, width, mvp ); |
246 | 0 | bs_write_se( s, h->mb.cache.mv[i_list][x264_scan8[idx]][0] - mvp[0] ); |
247 | 0 | bs_write_se( s, h->mb.cache.mv[i_list][x264_scan8[idx]][1] - mvp[1] ); |
248 | 0 | } Unexecuted instantiation: analyse.c:cavlc_mvd Unexecuted instantiation: cavlc.c:cavlc_mvd |
249 | | |
250 | | static inline void cavlc_8x8_mvd( x264_t *h, int i ) |
251 | 0 | { |
252 | 0 | switch( h->mb.i_sub_partition[i] ) |
253 | 0 | { |
254 | 0 | case D_L0_8x8: |
255 | 0 | cavlc_mvd( h, 0, 4*i, 2 ); |
256 | 0 | break; |
257 | 0 | case D_L0_8x4: |
258 | 0 | cavlc_mvd( h, 0, 4*i+0, 2 ); |
259 | 0 | cavlc_mvd( h, 0, 4*i+2, 2 ); |
260 | 0 | break; |
261 | 0 | case D_L0_4x8: |
262 | 0 | cavlc_mvd( h, 0, 4*i+0, 1 ); |
263 | 0 | cavlc_mvd( h, 0, 4*i+1, 1 ); |
264 | 0 | break; |
265 | 0 | case D_L0_4x4: |
266 | 0 | cavlc_mvd( h, 0, 4*i+0, 1 ); |
267 | 0 | cavlc_mvd( h, 0, 4*i+1, 1 ); |
268 | 0 | cavlc_mvd( h, 0, 4*i+2, 1 ); |
269 | 0 | cavlc_mvd( h, 0, 4*i+3, 1 ); |
270 | 0 | break; |
271 | 0 | } |
272 | 0 | } Unexecuted instantiation: analyse.c:cavlc_8x8_mvd Unexecuted instantiation: cavlc.c:cavlc_8x8_mvd |
273 | | |
274 | | static ALWAYS_INLINE void cavlc_macroblock_luma_residual( x264_t *h, int plane_count ) |
275 | 0 | { |
276 | 0 | if( h->mb.b_transform_8x8 ) |
277 | 0 | { |
278 | | /* shuffle 8x8 dct coeffs into 4x4 lists */ |
279 | 0 | for( int p = 0; p < plane_count; p++ ) |
280 | 0 | for( int i8 = 0; i8 < 4; i8++ ) |
281 | 0 | if( h->mb.cache.non_zero_count[x264_scan8[p*16+i8*4]] ) |
282 | 0 | h->zigzagf.interleave_8x8_cavlc( h->dct.luma4x4[p*16+i8*4], h->dct.luma8x8[p*4+i8], |
283 | 0 | &h->mb.cache.non_zero_count[x264_scan8[p*16+i8*4]] ); |
284 | 0 | } |
285 | |
|
286 | 0 | for( int p = 0; p < plane_count; p++ ) |
287 | 0 | FOREACH_BIT( i8, 0, h->mb.i_cbp_luma ) |
288 | 0 | for( int i4 = 0; i4 < 4; i4++ ) |
289 | 0 | x264_cavlc_block_residual( h, DCT_LUMA_4x4, i4+i8*4+p*16, h->dct.luma4x4[i4+i8*4+p*16] ); |
290 | 0 | } Unexecuted instantiation: analyse.c:cavlc_macroblock_luma_residual Unexecuted instantiation: cavlc.c:cavlc_macroblock_luma_residual |
291 | | |
292 | | #if RDO_SKIP_BS |
293 | | static ALWAYS_INLINE void cavlc_partition_luma_residual( x264_t *h, int i8, int p ) |
294 | 0 | { |
295 | 0 | if( h->mb.b_transform_8x8 && h->mb.cache.non_zero_count[x264_scan8[i8*4+p*16]] ) |
296 | 0 | h->zigzagf.interleave_8x8_cavlc( h->dct.luma4x4[i8*4+p*16], h->dct.luma8x8[i8+p*4], |
297 | 0 | &h->mb.cache.non_zero_count[x264_scan8[i8*4+p*16]] ); |
298 | |
|
299 | 0 | if( h->mb.i_cbp_luma & (1 << i8) ) |
300 | 0 | for( int i4 = 0; i4 < 4; i4++ ) |
301 | 0 | x264_cavlc_block_residual( h, DCT_LUMA_4x4, i4+i8*4+p*16, h->dct.luma4x4[i4+i8*4+p*16] ); |
302 | 0 | } |
303 | | #endif |
304 | | |
305 | | static void cavlc_mb_header_i( x264_t *h, int i_mb_type, int i_mb_i_offset, int chroma ) |
306 | 0 | { |
307 | 0 | bs_t *s = &h->out.bs; |
308 | 0 | if( i_mb_type == I_16x16 ) |
309 | 0 | { |
310 | 0 | bs_write_ue( s, i_mb_i_offset + 1 + x264_mb_pred_mode16x16_fix[h->mb.i_intra16x16_pred_mode] + |
311 | 0 | h->mb.i_cbp_chroma * 4 + ( h->mb.i_cbp_luma == 0 ? 0 : 12 ) ); |
312 | 0 | } |
313 | 0 | else //if( i_mb_type == I_4x4 || i_mb_type == I_8x8 ) |
314 | 0 | { |
315 | 0 | int di = i_mb_type == I_8x8 ? 4 : 1; |
316 | 0 | bs_write_ue( s, i_mb_i_offset + 0 ); |
317 | 0 | if( h->pps->b_transform_8x8_mode ) |
318 | 0 | bs_write1( s, h->mb.b_transform_8x8 ); |
319 | | |
320 | | /* Prediction: Luma */ |
321 | 0 | for( int i = 0; i < 16; i += di ) |
322 | 0 | { |
323 | 0 | int i_pred = x264_mb_predict_intra4x4_mode( h, i ); |
324 | 0 | int i_mode = x264_mb_pred_mode4x4_fix( h->mb.cache.intra4x4_pred_mode[x264_scan8[i]] ); |
325 | |
|
326 | 0 | if( i_pred == i_mode ) |
327 | 0 | bs_write1( s, 1 ); /* b_prev_intra4x4_pred_mode */ |
328 | 0 | else |
329 | 0 | bs_write( s, 4, i_mode - (i_mode > i_pred) ); |
330 | 0 | } |
331 | |
|
332 | 0 | } |
333 | 0 | if( chroma ) |
334 | 0 | bs_write_ue( s, x264_mb_chroma_pred_mode_fix[h->mb.i_chroma_pred_mode] ); |
335 | 0 | } Unexecuted instantiation: analyse.c:cavlc_mb_header_i Unexecuted instantiation: cavlc.c:cavlc_mb_header_i |
336 | | |
337 | | static ALWAYS_INLINE void cavlc_mb_header_p( x264_t *h, int i_mb_type, int chroma ) |
338 | 0 | { |
339 | 0 | bs_t *s = &h->out.bs; |
340 | 0 | if( i_mb_type == P_L0 ) |
341 | 0 | { |
342 | 0 | if( h->mb.i_partition == D_16x16 ) |
343 | 0 | { |
344 | 0 | bs_write1( s, 1 ); |
345 | |
|
346 | 0 | if( h->mb.pic.i_fref[0] > 1 ) |
347 | 0 | bs_write_te( s, h->mb.pic.i_fref[0] - 1, h->mb.cache.ref[0][x264_scan8[0]] ); |
348 | 0 | cavlc_mvd( h, 0, 0, 4 ); |
349 | 0 | } |
350 | 0 | else if( h->mb.i_partition == D_16x8 ) |
351 | 0 | { |
352 | 0 | bs_write_ue( s, 1 ); |
353 | 0 | if( h->mb.pic.i_fref[0] > 1 ) |
354 | 0 | { |
355 | 0 | bs_write_te( s, h->mb.pic.i_fref[0] - 1, h->mb.cache.ref[0][x264_scan8[0]] ); |
356 | 0 | bs_write_te( s, h->mb.pic.i_fref[0] - 1, h->mb.cache.ref[0][x264_scan8[8]] ); |
357 | 0 | } |
358 | 0 | cavlc_mvd( h, 0, 0, 4 ); |
359 | 0 | cavlc_mvd( h, 0, 8, 4 ); |
360 | 0 | } |
361 | 0 | else if( h->mb.i_partition == D_8x16 ) |
362 | 0 | { |
363 | 0 | bs_write_ue( s, 2 ); |
364 | 0 | if( h->mb.pic.i_fref[0] > 1 ) |
365 | 0 | { |
366 | 0 | bs_write_te( s, h->mb.pic.i_fref[0] - 1, h->mb.cache.ref[0][x264_scan8[0]] ); |
367 | 0 | bs_write_te( s, h->mb.pic.i_fref[0] - 1, h->mb.cache.ref[0][x264_scan8[4]] ); |
368 | 0 | } |
369 | 0 | cavlc_mvd( h, 0, 0, 2 ); |
370 | 0 | cavlc_mvd( h, 0, 4, 2 ); |
371 | 0 | } |
372 | 0 | } |
373 | 0 | else if( i_mb_type == P_8x8 ) |
374 | 0 | { |
375 | 0 | int b_sub_ref; |
376 | 0 | if( (h->mb.cache.ref[0][x264_scan8[0]] | h->mb.cache.ref[0][x264_scan8[ 4]] | |
377 | 0 | h->mb.cache.ref[0][x264_scan8[8]] | h->mb.cache.ref[0][x264_scan8[12]]) == 0 ) |
378 | 0 | { |
379 | 0 | bs_write_ue( s, 4 ); |
380 | 0 | b_sub_ref = 0; |
381 | 0 | } |
382 | 0 | else |
383 | 0 | { |
384 | 0 | bs_write_ue( s, 3 ); |
385 | 0 | b_sub_ref = 1; |
386 | 0 | } |
387 | | |
388 | | /* sub mb type */ |
389 | 0 | if( h->param.analyse.inter & X264_ANALYSE_PSUB8x8 ) |
390 | 0 | for( int i = 0; i < 4; i++ ) |
391 | 0 | bs_write_ue( s, subpartition_p_to_golomb[ h->mb.i_sub_partition[i] ] ); |
392 | 0 | else |
393 | 0 | bs_write( s, 4, 0xf ); |
394 | | |
395 | | /* ref0 */ |
396 | 0 | if( b_sub_ref ) |
397 | 0 | { |
398 | 0 | bs_write_te( s, h->mb.pic.i_fref[0] - 1, h->mb.cache.ref[0][x264_scan8[0]] ); |
399 | 0 | bs_write_te( s, h->mb.pic.i_fref[0] - 1, h->mb.cache.ref[0][x264_scan8[4]] ); |
400 | 0 | bs_write_te( s, h->mb.pic.i_fref[0] - 1, h->mb.cache.ref[0][x264_scan8[8]] ); |
401 | 0 | bs_write_te( s, h->mb.pic.i_fref[0] - 1, h->mb.cache.ref[0][x264_scan8[12]] ); |
402 | 0 | } |
403 | |
|
404 | 0 | for( int i = 0; i < 4; i++ ) |
405 | 0 | cavlc_8x8_mvd( h, i ); |
406 | 0 | } |
407 | 0 | else //if( IS_INTRA( i_mb_type ) ) |
408 | 0 | cavlc_mb_header_i( h, i_mb_type, 5, chroma ); |
409 | 0 | } Unexecuted instantiation: analyse.c:cavlc_mb_header_p Unexecuted instantiation: cavlc.c:cavlc_mb_header_p |
410 | | |
411 | | static ALWAYS_INLINE void cavlc_mb_header_b( x264_t *h, int i_mb_type, int chroma ) |
412 | 0 | { |
413 | 0 | bs_t *s = &h->out.bs; |
414 | 0 | if( i_mb_type == B_8x8 ) |
415 | 0 | { |
416 | 0 | bs_write_ue( s, 22 ); |
417 | | |
418 | | /* sub mb type */ |
419 | 0 | for( int i = 0; i < 4; i++ ) |
420 | 0 | bs_write_ue( s, subpartition_b_to_golomb[ h->mb.i_sub_partition[i] ] ); |
421 | | |
422 | | /* ref */ |
423 | 0 | if( h->mb.pic.i_fref[0] > 1 ) |
424 | 0 | for( int i = 0; i < 4; i++ ) |
425 | 0 | if( x264_mb_partition_listX_table[0][ h->mb.i_sub_partition[i] ] ) |
426 | 0 | bs_write_te( s, h->mb.pic.i_fref[0] - 1, h->mb.cache.ref[0][x264_scan8[i*4]] ); |
427 | 0 | if( h->mb.pic.i_fref[1] > 1 ) |
428 | 0 | for( int i = 0; i < 4; i++ ) |
429 | 0 | if( x264_mb_partition_listX_table[1][ h->mb.i_sub_partition[i] ] ) |
430 | 0 | bs_write_te( s, h->mb.pic.i_fref[1] - 1, h->mb.cache.ref[1][x264_scan8[i*4]] ); |
431 | | |
432 | | /* mvd */ |
433 | 0 | for( int i = 0; i < 4; i++ ) |
434 | 0 | if( x264_mb_partition_listX_table[0][ h->mb.i_sub_partition[i] ] ) |
435 | 0 | cavlc_mvd( h, 0, 4*i, 2 ); |
436 | 0 | for( int i = 0; i < 4; i++ ) |
437 | 0 | if( x264_mb_partition_listX_table[1][ h->mb.i_sub_partition[i] ] ) |
438 | 0 | cavlc_mvd( h, 1, 4*i, 2 ); |
439 | 0 | } |
440 | 0 | else if( i_mb_type >= B_L0_L0 && i_mb_type <= B_BI_BI ) |
441 | 0 | { |
442 | | /* All B mode */ |
443 | | /* Motion Vector */ |
444 | 0 | const uint8_t (*b_list)[2] = x264_mb_type_list_table[i_mb_type]; |
445 | 0 | const int i_ref0_max = h->mb.pic.i_fref[0] - 1; |
446 | 0 | const int i_ref1_max = h->mb.pic.i_fref[1] - 1; |
447 | |
|
448 | 0 | bs_write_ue( s, mb_type_b_to_golomb[ h->mb.i_partition - D_16x8 ][ i_mb_type - B_L0_L0 ] ); |
449 | 0 | if( h->mb.i_partition == D_16x16 ) |
450 | 0 | { |
451 | 0 | if( i_ref0_max && b_list[0][0] ) bs_write_te( s, i_ref0_max, h->mb.cache.ref[0][x264_scan8[0]] ); |
452 | 0 | if( i_ref1_max && b_list[1][0] ) bs_write_te( s, i_ref1_max, h->mb.cache.ref[1][x264_scan8[0]] ); |
453 | 0 | if( b_list[0][0] ) cavlc_mvd( h, 0, 0, 4 ); |
454 | 0 | if( b_list[1][0] ) cavlc_mvd( h, 1, 0, 4 ); |
455 | 0 | } |
456 | 0 | else |
457 | 0 | { |
458 | 0 | if( i_ref0_max && b_list[0][0] ) bs_write_te( s, i_ref0_max, h->mb.cache.ref[0][x264_scan8[ 0]] ); |
459 | 0 | if( i_ref0_max && b_list[0][1] ) bs_write_te( s, i_ref0_max, h->mb.cache.ref[0][x264_scan8[12]] ); |
460 | 0 | if( i_ref1_max && b_list[1][0] ) bs_write_te( s, i_ref1_max, h->mb.cache.ref[1][x264_scan8[ 0]] ); |
461 | 0 | if( i_ref1_max && b_list[1][1] ) bs_write_te( s, i_ref1_max, h->mb.cache.ref[1][x264_scan8[12]] ); |
462 | 0 | if( h->mb.i_partition == D_16x8 ) |
463 | 0 | { |
464 | 0 | if( b_list[0][0] ) cavlc_mvd( h, 0, 0, 4 ); |
465 | 0 | if( b_list[0][1] ) cavlc_mvd( h, 0, 8, 4 ); |
466 | 0 | if( b_list[1][0] ) cavlc_mvd( h, 1, 0, 4 ); |
467 | 0 | if( b_list[1][1] ) cavlc_mvd( h, 1, 8, 4 ); |
468 | 0 | } |
469 | 0 | else //if( h->mb.i_partition == D_8x16 ) |
470 | 0 | { |
471 | 0 | if( b_list[0][0] ) cavlc_mvd( h, 0, 0, 2 ); |
472 | 0 | if( b_list[0][1] ) cavlc_mvd( h, 0, 4, 2 ); |
473 | 0 | if( b_list[1][0] ) cavlc_mvd( h, 1, 0, 2 ); |
474 | 0 | if( b_list[1][1] ) cavlc_mvd( h, 1, 4, 2 ); |
475 | 0 | } |
476 | 0 | } |
477 | 0 | } |
478 | 0 | else if( i_mb_type == B_DIRECT ) |
479 | 0 | bs_write1( s, 1 ); |
480 | 0 | else //if( IS_INTRA( i_mb_type ) ) |
481 | 0 | cavlc_mb_header_i( h, i_mb_type, 23, chroma ); |
482 | 0 | } Unexecuted instantiation: analyse.c:cavlc_mb_header_b Unexecuted instantiation: cavlc.c:cavlc_mb_header_b |
483 | | |
484 | | /***************************************************************************** |
485 | | * x264_macroblock_write: |
486 | | *****************************************************************************/ |
487 | | void x264_macroblock_write_cavlc( x264_t *h ) |
488 | 0 | { |
489 | 0 | bs_t *s = &h->out.bs; |
490 | 0 | const int i_mb_type = h->mb.i_type; |
491 | 0 | int plane_count = CHROMA444 ? 3 : 1; |
492 | 0 | int chroma = CHROMA_FORMAT == CHROMA_420 || CHROMA_FORMAT == CHROMA_422; |
493 | |
|
494 | | #if RDO_SKIP_BS |
495 | | s->i_bits_encoded = 0; |
496 | | #else |
497 | | const int i_mb_pos_start = bs_pos( s ); |
498 | | int i_mb_pos_tex; |
499 | | #endif |
500 | |
|
501 | 0 | if( SLICE_MBAFF |
502 | 0 | && (!(h->mb.i_mb_y & 1) || IS_SKIP(h->mb.type[h->mb.i_mb_xy - h->mb.i_mb_stride])) ) |
503 | 0 | { |
504 | 0 | bs_write1( s, MB_INTERLACED ); |
505 | | #if !RDO_SKIP_BS |
506 | 0 | h->mb.field_decoding_flag = MB_INTERLACED; |
507 | | #endif |
508 | 0 | } |
509 | |
|
510 | | #if !RDO_SKIP_BS |
511 | 0 | if( i_mb_type == I_PCM ) |
512 | 0 | { |
513 | 0 | static const uint8_t i_offsets[3] = {5,23,0}; |
514 | 0 | uint8_t *p_start = s->p_start; |
515 | 0 | bs_write_ue( s, i_offsets[h->sh.i_type] + 25 ); |
516 | 0 | i_mb_pos_tex = bs_pos( s ); |
517 | 0 | h->stat.frame.i_mv_bits += i_mb_pos_tex - i_mb_pos_start; |
518 | | |
519 | | bs_align_0( s ); |
520 | | |
521 | 0 | for( int p = 0; p < plane_count; p++ ) |
522 | 0 | for( int i = 0; i < 256; i++ ) |
523 | 0 | bs_write( s, BIT_DEPTH, h->mb.pic.p_fenc[p][i] ); |
524 | 0 | if( chroma ) |
525 | 0 | for( int ch = 1; ch < 3; ch++ ) |
526 | 0 | for( int i = 0; i < 16>>CHROMA_V_SHIFT; i++ ) |
527 | 0 | for( int j = 0; j < 8; j++ ) |
528 | 0 | bs_write( s, BIT_DEPTH, h->mb.pic.p_fenc[ch][i*FENC_STRIDE+j] ); |
529 | | |
530 | | bs_init( s, s->p, s->p_end - s->p ); |
531 | | s->p_start = p_start; |
532 | |
|
533 | 0 | h->stat.frame.i_tex_bits += bs_pos(s) - i_mb_pos_tex; |
534 | 0 | return; |
535 | 0 | } |
536 | 0 | #endif |
537 | | |
538 | 0 | if( h->sh.i_type == SLICE_TYPE_P ) |
539 | 0 | cavlc_mb_header_p( h, i_mb_type, chroma ); |
540 | 0 | else if( h->sh.i_type == SLICE_TYPE_B ) |
541 | 0 | cavlc_mb_header_b( h, i_mb_type, chroma ); |
542 | 0 | else //if( h->sh.i_type == SLICE_TYPE_I ) |
543 | 0 | cavlc_mb_header_i( h, i_mb_type, 0, chroma ); |
544 | |
|
545 | | #if !RDO_SKIP_BS |
546 | | i_mb_pos_tex = bs_pos( s ); |
547 | | h->stat.frame.i_mv_bits += i_mb_pos_tex - i_mb_pos_start; |
548 | | #endif |
549 | | |
550 | | /* Coded block pattern */ |
551 | 0 | if( i_mb_type != I_16x16 ) |
552 | 0 | bs_write_ue( s, cbp_to_golomb[chroma][IS_INTRA(i_mb_type)][(h->mb.i_cbp_chroma << 4)|h->mb.i_cbp_luma] ); |
553 | | |
554 | | /* transform size 8x8 flag */ |
555 | 0 | if( x264_mb_transform_8x8_allowed( h ) && h->mb.i_cbp_luma ) |
556 | 0 | bs_write1( s, h->mb.b_transform_8x8 ); |
557 | |
|
558 | 0 | if( i_mb_type == I_16x16 ) |
559 | 0 | { |
560 | 0 | cavlc_qp_delta( h ); |
561 | | |
562 | | /* DC Luma */ |
563 | 0 | for( int p = 0; p < plane_count; p++ ) |
564 | 0 | { |
565 | 0 | x264_cavlc_block_residual( h, DCT_LUMA_DC, LUMA_DC+p, h->dct.luma16x16_dc[p] ); |
566 | | |
567 | | /* AC Luma */ |
568 | 0 | if( h->mb.i_cbp_luma ) |
569 | 0 | for( int i = p*16; i < p*16+16; i++ ) |
570 | 0 | x264_cavlc_block_residual( h, DCT_LUMA_AC, i, h->dct.luma4x4[i]+1 ); |
571 | 0 | } |
572 | 0 | } |
573 | 0 | else if( h->mb.i_cbp_luma | h->mb.i_cbp_chroma ) |
574 | 0 | { |
575 | 0 | cavlc_qp_delta( h ); |
576 | 0 | cavlc_macroblock_luma_residual( h, plane_count ); |
577 | 0 | } |
578 | 0 | if( h->mb.i_cbp_chroma ) |
579 | 0 | { |
580 | | /* Chroma DC residual present */ |
581 | 0 | x264_cavlc_block_residual( h, DCT_CHROMA_DC, CHROMA_DC+0, h->dct.chroma_dc[0] ); |
582 | 0 | x264_cavlc_block_residual( h, DCT_CHROMA_DC, CHROMA_DC+1, h->dct.chroma_dc[1] ); |
583 | 0 | if( h->mb.i_cbp_chroma == 2 ) /* Chroma AC residual present */ |
584 | 0 | { |
585 | 0 | int step = 8 << CHROMA_V_SHIFT; |
586 | 0 | for( int i = 16; i < 3*16; i += step ) |
587 | 0 | for( int j = i; j < i+4; j++ ) |
588 | 0 | x264_cavlc_block_residual( h, DCT_CHROMA_AC, j, h->dct.luma4x4[j]+1 ); |
589 | 0 | } |
590 | 0 | } |
591 | |
|
592 | | #if !RDO_SKIP_BS |
593 | | h->stat.frame.i_tex_bits += bs_pos(s) - i_mb_pos_tex; |
594 | | #endif |
595 | 0 | } Unexecuted instantiation: analyse.c:macroblock_size_cavlc Unexecuted instantiation: x264_8_macroblock_write_cavlc Unexecuted instantiation: x264_10_macroblock_write_cavlc |
596 | | |
597 | | #if RDO_SKIP_BS |
598 | | /***************************************************************************** |
599 | | * RD only; doesn't generate a valid bitstream |
600 | | * doesn't write cbp or chroma dc (I don't know how much this matters) |
601 | | * doesn't write ref (never varies between calls, so no point in doing so) |
602 | | * only writes subpartition for p8x8, needed for sub-8x8 mode decision RDO |
603 | | * works on all partition sizes except 16x16 |
604 | | *****************************************************************************/ |
605 | | static int partition_size_cavlc( x264_t *h, int i8, int i_pixel ) |
606 | 0 | { |
607 | 0 | bs_t *s = &h->out.bs; |
608 | 0 | const int i_mb_type = h->mb.i_type; |
609 | 0 | int b_8x16 = h->mb.i_partition == D_8x16; |
610 | 0 | int plane_count = CHROMA444 ? 3 : 1; |
611 | 0 | int j; |
612 | |
|
613 | 0 | h->out.bs.i_bits_encoded = 0; |
614 | |
|
615 | 0 | if( i_mb_type == P_8x8 ) |
616 | 0 | { |
617 | 0 | cavlc_8x8_mvd( h, i8 ); |
618 | 0 | bs_write_ue( s, subpartition_p_to_golomb[ h->mb.i_sub_partition[i8] ] ); |
619 | 0 | } |
620 | 0 | else if( i_mb_type == P_L0 ) |
621 | 0 | cavlc_mvd( h, 0, 4*i8, 4>>b_8x16 ); |
622 | 0 | else if( i_mb_type > B_DIRECT && i_mb_type < B_8x8 ) |
623 | 0 | { |
624 | 0 | if( x264_mb_type_list_table[ i_mb_type ][0][!!i8] ) cavlc_mvd( h, 0, 4*i8, 4>>b_8x16 ); |
625 | 0 | if( x264_mb_type_list_table[ i_mb_type ][1][!!i8] ) cavlc_mvd( h, 1, 4*i8, 4>>b_8x16 ); |
626 | 0 | } |
627 | 0 | else //if( i_mb_type == B_8x8 ) |
628 | 0 | { |
629 | 0 | if( x264_mb_partition_listX_table[0][ h->mb.i_sub_partition[i8] ] ) |
630 | 0 | cavlc_mvd( h, 0, 4*i8, 2 ); |
631 | 0 | if( x264_mb_partition_listX_table[1][ h->mb.i_sub_partition[i8] ] ) |
632 | 0 | cavlc_mvd( h, 1, 4*i8, 2 ); |
633 | 0 | } |
634 | |
|
635 | 0 | for( j = (i_pixel < PIXEL_8x8); j >= 0; j-- ) |
636 | 0 | { |
637 | 0 | for( int p = 0; p < plane_count; p++ ) |
638 | 0 | cavlc_partition_luma_residual( h, i8, p ); |
639 | 0 | if( h->mb.i_cbp_chroma ) |
640 | 0 | { |
641 | 0 | if( CHROMA_FORMAT == CHROMA_422 ) |
642 | 0 | { |
643 | 0 | int offset = (5*i8) & 0x09; |
644 | 0 | x264_cavlc_block_residual( h, DCT_CHROMA_AC, 16+offset, h->dct.luma4x4[16+offset]+1 ); |
645 | 0 | x264_cavlc_block_residual( h, DCT_CHROMA_AC, 18+offset, h->dct.luma4x4[18+offset]+1 ); |
646 | 0 | x264_cavlc_block_residual( h, DCT_CHROMA_AC, 32+offset, h->dct.luma4x4[32+offset]+1 ); |
647 | 0 | x264_cavlc_block_residual( h, DCT_CHROMA_AC, 34+offset, h->dct.luma4x4[34+offset]+1 ); |
648 | 0 | } |
649 | 0 | else |
650 | 0 | { |
651 | 0 | x264_cavlc_block_residual( h, DCT_CHROMA_AC, 16+i8, h->dct.luma4x4[16+i8]+1 ); |
652 | 0 | x264_cavlc_block_residual( h, DCT_CHROMA_AC, 32+i8, h->dct.luma4x4[32+i8]+1 ); |
653 | 0 | } |
654 | 0 | } |
655 | 0 | i8 += x264_pixel_size[i_pixel].h >> 3; |
656 | 0 | } |
657 | |
|
658 | 0 | return h->out.bs.i_bits_encoded; |
659 | 0 | } |
660 | | |
661 | | static int subpartition_size_cavlc( x264_t *h, int i4, int i_pixel ) |
662 | 0 | { |
663 | 0 | int plane_count = CHROMA444 ? 3 : 1; |
664 | 0 | int b_8x4 = i_pixel == PIXEL_8x4; |
665 | 0 | h->out.bs.i_bits_encoded = 0; |
666 | 0 | cavlc_mvd( h, 0, i4, 1+b_8x4 ); |
667 | 0 | for( int p = 0; p < plane_count; p++ ) |
668 | 0 | { |
669 | 0 | x264_cavlc_block_residual( h, DCT_LUMA_4x4, p*16+i4, h->dct.luma4x4[p*16+i4] ); |
670 | 0 | if( i_pixel != PIXEL_4x4 ) |
671 | 0 | x264_cavlc_block_residual( h, DCT_LUMA_4x4, p*16+i4+2-b_8x4, h->dct.luma4x4[p*16+i4+2-b_8x4] ); |
672 | 0 | } |
673 | |
|
674 | 0 | return h->out.bs.i_bits_encoded; |
675 | 0 | } |
676 | | |
677 | | static int cavlc_intra4x4_pred_size( x264_t *h, int i4, int i_mode ) |
678 | 0 | { |
679 | 0 | if( x264_mb_predict_intra4x4_mode( h, i4 ) == x264_mb_pred_mode4x4_fix( i_mode ) ) |
680 | 0 | return 1; |
681 | 0 | else |
682 | 0 | return 4; |
683 | 0 | } |
684 | | |
685 | | static int partition_i8x8_size_cavlc( x264_t *h, int i8, int i_mode ) |
686 | 0 | { |
687 | 0 | int plane_count = CHROMA444 ? 3 : 1; |
688 | 0 | h->out.bs.i_bits_encoded = cavlc_intra4x4_pred_size( h, 4*i8, i_mode ); |
689 | 0 | bs_write_ue( &h->out.bs, cbp_to_golomb[!CHROMA444][1][(h->mb.i_cbp_chroma << 4)|h->mb.i_cbp_luma] ); |
690 | 0 | for( int p = 0; p < plane_count; p++ ) |
691 | 0 | cavlc_partition_luma_residual( h, i8, p ); |
692 | 0 | return h->out.bs.i_bits_encoded; |
693 | 0 | } |
694 | | |
695 | | static int partition_i4x4_size_cavlc( x264_t *h, int i4, int i_mode ) |
696 | 0 | { |
697 | 0 | int plane_count = CHROMA444 ? 3 : 1; |
698 | 0 | h->out.bs.i_bits_encoded = cavlc_intra4x4_pred_size( h, i4, i_mode ); |
699 | 0 | for( int p = 0; p < plane_count; p++ ) |
700 | 0 | x264_cavlc_block_residual( h, DCT_LUMA_4x4, p*16+i4, h->dct.luma4x4[p*16+i4] ); |
701 | 0 | return h->out.bs.i_bits_encoded; |
702 | 0 | } |
703 | | |
704 | | static int chroma_size_cavlc( x264_t *h ) |
705 | 0 | { |
706 | 0 | h->out.bs.i_bits_encoded = bs_size_ue( x264_mb_chroma_pred_mode_fix[h->mb.i_chroma_pred_mode] ); |
707 | 0 | if( h->mb.i_cbp_chroma ) |
708 | 0 | { |
709 | 0 | x264_cavlc_block_residual( h, DCT_CHROMA_DC, CHROMA_DC+0, h->dct.chroma_dc[0] ); |
710 | 0 | x264_cavlc_block_residual( h, DCT_CHROMA_DC, CHROMA_DC+1, h->dct.chroma_dc[1] ); |
711 | |
|
712 | 0 | if( h->mb.i_cbp_chroma == 2 ) |
713 | 0 | { |
714 | 0 | int step = 8 << CHROMA_V_SHIFT; |
715 | 0 | for( int i = 16; i < 3*16; i += step ) |
716 | 0 | for( int j = i; j < i+4; j++ ) |
717 | 0 | x264_cavlc_block_residual( h, DCT_CHROMA_AC, j, h->dct.luma4x4[j]+1 ); |
718 | 0 | } |
719 | 0 | } |
720 | 0 | return h->out.bs.i_bits_encoded; |
721 | 0 | } |
722 | | #endif |