/src/libhevc/encoder/ihevce_cabac.c
Line | Count | Source (jump to first uncovered line) |
1 | | /****************************************************************************** |
2 | | * |
3 | | * Copyright (C) 2018 The Android Open Source Project |
4 | | * |
5 | | * Licensed under the Apache License, Version 2.0 (the "License"); |
6 | | * you may not use this file except in compliance with the License. |
7 | | * You may obtain a copy of the License at: |
8 | | * |
9 | | * http://www.apache.org/licenses/LICENSE-2.0 |
10 | | * |
11 | | * Unless required by applicable law or agreed to in writing, software |
12 | | * distributed under the License is distributed on an "AS IS" BASIS, |
13 | | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
14 | | * See the License for the specific language governing permissions and |
15 | | * limitations under the License. |
16 | | * |
17 | | ***************************************************************************** |
18 | | * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore |
19 | | */ |
20 | | /** |
21 | | ****************************************************************************** |
22 | | * @file ihevce_cabac.c |
23 | | * |
24 | | * @brief |
25 | | * This file contains function definitions related to bitstream generation |
26 | | * |
27 | | * @author |
28 | | * ittiam |
29 | | * |
30 | | * @List of Functions |
31 | | * ihevce_cabac_reset() |
32 | | * ihevce_cabac_init() |
33 | | * ihevce_cabac_put_byte() |
34 | | * ihevce_cabac_encode_bin() |
35 | | * ihevce_cabac_encode_bypass_bin() |
36 | | * ihevce_cabac_encode_terminate() |
37 | | * ihevce_cabac_encode_tunary() |
38 | | * ihevce_cabac_encode_tunary_bypass() |
39 | | * ihevce_cabac_encode_bypass_bins() |
40 | | * ihevce_cabac_encode_egk() |
41 | | * ihevce_cabac_encode_trunc_rice() |
42 | | * ihevce_cabac_encode_trunc_rice_ctxt() |
43 | | * ihevce_cabac_flush() |
44 | | * ihevce_cabac_ctxt_backup() |
45 | | * ihevce_cabac_ctxt_row_init() |
46 | | * |
47 | | ******************************************************************************* |
48 | | */ |
49 | | |
50 | | /*****************************************************************************/ |
51 | | /* File Includes */ |
52 | | /*****************************************************************************/ |
53 | | /* System include files */ |
54 | | #include <stdio.h> |
55 | | #include <string.h> |
56 | | #include <stdlib.h> |
57 | | #include <assert.h> |
58 | | #include <stdarg.h> |
59 | | #include <math.h> |
60 | | |
61 | | /* User include files */ |
62 | | #include "ihevc_typedefs.h" |
63 | | #include "ihevc_debug.h" |
64 | | #include "ihevc_macros.h" |
65 | | #include "ihevc_platform_macros.h" |
66 | | #include "ihevc_cabac_tables.h" |
67 | | |
68 | | #include "ihevce_defs.h" |
69 | | #include "ihevce_error_codes.h" |
70 | | #include "ihevce_bitstream.h" |
71 | | #include "ihevce_cabac.h" |
72 | | |
73 | | #define TEST_CABAC_BITESTIMATE 0 |
74 | | |
75 | | /*****************************************************************************/ |
76 | | /* Function Definitions */ |
77 | | /*****************************************************************************/ |
78 | | |
79 | | /** |
80 | | ****************************************************************************** |
81 | | * |
82 | | * @brief Resets the encoder cabac engine |
83 | | * |
84 | | * @par Description |
85 | | * This routine needs to be called at start of dependent slice encode |
86 | | * |
87 | | * @param[inout] ps_cabac_ctxt |
88 | | * pointer to cabac context (handle) |
89 | | * |
90 | | * @param[in] ps_bitstrm |
91 | | * pointer to bitstream context (handle) |
92 | | * |
93 | | * @param[in] e_cabac_op_mode |
94 | | * opertaing mode of cabac; put bits / compute bits mode @sa CABAC_OP_MODE |
95 | | * |
96 | | * @return success or failure error code |
97 | | * |
98 | | ****************************************************************************** |
99 | | */ |
100 | | WORD32 |
101 | | ihevce_cabac_reset(cab_ctxt_t *ps_cabac, bitstrm_t *ps_bitstrm, CABAC_OP_MODE e_cabac_op_mode) |
102 | 0 | { |
103 | | /* Sanity checks */ |
104 | 0 | ASSERT(ps_cabac != NULL); |
105 | 0 | ASSERT( |
106 | 0 | (e_cabac_op_mode == CABAC_MODE_ENCODE_BITS) || |
107 | 0 | (e_cabac_op_mode == CABAC_MODE_COMPUTE_BITS)); |
108 | | |
109 | 0 | ps_cabac->e_cabac_op_mode = e_cabac_op_mode; |
110 | |
|
111 | 0 | if(CABAC_MODE_ENCODE_BITS == e_cabac_op_mode) |
112 | 0 | { |
113 | 0 | ASSERT(ps_bitstrm != NULL); |
114 | | |
115 | | /* Bitstream context initialization */ |
116 | 0 | ps_cabac->pu1_strm_buffer = ps_bitstrm->pu1_strm_buffer; |
117 | 0 | ps_cabac->u4_max_strm_size = ps_bitstrm->u4_max_strm_size; |
118 | | /* When entropy sync is enabled start form fixed offset from point |
119 | | * where slice header extension has ended to handle emulation prevention |
120 | | * bytes during insertion of slice offset at end of frame */ |
121 | 0 | if(1 == ps_cabac->i1_entropy_coding_sync_enabled_flag) |
122 | 0 | { |
123 | 0 | ps_cabac->u4_strm_buf_offset = ps_cabac->u4_first_slice_start_offset; |
124 | 0 | } |
125 | 0 | else |
126 | 0 | { |
127 | 0 | ps_cabac->u4_strm_buf_offset = ps_bitstrm->u4_strm_buf_offset; |
128 | 0 | } |
129 | 0 | ps_cabac->i4_zero_bytes_run = ps_bitstrm->i4_zero_bytes_run; |
130 | | |
131 | | /* cabac engine initialization */ |
132 | 0 | ps_cabac->u4_low = 0; |
133 | 0 | ps_cabac->u4_range = 510; |
134 | 0 | ps_cabac->u4_bits_gen = 0; |
135 | 0 | ps_cabac->u4_out_standing_bytes = 0; |
136 | 0 | } |
137 | 0 | else /* (CABAC_MODE_COMPUTE_BITS == e_cabac_op_mode) */ |
138 | 0 | { |
139 | | /* reset the bits estimated */ |
140 | 0 | ps_cabac->u4_bits_estimated_q12 = 0; |
141 | | |
142 | | /* reset the texture bits estimated */ |
143 | 0 | ps_cabac->u4_texture_bits_estimated_q12 = 0; |
144 | | |
145 | | /* Setting range to 0 switches off AEV_TRACE in compute bits mode */ |
146 | 0 | ps_cabac->u4_range = 0; |
147 | 0 | } |
148 | | |
149 | 0 | return (IHEVCE_SUCCESS); |
150 | 0 | } |
151 | | |
152 | | /** |
153 | | ****************************************************************************** |
154 | | * |
155 | | * @brief Initializes the encoder cabac engine |
156 | | * |
157 | | * @par Description |
158 | | * This routine needs to be called at start of slice/frame encode |
159 | | * |
160 | | * @param[inout] ps_cabac_ctxt |
161 | | * pointer to cabac context (handle) |
162 | | * |
163 | | * @param[in] ps_bitstrm |
164 | | * pointer to bitstream context (handle) |
165 | | * |
166 | | * @param[in] qp |
167 | | * current slice qp |
168 | | * |
169 | | * @param[in] cabac_init_idc |
170 | | * current slice init idc (range - [0- 2])* |
171 | | * |
172 | | * @param[in] e_cabac_op_mode |
173 | | * opertaing mode of cabac; put bits / compute bits mode @sa CABAC_OP_MODE |
174 | | * |
175 | | * @return success or failure error code |
176 | | * |
177 | | ****************************************************************************** |
178 | | */ |
179 | | WORD32 ihevce_cabac_init( |
180 | | cab_ctxt_t *ps_cabac, |
181 | | bitstrm_t *ps_bitstrm, |
182 | | WORD32 slice_qp, |
183 | | WORD32 cabac_init_idc, |
184 | | CABAC_OP_MODE e_cabac_op_mode) |
185 | 0 | { |
186 | | /* Sanity checks */ |
187 | 0 | ASSERT(ps_cabac != NULL); |
188 | 0 | ASSERT((slice_qp >= 0) && (slice_qp < IHEVC_MAX_QP)); |
189 | 0 | ASSERT((cabac_init_idc >= 0) && (cabac_init_idc < 3)); |
190 | 0 | ASSERT( |
191 | 0 | (e_cabac_op_mode == CABAC_MODE_ENCODE_BITS) || |
192 | 0 | (e_cabac_op_mode == CABAC_MODE_COMPUTE_BITS)); |
193 | | |
194 | 0 | ps_cabac->e_cabac_op_mode = e_cabac_op_mode; |
195 | |
|
196 | 0 | if(CABAC_MODE_ENCODE_BITS == e_cabac_op_mode) |
197 | 0 | { |
198 | 0 | ASSERT(ps_bitstrm != NULL); |
199 | | |
200 | | /* Bitstream context initialization */ |
201 | 0 | ps_cabac->pu1_strm_buffer = ps_bitstrm->pu1_strm_buffer; |
202 | 0 | ps_cabac->u4_max_strm_size = ps_bitstrm->u4_max_strm_size; |
203 | | /* When entropy sync is enabled start form fixed offset from point |
204 | | * where slice header extension has ended to handle emulation prevention |
205 | | * bytes during insertion of slice offset at end of frame */ |
206 | 0 | if(1 == ps_cabac->i1_entropy_coding_sync_enabled_flag) |
207 | 0 | { |
208 | 0 | ps_cabac->u4_strm_buf_offset = ps_cabac->u4_first_slice_start_offset; |
209 | 0 | } |
210 | 0 | else |
211 | 0 | { |
212 | 0 | ps_cabac->u4_strm_buf_offset = ps_bitstrm->u4_strm_buf_offset; |
213 | 0 | } |
214 | 0 | ps_cabac->i4_zero_bytes_run = ps_bitstrm->i4_zero_bytes_run; |
215 | | |
216 | | /* cabac engine initialization */ |
217 | 0 | ps_cabac->u4_low = 0; |
218 | 0 | ps_cabac->u4_range = 510; |
219 | 0 | ps_cabac->u4_bits_gen = 0; |
220 | 0 | ps_cabac->u4_out_standing_bytes = 0; |
221 | | |
222 | | /* reset the bits estimated */ |
223 | 0 | ps_cabac->u4_bits_estimated_q12 = 0; |
224 | | |
225 | | /* reset the texture bits estimated */ |
226 | 0 | ps_cabac->u4_texture_bits_estimated_q12 = 0; |
227 | 0 | } |
228 | 0 | else /* (CABAC_MODE_COMPUTE_BITS == e_cabac_op_mode) */ |
229 | 0 | { |
230 | | /* reset the bits estimated */ |
231 | 0 | ps_cabac->u4_bits_estimated_q12 = 0; |
232 | | |
233 | | /* reset the texture bits estimated */ |
234 | 0 | ps_cabac->u4_texture_bits_estimated_q12 = 0; |
235 | | |
236 | | /* Setting range to 0 switches off AEV_TRACE in compute bits mode */ |
237 | 0 | ps_cabac->u4_range = 0; |
238 | 0 | } |
239 | | |
240 | | /* cabac context initialization based on init idc and slice qp */ |
241 | 0 | COPY_CABAC_STATES( |
242 | 0 | ps_cabac->au1_ctxt_models, |
243 | 0 | &gau1_ihevc_cab_ctxts[cabac_init_idc][slice_qp][0], |
244 | 0 | IHEVC_CAB_CTXT_END); |
245 | |
|
246 | 0 | return (IHEVCE_SUCCESS); |
247 | 0 | } |
248 | | |
249 | | /** |
250 | | ****************************************************************************** |
251 | | * |
252 | | * @brief Puts new byte (and outstanding bytes) into bitstream after cabac |
253 | | * renormalization |
254 | | * |
255 | | * @par Description |
256 | | * 1. Extract the leading byte of low(L) |
257 | | * 2. If leading byte=0xff increment outstanding bytes and return |
258 | | * (as the actual bits depend on carry propogation later) |
259 | | * 3. If leading byte is not 0xff check for any carry propogation |
260 | | * 4. Insert the carry (propogated in previous byte) along with outstanding |
261 | | * bytes (if any) and leading byte |
262 | | * |
263 | | * |
264 | | * @param[inout] ps_cabac |
265 | | * pointer to cabac context (handle) |
266 | | * |
267 | | * @return success or failure error code |
268 | | * |
269 | | ****************************************************************************** |
270 | | */ |
271 | | WORD32 ihevce_cabac_put_byte(cab_ctxt_t *ps_cabac) |
272 | 0 | { |
273 | 0 | UWORD32 u4_low = ps_cabac->u4_low; |
274 | 0 | UWORD32 u4_bits_gen = ps_cabac->u4_bits_gen; |
275 | 0 | WORD32 lead_byte = u4_low >> (u4_bits_gen + CABAC_BITS - 8); |
276 | | |
277 | | /* Sanity checks */ |
278 | 0 | ASSERT((ps_cabac->u4_range >= 256) && (ps_cabac->u4_range < 512)); |
279 | 0 | ASSERT((u4_bits_gen >= 8)); |
280 | | |
281 | | /* update bits generated and low after extracting leading byte */ |
282 | 0 | u4_bits_gen -= 8; |
283 | 0 | ps_cabac->u4_low &= ((1 << (CABAC_BITS + u4_bits_gen)) - 1); |
284 | 0 | ps_cabac->u4_bits_gen = u4_bits_gen; |
285 | | |
286 | | /************************************************************************/ |
287 | | /* 1. Extract the leading byte of low(L) */ |
288 | | /* 2. If leading byte=0xff increment outstanding bytes and return */ |
289 | | /* (as the actual bits depend on carry propogation later) */ |
290 | | /* 3. If leading byte is not 0xff check for any carry propogation */ |
291 | | /* 4. Insert the carry (propogated in previous byte) along with */ |
292 | | /* outstanding bytes (if any) and leading byte */ |
293 | | /************************************************************************/ |
294 | 0 | if(lead_byte == 0xff) |
295 | 0 | { |
296 | | /* actual bits depend on carry propogration */ |
297 | 0 | ps_cabac->u4_out_standing_bytes++; |
298 | 0 | return (IHEVCE_SUCCESS); |
299 | 0 | } |
300 | 0 | else |
301 | 0 | { |
302 | | /* carry = 1 => putbit(1); carry propogated due to L renorm */ |
303 | 0 | WORD32 carry = (lead_byte >> 8) & 0x1; |
304 | 0 | UWORD8 *pu1_strm_buf = ps_cabac->pu1_strm_buffer; |
305 | 0 | UWORD32 u4_strm_buf_offset = ps_cabac->u4_strm_buf_offset; |
306 | 0 | WORD32 zero_run = ps_cabac->i4_zero_bytes_run; |
307 | 0 | UWORD32 u4_out_standing_bytes = ps_cabac->u4_out_standing_bytes; |
308 | | |
309 | | /*********************************************************************/ |
310 | | /* Bitstream overflow check */ |
311 | | /* NOTE: corner case of epb bytes (max 2 for 32bit word) not handled */ |
312 | | /*********************************************************************/ |
313 | 0 | if((u4_strm_buf_offset + u4_out_standing_bytes + 1) >= ps_cabac->u4_max_strm_size) |
314 | 0 | { |
315 | | /* return without corrupting the buffer beyond its size */ |
316 | 0 | return (IHEVCE_BITSTREAM_BUFFER_OVERFLOW); |
317 | 0 | } |
318 | | |
319 | | /*********************************************************************/ |
320 | | /* Insert the carry propogated in previous byte */ |
321 | | /* */ |
322 | | /* Note : Do not worry about corruption into slice header align byte */ |
323 | | /* This is because the first bin cannot result in overflow */ |
324 | | /*********************************************************************/ |
325 | 0 | if(carry) |
326 | 0 | { |
327 | | /* CORNER CASE: if the previous data is 0x000003, then EPB will be inserted |
328 | | and the data will become 0x00000303 and if the carry is present, it will |
329 | | be added with the last byte and it will become 0x00000304 which is not correct |
330 | | as per standard*/ |
331 | | /* so check for previous four bytes and if it is equal to 0x00000303 |
332 | | then subtract u4_strm_buf_offset by 1 */ |
333 | 0 | if(pu1_strm_buf[u4_strm_buf_offset - 1] == 0x03 && |
334 | 0 | pu1_strm_buf[u4_strm_buf_offset - 2] == 0x03 && |
335 | 0 | pu1_strm_buf[u4_strm_buf_offset - 3] == 0x00 && |
336 | 0 | pu1_strm_buf[u4_strm_buf_offset - 4] == 0x00) |
337 | 0 | { |
338 | 0 | u4_strm_buf_offset -= 1; |
339 | 0 | } |
340 | | /* previous byte carry add will not result in overflow to */ |
341 | | /* u4_strm_buf_offset - 2 as we track 0xff as outstanding bytes */ |
342 | 0 | pu1_strm_buf[u4_strm_buf_offset - 1] += carry; |
343 | 0 | zero_run = 0; |
344 | 0 | } |
345 | | |
346 | | /* Insert outstanding bytes (if any) */ |
347 | 0 | while(u4_out_standing_bytes) |
348 | 0 | { |
349 | 0 | UWORD8 u1_0_or_ff = carry ? 0 : 0xFF; |
350 | |
|
351 | 0 | PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, u1_0_or_ff, zero_run); |
352 | |
|
353 | 0 | u4_out_standing_bytes--; |
354 | 0 | } |
355 | 0 | ps_cabac->u4_out_standing_bytes = 0; |
356 | | |
357 | | /* Insert the leading byte */ |
358 | 0 | lead_byte &= 0xFF; |
359 | 0 | PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, lead_byte, zero_run); |
360 | | |
361 | | /* update the state variables and return success */ |
362 | 0 | ps_cabac->u4_strm_buf_offset = u4_strm_buf_offset; |
363 | 0 | ps_cabac->i4_zero_bytes_run = zero_run; |
364 | 0 | return (IHEVCE_SUCCESS); |
365 | 0 | } |
366 | 0 | } |
367 | | |
368 | | /** |
369 | | ****************************************************************************** |
370 | | * |
371 | | * @brief Codes a bypass bin (equi probable 0 / 1) |
372 | | * |
373 | | * @par Description |
374 | | * After encoding bypass bin, bits gen incremented by 1 and bitstream generated |
375 | | * |
376 | | * @param[inout] ps_cabac : pointer to cabac context (handle) |
377 | | * |
378 | | * @param[in] bin : bypass bin(0/1) to be encoded |
379 | | * |
380 | | * @return success or failure error code |
381 | | * |
382 | | ****************************************************************************** |
383 | | */ |
384 | | WORD32 ihevce_cabac_encode_bypass_bin(cab_ctxt_t *ps_cabac, WORD32 bin) |
385 | 0 | { |
386 | 0 | UWORD32 u4_range = ps_cabac->u4_range; |
387 | 0 | UWORD32 u4_low = ps_cabac->u4_low; |
388 | |
|
389 | 0 | if(CABAC_MODE_ENCODE_BITS == ps_cabac->e_cabac_op_mode) |
390 | 0 | { |
391 | | /* Sanity checks */ |
392 | 0 | ASSERT((u4_range >= 256) && (u4_range < 512)); |
393 | 0 | ASSERT((bin == 0) || (bin == 1)); |
394 | | |
395 | | /*Compute bit always to populate the trace*/ |
396 | | /* increment bits generated by 1 */ |
397 | 0 | ps_cabac->u4_bits_estimated_q12 += (1 << CABAC_FRAC_BITS_Q); |
398 | |
|
399 | 0 | u4_low <<= 1; |
400 | | /* add range if bin is 1 */ |
401 | 0 | if(bin) |
402 | 0 | { |
403 | 0 | u4_low += u4_range; |
404 | 0 | } |
405 | | |
406 | | /* 1 bit to be inserted in the bitstream */ |
407 | 0 | ps_cabac->u4_bits_gen++; |
408 | 0 | ps_cabac->u4_low = u4_low; |
409 | | |
410 | | /* generate stream when a byte is ready */ |
411 | 0 | if(ps_cabac->u4_bits_gen > CABAC_BITS) |
412 | 0 | { |
413 | 0 | return (ihevce_cabac_put_byte(ps_cabac)); |
414 | 0 | } |
415 | 0 | } |
416 | 0 | else /* (CABAC_MODE_COMPUTE_BITS == e_cabac_op_mode) */ |
417 | 0 | { |
418 | | /* increment bits generated by 1 */ |
419 | 0 | ps_cabac->u4_bits_estimated_q12 += (1 << CABAC_FRAC_BITS_Q); |
420 | 0 | } |
421 | | |
422 | 0 | return (IHEVCE_SUCCESS); |
423 | 0 | } |
424 | | |
425 | | /** |
426 | | ****************************************************************************** |
427 | | * |
428 | | * @brief Codes a terminate bin (1:terminate 0:do not terminate) |
429 | | * |
430 | | * @par Description |
431 | | * After encoding bypass bin, bits gen incremented by 1 and bitstream generated |
432 | | * |
433 | | * @param[inout] ps_cabac : pointer to cabac context (handle) |
434 | | * |
435 | | * @param[in] term_bin : (1:terminate 0:do not terminate) |
436 | | * |
437 | | * @return success or failure error code |
438 | | * |
439 | | ****************************************************************************** |
440 | | */ |
441 | | WORD32 |
442 | | ihevce_cabac_encode_terminate(cab_ctxt_t *ps_cabac, WORD32 term_bin, WORD32 i4_end_of_sub_strm) |
443 | 0 | { |
444 | 0 | UWORD32 u4_range = ps_cabac->u4_range; |
445 | 0 | UWORD32 u4_low = ps_cabac->u4_low; |
446 | 0 | UWORD32 u4_rlps; |
447 | 0 | WORD32 shift; |
448 | 0 | WORD32 error = IHEVCE_SUCCESS; |
449 | | |
450 | | /* Sanity checks */ |
451 | 0 | ASSERT((u4_range >= 256) && (u4_range < 512)); |
452 | 0 | ASSERT((term_bin == 0) || (term_bin == 1)); |
453 | | |
454 | | /* term_bin = 1 has lps range = 2 */ |
455 | 0 | u4_rlps = 2; |
456 | 0 | u4_range -= u4_rlps; |
457 | | |
458 | | /* if terminate L is incremented by curR and R=2 */ |
459 | 0 | if(term_bin) |
460 | 0 | { |
461 | | /* lps path; L= L + R; R = RLPS */ |
462 | 0 | u4_low += u4_range; |
463 | 0 | u4_range = u4_rlps; |
464 | 0 | } |
465 | | |
466 | | /*****************************************************************/ |
467 | | /* Renormalization; calculate bits generated based on range(R) */ |
468 | | /* Note : 6 <= R < 512; R is 2 only for terminating encode */ |
469 | | /*****************************************************************/ |
470 | 0 | GETRANGE(shift, u4_range); |
471 | 0 | shift = 9 - shift; |
472 | 0 | u4_low <<= shift; |
473 | 0 | u4_range <<= shift; |
474 | | |
475 | | /* bits to be inserted in the bitstream */ |
476 | 0 | ps_cabac->u4_bits_gen += shift; |
477 | 0 | ps_cabac->u4_range = u4_range; |
478 | 0 | ps_cabac->u4_low = u4_low; |
479 | | |
480 | | /* generate stream when a byte is ready */ |
481 | 0 | if(ps_cabac->u4_bits_gen > CABAC_BITS) |
482 | 0 | { |
483 | 0 | error = ihevce_cabac_put_byte(ps_cabac); |
484 | 0 | } |
485 | |
|
486 | 0 | if(term_bin) |
487 | 0 | { |
488 | 0 | ihevce_cabac_flush(ps_cabac, i4_end_of_sub_strm); |
489 | 0 | } |
490 | | |
491 | | /*Compute bit always to populate the trace*/ |
492 | 0 | ps_cabac->u4_bits_estimated_q12 += gau2_ihevce_cabac_bin_to_bits[(62 << 1) | term_bin]; |
493 | |
|
494 | 0 | return (error); |
495 | 0 | } |
496 | | |
497 | | /** |
498 | | ****************************************************************************** |
499 | | * |
500 | | * @brief Encodes a truncated unary symbol associated with context model(s) |
501 | | * |
502 | | * @par Description |
503 | | * Does binarization of tunary symbol as per sec 9.3.2.2 and does the cabac |
504 | | * encoding of each bin. This is used for computing symbols like qp_delta, |
505 | | * last_sig_coeff_prefix_x, last_sig_coeff_prefix_y. |
506 | | * |
507 | | * The context models associated with each bin is computed as : |
508 | | * current bin context = "base context idx" + (bin_idx >> shift) |
509 | | * where |
510 | | * 1. "base context idx" is the base index for the syntax element |
511 | | * 2. "bin_idx" is the current bin index of the unary code |
512 | | * 3. "shift" is the shift factor associated with this syntax element |
513 | | * |
514 | | * @param[inout]ps_cabac |
515 | | * pointer to cabac context (handle) |
516 | | * |
517 | | * @param[in] sym |
518 | | * syntax element to be coded as truncated unary bins |
519 | | * |
520 | | * @param[in] c_max |
521 | | * maximum value of sym (required for tunary binarization) |
522 | | * |
523 | | * @param[in] ctxt_index |
524 | | * base context model index for this syntax element |
525 | | * |
526 | | * @param[in] ctxt_shift |
527 | | * shift factor for context increments associated with this syntax element |
528 | | * |
529 | | * @param[in] ctxt_inc_max |
530 | | * max value of context increment beyond which all bins will use same ctxt |
531 | | * |
532 | | * @return success or failure error code |
533 | | * |
534 | | ****************************************************************************** |
535 | | */ |
536 | | WORD32 ihevce_cabac_encode_tunary( |
537 | | cab_ctxt_t *ps_cabac, |
538 | | WORD32 sym, |
539 | | WORD32 c_max, |
540 | | WORD32 ctxt_index, |
541 | | WORD32 ctxt_shift, |
542 | | WORD32 ctxt_inc_max) |
543 | 0 | { |
544 | 0 | WORD32 bin_ctxt, i; |
545 | 0 | WORD32 error = IHEVCE_SUCCESS; |
546 | | |
547 | | /* Sanity checks */ |
548 | 0 | ASSERT(c_max > 0); |
549 | 0 | ASSERT((sym <= c_max) && (sym >= 0)); |
550 | 0 | ASSERT((ctxt_index >= 0) && (ctxt_index < IHEVC_CAB_CTXT_END)); |
551 | 0 | ASSERT((ctxt_index + (c_max >> ctxt_shift)) < IHEVC_CAB_CTXT_END); |
552 | | |
553 | | /* Special case of sym= 0 */ |
554 | 0 | if(0 == sym) |
555 | 0 | { |
556 | 0 | return (ihevce_cabac_encode_bin(ps_cabac, 0, ctxt_index)); |
557 | 0 | } |
558 | | |
559 | | /* write '1' bins */ |
560 | 0 | for(i = 0; i < sym; i++) |
561 | 0 | { |
562 | | /* TODO: encode bin to be inlined later */ |
563 | 0 | bin_ctxt = ctxt_index + MIN((i >> ctxt_shift), ctxt_inc_max); |
564 | 0 | error |= ihevce_cabac_encode_bin(ps_cabac, 1, bin_ctxt); |
565 | 0 | } |
566 | | |
567 | | /* write terminating 0 bin */ |
568 | 0 | if(sym < c_max) |
569 | 0 | { |
570 | | /* TODO: encode bin to be inlined later */ |
571 | 0 | bin_ctxt = ctxt_index + MIN((i >> ctxt_shift), ctxt_inc_max); |
572 | 0 | error |= ihevce_cabac_encode_bin(ps_cabac, 0, bin_ctxt); |
573 | 0 | } |
574 | |
|
575 | 0 | return (error); |
576 | 0 | } |
577 | | |
578 | | /** |
579 | | ****************************************************************************** |
580 | | * |
581 | | * @brief Encodes a syntax element as truncated unary bypass bins |
582 | | * |
583 | | * @par Description |
584 | | * Does binarization of tunary symbol as per sec 9.3.2.2 and does the cabac |
585 | | * encoding of each bin. This is used for computing symbols like merge_idx, |
586 | | * mpm_idx etc |
587 | | * |
588 | | * @param[inout]ps_cabac |
589 | | * pointer to cabac context (handle) |
590 | | * |
591 | | * @param[in] sym |
592 | | * syntax element to be coded as truncated unary bins |
593 | | * |
594 | | * @param[in] c_max |
595 | | * maximum value of sym (required for tunary binarization) |
596 | | * |
597 | | * @return success or failure error code |
598 | | * |
599 | | ****************************************************************************** |
600 | | */ |
601 | | WORD32 ihevce_cabac_encode_tunary_bypass(cab_ctxt_t *ps_cabac, WORD32 sym, WORD32 c_max) |
602 | 0 | { |
603 | 0 | WORD32 error = IHEVCE_SUCCESS; |
604 | 0 | WORD32 length; |
605 | 0 | WORD32 u4_bins; |
606 | | |
607 | | /* Sanity checks */ |
608 | 0 | ASSERT(c_max > 0); |
609 | 0 | ASSERT((sym <= c_max) && (sym >= 0)); |
610 | | |
611 | 0 | if(sym < c_max) |
612 | 0 | { |
613 | | /* unary code with (sym) '1's and terminating '0' bin */ |
614 | 0 | length = (sym + 1); |
615 | 0 | u4_bins = (1 << length) - 2; |
616 | 0 | } |
617 | 0 | else |
618 | 0 | { |
619 | | /* tunary code with (sym) '1's */ |
620 | 0 | length = sym; |
621 | 0 | u4_bins = (1 << length) - 1; |
622 | 0 | } |
623 | | |
624 | | /* Encode the tunary binarized code as bypass bins */ |
625 | 0 | error = ihevce_cabac_encode_bypass_bins(ps_cabac, u4_bins, length); |
626 | |
|
627 | 0 | return (error); |
628 | 0 | } |
629 | | |
630 | | /** |
631 | | ****************************************************************************** |
632 | | * |
633 | | * @brief Encodes a syntax element as kth order Exp-Golomb code (EGK) |
634 | | * |
635 | | * @par Description |
636 | | * Does binarization of symbol as per sec 9.3.2.4 kth order Exp-Golomb(EGk) |
637 | | * process and encodes the resulting bypass bins |
638 | | * |
639 | | * @param[inout]ps_cabac |
640 | | * pointer to cabac context (handle) |
641 | | * |
642 | | * @param[in] u4_sym |
643 | | * syntax element to be coded as EGK |
644 | | * |
645 | | * @param[in] k |
646 | | * order of EGk |
647 | | * |
648 | | * @return success or failure error code |
649 | | * |
650 | | ****************************************************************************** |
651 | | */ |
652 | | WORD32 ihevce_cabac_encode_egk(cab_ctxt_t *ps_cabac, UWORD32 u4_sym, WORD32 k) |
653 | 0 | { |
654 | 0 | WORD32 num_bins, unary_length; |
655 | 0 | UWORD32 u4_sym_shiftk_plus1, u4_egk, u4_unary_bins; |
656 | |
|
657 | 0 | WORD32 error = IHEVCE_SUCCESS; |
658 | | |
659 | | /* Sanity checks */ |
660 | 0 | ASSERT((k >= 0)); |
661 | | /* ASSERT(u4_sym >= (UWORD32)(1 << k)); */ |
662 | | |
663 | | /************************************************************************/ |
664 | | /* shift symbol by k bits to find unary code prefix (111110) */ |
665 | | /* Use GETRANGE to elminate the while loop in sec 9.3.2.4 of HEVC spec */ |
666 | | /************************************************************************/ |
667 | 0 | u4_sym_shiftk_plus1 = (u4_sym >> k) + 1; |
668 | | /* GETRANGE(unary_length, (u4_sym_shiftk_plus1 + 1)); */ |
669 | 0 | GETRANGE(unary_length, u4_sym_shiftk_plus1); |
670 | | |
671 | | /* unary code with (unary_length-1) '1's and terminating '0' bin */ |
672 | 0 | u4_unary_bins = (1 << unary_length) - 2; |
673 | | |
674 | | /* insert the symbol prefix of (unary lenght - 1) bins */ |
675 | 0 | u4_egk = (u4_unary_bins << (unary_length - 1)) | |
676 | 0 | (u4_sym_shiftk_plus1 & ((1 << (unary_length - 1)) - 1)); |
677 | | |
678 | | /* insert last k bits of symbol in the end */ |
679 | 0 | u4_egk = (u4_egk << k) | (u4_sym & ((1 << k) - 1)); |
680 | | |
681 | | /* length of the code = 2 *(unary_length - 1) + 1 + k */ |
682 | 0 | num_bins = (2 * unary_length) - 1 + k; |
683 | | |
684 | | /* Encode the egk binarized code as bypass bins */ |
685 | 0 | error = ihevce_cabac_encode_bypass_bins(ps_cabac, u4_egk, num_bins); |
686 | |
|
687 | 0 | return (error); |
688 | 0 | } |
689 | | |
690 | | /** |
691 | | ****************************************************************************** |
692 | | * |
693 | | * @brief Encodes a syntax element as truncated rice code (TR) |
694 | | * |
695 | | * @par Description |
696 | | * Does binarization of symbol as per sec 9.3.2.3 Truncated Rice(TR) |
697 | | * binarization process and encodes the resulting bypass bins |
698 | | * This function ise used for coeff_abs_level_remaining coding when |
699 | | * level is less than c_rice_max |
700 | | * |
701 | | * @param[inout]ps_cabac |
702 | | * pointer to cabac context (handle) |
703 | | * |
704 | | * @param[in] u4_sym |
705 | | * syntax element to be coded as truncated rice code |
706 | | * |
707 | | * @param[in] c_rice_param |
708 | | * shift factor for truncated unary prefix coding of (u4_sym >> c_rice_param) |
709 | | * |
710 | | * @param[in] c_rice_max |
711 | | * max symbol val below which a suffix is coded as (u4_sym%(1<<c_rice_param)) |
712 | | * This is currently (4 << c_rice_param) for coeff_abs_level_remaining |
713 | | * |
714 | | * @return success or failure error code |
715 | | * |
716 | | ****************************************************************************** |
717 | | */ |
718 | | WORD32 ihevce_cabac_encode_trunc_rice( |
719 | | cab_ctxt_t *ps_cabac, UWORD32 u4_sym, WORD32 c_rice_param, WORD32 c_rice_max) |
720 | 0 | { |
721 | 0 | WORD32 num_bins, unary_length, u4_unary_bins; |
722 | 0 | UWORD32 u4_tr; |
723 | |
|
724 | 0 | WORD32 error = IHEVCE_SUCCESS; |
725 | |
|
726 | 0 | (void)c_rice_max; |
727 | | /* Sanity checks */ |
728 | 0 | ASSERT((c_rice_param >= 0)); |
729 | 0 | ASSERT((UWORD32)c_rice_max > u4_sym); |
730 | | |
731 | | /************************************************************************/ |
732 | | /* shift symbol by c_rice_param bits to find unary code prefix (111.10) */ |
733 | | /************************************************************************/ |
734 | 0 | unary_length = (u4_sym >> c_rice_param) + 1; |
735 | | |
736 | | /* unary code with (unary_length-1) '1's and terminating '0' bin */ |
737 | 0 | u4_unary_bins = (1 << unary_length) - 2; |
738 | | |
739 | | /* insert last c_rice_param bits of symbol in the end */ |
740 | 0 | u4_tr = (u4_unary_bins << c_rice_param) | (u4_sym & ((1 << c_rice_param) - 1)); |
741 | | |
742 | | /* length of the code */ |
743 | 0 | num_bins = unary_length + c_rice_param; |
744 | | |
745 | | /* Encode the tr binarized code as bypass bins */ |
746 | 0 | error = ihevce_cabac_encode_bypass_bins(ps_cabac, u4_tr, num_bins); |
747 | |
|
748 | 0 | return (error); |
749 | 0 | } |
750 | | |
751 | | /** |
752 | | ****************************************************************************** |
753 | | * |
754 | | * @brief Flushes the cabac encoder engine as per section 9.3.4 figure 9-12 |
755 | | * |
756 | | * @par Description |
757 | | * |
758 | | * |
759 | | * @param[inout] ps_cabac |
760 | | * pointer to cabac context (handle) |
761 | | * |
762 | | * @return success or failure error code |
763 | | * |
764 | | ****************************************************************************** |
765 | | */ |
766 | | WORD32 ihevce_cabac_flush(cab_ctxt_t *ps_cabac, WORD32 i4_end_of_sub_strm) |
767 | 0 | { |
768 | 0 | UWORD32 u4_low = ps_cabac->u4_low; |
769 | 0 | UWORD32 u4_bits_gen = ps_cabac->u4_bits_gen; |
770 | |
|
771 | 0 | UWORD8 *pu1_strm_buf = ps_cabac->pu1_strm_buffer; |
772 | 0 | UWORD32 u4_strm_buf_offset = ps_cabac->u4_strm_buf_offset; |
773 | 0 | WORD32 zero_run = ps_cabac->i4_zero_bytes_run; |
774 | 0 | UWORD32 u4_out_standing_bytes = ps_cabac->u4_out_standing_bytes; |
775 | |
|
776 | 0 | (void)i4_end_of_sub_strm; |
777 | | /************************************************************************/ |
778 | | /* Insert the carry (propogated in previous byte) along with */ |
779 | | /* outstanding bytes (if any) and flush remaining bits */ |
780 | | /************************************************************************/ |
781 | | |
782 | | //TODO: Review this function |
783 | 0 | { |
784 | | /* carry = 1 => putbit(1); carry propogated due to L renorm */ |
785 | 0 | WORD32 carry = (u4_low >> (u4_bits_gen + CABAC_BITS)) & 0x1; |
786 | 0 | WORD32 last_byte; |
787 | 0 | WORD32 bits_left; |
788 | 0 | WORD32 rem_bits; |
789 | | |
790 | | /*********************************************************************/ |
791 | | /* Bitstream overflow check */ |
792 | | /* NOTE: corner case of epb bytes (max 2 for 32bit word) not handled */ |
793 | | /*********************************************************************/ |
794 | 0 | if((u4_strm_buf_offset + u4_out_standing_bytes + 1) >= ps_cabac->u4_max_strm_size) |
795 | 0 | { |
796 | | /* return without corrupting the buffer beyond its size */ |
797 | 0 | return (IHEVCE_BITSTREAM_BUFFER_OVERFLOW); |
798 | 0 | } |
799 | | |
800 | 0 | if(carry) |
801 | 0 | { |
802 | | /* CORNER CASE: if the previous data is 0x000003, then EPB will be inserted |
803 | | and the data will become 0x00000303 and if the carry is present, it will |
804 | | be added with the last byte and it will become 0x00000304 which is not correct |
805 | | as per standard*/ |
806 | | /* so check for previous four bytes and if it is equal to 0x00000303 |
807 | | then subtract u4_strm_buf_offset by 1 */ |
808 | 0 | if(pu1_strm_buf[u4_strm_buf_offset - 1] == 0x03 && |
809 | 0 | pu1_strm_buf[u4_strm_buf_offset - 2] == 0x03 && |
810 | 0 | pu1_strm_buf[u4_strm_buf_offset - 3] == 0x00 && |
811 | 0 | pu1_strm_buf[u4_strm_buf_offset - 4] == 0x00) |
812 | 0 | { |
813 | 0 | u4_strm_buf_offset -= 1; |
814 | 0 | } |
815 | | /* previous byte carry add will not result in overflow to */ |
816 | | /* u4_strm_buf_offset - 2 as we track 0xff as outstanding bytes */ |
817 | 0 | pu1_strm_buf[u4_strm_buf_offset - 1] += carry; |
818 | 0 | zero_run = 0; |
819 | 0 | } |
820 | | |
821 | | /* Insert outstanding bytes (if any) */ |
822 | 0 | while(u4_out_standing_bytes) |
823 | 0 | { |
824 | 0 | UWORD8 u1_0_or_ff = carry ? 0 : 0xFF; |
825 | |
|
826 | 0 | PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, u1_0_or_ff, zero_run); |
827 | |
|
828 | 0 | u4_out_standing_bytes--; |
829 | 0 | } |
830 | | |
831 | | /* clear the carry in low */ |
832 | 0 | u4_low &= ((1 << (u4_bits_gen + CABAC_BITS)) - 1); |
833 | | |
834 | | /* extract the remaining bits; */ |
835 | | /* includes additional msb bit of low as per Figure 9-12 */ |
836 | 0 | bits_left = u4_bits_gen + 1; |
837 | 0 | rem_bits = (u4_low >> (u4_bits_gen + CABAC_BITS - bits_left)); |
838 | |
|
839 | 0 | if(bits_left >= 8) |
840 | 0 | { |
841 | 0 | last_byte = (rem_bits >> (bits_left - 8)) & 0xFF; |
842 | 0 | PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, last_byte, zero_run); |
843 | 0 | bits_left -= 8; |
844 | 0 | } |
845 | | |
846 | | /* insert last byte along with rbsp stop bit(1) and 0's in the end */ |
847 | 0 | last_byte = (rem_bits << (8 - bits_left)) | (1 << (7 - bits_left)); |
848 | 0 | last_byte &= 0xFF; |
849 | 0 | PUTBYTE_EPB(pu1_strm_buf, u4_strm_buf_offset, last_byte, zero_run); |
850 | | |
851 | | /* update the state variables and return success */ |
852 | 0 | ps_cabac->u4_strm_buf_offset = u4_strm_buf_offset; |
853 | 0 | ps_cabac->i4_zero_bytes_run = 0; |
854 | 0 | return (IHEVCE_SUCCESS); |
855 | 0 | } |
856 | 0 | } |
857 | | |
858 | | /** |
859 | | ****************************************************************************** |
860 | | * |
861 | | * @brief API to backup cabac ctxt at end of 2nd CTB row which is used to init |
862 | | * context at start of every row |
863 | | * |
864 | | * @par Description |
865 | | * API to backup cabac ctxt at end of 2nd CTB row which is used to init |
866 | | * context at start of every row |
867 | | * |
868 | | * @param[inout] ps_cabac |
869 | | * pointer to cabac context (handle) |
870 | | * |
871 | | * @return success or failure error code |
872 | | * |
873 | | ****************************************************************************** |
874 | | */ |
875 | | WORD32 ihevce_cabac_ctxt_backup(cab_ctxt_t *ps_cabac) |
876 | 0 | { |
877 | 0 | memcpy( |
878 | 0 | ps_cabac->au1_ctxt_models_top_right, |
879 | 0 | ps_cabac->au1_ctxt_models, |
880 | 0 | sizeof(ps_cabac->au1_ctxt_models)); |
881 | 0 | return (IHEVCE_SUCCESS); |
882 | 0 | } |
883 | | |
884 | | /** |
885 | | ****************************************************************************** |
886 | | * |
887 | | * @brief Init cabac ctxt at every row start |
888 | | * |
889 | | * @par Description |
890 | | * API to init cabac ctxt at start of every row when entropy sync is |
891 | | * enabled |
892 | | * |
893 | | * @param[inout] ps_cabac |
894 | | * pointer to cabac context (handle) |
895 | | * |
896 | | * @return success or failure error code |
897 | | * |
898 | | ****************************************************************************** |
899 | | */ |
900 | | WORD32 ihevce_cabac_ctxt_row_init(cab_ctxt_t *ps_cabac) |
901 | 0 | { |
902 | | /* cabac engine initialization */ |
903 | 0 | ps_cabac->u4_low = 0; |
904 | 0 | ps_cabac->u4_range = 510; |
905 | 0 | ps_cabac->u4_bits_gen = 0; |
906 | 0 | ps_cabac->u4_out_standing_bytes = 0; |
907 | 0 | ps_cabac->i4_zero_bytes_run = 0; |
908 | | |
909 | | /*copy top right context as init context when starting to encode a row*/ |
910 | 0 | COPY_CABAC_STATES( |
911 | 0 | ps_cabac->au1_ctxt_models, ps_cabac->au1_ctxt_models_top_right, IHEVC_CAB_CTXT_END); |
912 | |
|
913 | 0 | return (IHEVCE_SUCCESS); |
914 | 0 | } |