1 /******************************************************************************
2 *
3 * Copyright (C) 2022 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 *******************************************************************************
23 * @file
24 * isvce_cavlc.c
25 *
26 * @brief
27 * Contains all the routines to code syntax elements and residuals when entropy
28 * coding chosen is CAVLC
29 *
30 * @author
31 * ittiam
32 *
33 * @par List of Functions:
34 * - isvce_compute_zeroruns_and_trailingones()
35 * - isvce_write_coeff4x4_cavlc()
36 * - isvce_write_coeff8x8_cavlc()
37 * - isvce_encode_residue()
38 * - isvce_write_islice_mb_cavlc()
39 * - isvce_write_pslice_mb_cavlc()
40 *
41 * @remarks
42 * None
43 *
44 *******************************************************************************
45 */
46
47 /*****************************************************************************/
48 /* File Includes */
49 /*****************************************************************************/
50
51 /* System include files */
52 #include <stdio.h>
53 #include <assert.h>
54 #include <limits.h>
55
56 /* User include files */
57 #include "ih264e_config.h"
58 #include "ih264_typedefs.h"
59 #include "iv2.h"
60 #include "ive2.h"
61 #include "ih264_debug.h"
62 #include "isvc_macros.h"
63 #include "isvc_defs.h"
64 #include "isvce_defs.h"
65 #include "ih264e_error.h"
66 #include "ih264e_bitstream.h"
67 #include "ime_distortion_metrics.h"
68 #include "ime_defs.h"
69 #include "ime_structs.h"
70 #include "ih264_error.h"
71 #include "isvc_structs.h"
72 #include "isvc_trans_quant_itrans_iquant.h"
73 #include "isvc_inter_pred_filters.h"
74 #include "isvc_mem_fns.h"
75 #include "ih264_padding.h"
76 #include "ih264_intra_pred_filters.h"
77 #include "ih264_deblk_edge_filters.h"
78 #include "isvc_cabac_tables.h"
79 #include "irc_cntrl_param.h"
80 #include "irc_frame_info_collector.h"
81 #include "isvce_rate_control.h"
82 #include "isvce_cabac_structs.h"
83 #include "isvce_structs.h"
84 #include "isvce_encode_header.h"
85 #include "ih264_cavlc_tables.h"
86 #include "isvce_cavlc.h"
87 #include "ih264e_statistics.h"
88 #include "ih264e_trace.h"
89 #include "isvce_encode_header.h"
90 #include "isvce_utils.h"
91
92 /*****************************************************************************/
93 /* Function Definitions */
94 /*****************************************************************************/
95
96 /**
97 *******************************************************************************
98 *
99 * @brief
100 * This function computes run of zero, number of trailing ones and sign of
101 * trailing ones basing on the significant coeff map, residual block and
102 * total nnz.
103 *
104 * @param[in] pi2_res_block
105 * Pointer to residual block containing levels in scan order
106 *
107 * @param[in] u4_total_coeff
108 * Total non-zero coefficients in that sub block
109 *
110 * @param[in] pu1_zero_run
111 * Pointer to array to store run of zeros
112 *
113 * @param[in] u4_sig_coeff_map
114 * significant coefficient map
115 *
116 * @returns u4_totzero_sign_trailone
117 * Bits 0-8 contains number of trailing ones.
118 * Bits 8-16 contains bitwise sign information of trailing one
119 * Bits 16-24 contains total number of zeros.
120 *
121 * @remarks
122 * None
123 *
124 *******************************************************************************
125 */
isvce_compute_zeroruns_and_trailingones(WORD16 * pi2_res_block,UWORD32 u4_total_coeff,UWORD8 * pu1_zero_run,UWORD32 u4_sig_coeff_map)126 static UWORD32 isvce_compute_zeroruns_and_trailingones(WORD16 *pi2_res_block,
127 UWORD32 u4_total_coeff, UWORD8 *pu1_zero_run,
128 UWORD32 u4_sig_coeff_map)
129 {
130 UWORD32 i = 0;
131 UWORD32 u4_nnz_coeff = 0;
132 WORD32 i4_run = -1;
133 UWORD32 u4_sign = 0;
134 UWORD32 u4_tot_zero = 0;
135 UWORD32 u4_trailing1 = 0;
136 WORD32 i4_val;
137 UWORD32 u4_totzero_sign_trailone;
138 UWORD32 *pu4_zero_run;
139
140 pu4_zero_run = (void *) pu1_zero_run;
141 pu4_zero_run[0] = 0;
142 pu4_zero_run[1] = 0;
143 pu4_zero_run[2] = 0;
144 pu4_zero_run[3] = 0;
145
146 /* Compute Runs of zeros for all nnz coefficients except the last 3 */
147 if(u4_total_coeff > 3)
148 {
149 for(i = 0; u4_nnz_coeff < (u4_total_coeff - 3); i++)
150 {
151 i4_run++;
152
153 i4_val = (u4_sig_coeff_map & 0x1);
154 u4_sig_coeff_map >>= 1;
155
156 if(i4_val != 0)
157 {
158 pu1_zero_run[u4_nnz_coeff++] = i4_run;
159 i4_run = -1;
160 }
161 }
162 }
163
164 /* Compute T1's, Signof(T1's) and Runs of zeros for the last 3 */
165 while(u4_nnz_coeff != u4_total_coeff)
166 {
167 i4_run++;
168
169 i4_val = (u4_sig_coeff_map & 0x1);
170 u4_sig_coeff_map >>= 1;
171
172 if(i4_val != 0)
173 {
174 if(pi2_res_block[u4_nnz_coeff] == 1)
175 {
176 pu1_zero_run[u4_nnz_coeff] = i4_run;
177 u4_trailing1++;
178 }
179 else
180 {
181 if(pi2_res_block[u4_nnz_coeff] == -1)
182 {
183 pu1_zero_run[u4_nnz_coeff] = i4_run;
184 u4_sign |= 1 << u4_trailing1;
185 u4_trailing1++;
186 }
187 else
188 {
189 pu1_zero_run[u4_nnz_coeff] = i4_run;
190 u4_trailing1 = 0;
191 u4_sign = 0;
192 }
193 }
194 i4_run = -1;
195 u4_nnz_coeff++;
196 }
197 i++;
198 }
199
200 u4_tot_zero = i - u4_total_coeff;
201 u4_totzero_sign_trailone = (u4_tot_zero << 16) | (u4_sign << 8) | u4_trailing1;
202
203 return (u4_totzero_sign_trailone);
204 }
205
206 /**
207 *******************************************************************************
208 *
209 * @brief
210 * This function generates CAVLC coded bit stream for the given residual block
211 *
212 * @param[in] pi2_res_block
213 * Pointer to residual block containing levels in scan order
214 *
215 * @param[in] u4_total_coeff
216 * Total non-zero coefficients in the sub block
217 *
218 * @param[in] u4_block_type
219 * block type
220 *
221 * @param[in] pu1_zero_run
222 * Pointer to array to store run of zeros
223 *
224 * @param[in] u4_nc
225 * average of non zero coeff from top and left blocks (when available)
226 *
227 * @param[in, out] ps_bit_stream
228 * structure pointing to a buffer holding output bit stream
229 *
230 * @param[in] u4_sig_coeff_map
231 * significant coefficient map of the residual block
232 *
233 * @returns
234 * error code
235 *
236 * @remarks
237 * If the block type is CAVLC_CHROMA_4x4_DC, then u4_nc is non-significant
238 *
239 *******************************************************************************
240 */
isvce_write_coeff4x4_cavlc(WORD16 * pi2_res_block,UWORD32 u4_total_coeff,ENTROPY_BLK_TYPE u4_block_type,UWORD8 * pu1_zero_run,UWORD32 u4_nc,bitstrm_t * ps_bit_stream,UWORD32 u4_sig_coeff_map)241 static IH264E_ERROR_T isvce_write_coeff4x4_cavlc(WORD16 *pi2_res_block, UWORD32 u4_total_coeff,
242 ENTROPY_BLK_TYPE u4_block_type,
243 UWORD8 *pu1_zero_run, UWORD32 u4_nc,
244 bitstrm_t *ps_bit_stream, UWORD32 u4_sig_coeff_map)
245 {
246 IH264E_ERROR_T error_status = IH264E_SUCCESS;
247 UWORD32 u4_totzero_sign_trailone = 0;
248 UWORD32 u4_trailing_ones = 0;
249 UWORD32 u4_tot_zeros = 0;
250 UWORD32 u4_remaining_coeff = 0;
251 UWORD32 u4_sign1 = 0;
252 UWORD32 u4_max_num_coeff = 0;
253 const UWORD32 au4_max_num_nnz_coeff[] = {16, 15, 16, 4, 15};
254
255 /* validate inputs */
256 ASSERT(u4_block_type <= CAVLC_CHROMA_4x4_AC);
257
258 u4_max_num_coeff = au4_max_num_nnz_coeff[u4_block_type];
259
260 ASSERT(u4_total_coeff <= u4_max_num_coeff);
261
262 if(!u4_total_coeff)
263 {
264 UWORD32 u4_codeword = 15;
265 UWORD32 u4_codesize = 1;
266 if(u4_block_type == CAVLC_CHROMA_4x4_DC)
267 {
268 u4_codeword = 1;
269 u4_codesize = 2;
270 DEBUG("\n[%d numcoeff, %d numtrailing ones]", u4_total_coeff, 0);
271 ENTROPY_TRACE("\tnumber of non zero coeffs ", u4_total_coeff);
272 ENTROPY_TRACE("\tnumber of trailing ones ", 0);
273 }
274 else
275 {
276 UWORD32 u4_vlcnum = u4_nc >> 1;
277
278 /* write coeff_token */
279 if(u4_vlcnum > 3)
280 {
281 /* Num-FLC */
282 u4_codeword = 3;
283 u4_codesize = 6;
284 }
285 else
286 {
287 /* Num-VLC 0, 1, 2 */
288 if(u4_vlcnum > 1)
289 {
290 u4_vlcnum = 2;
291 }
292 u4_codesize <<= u4_vlcnum;
293 u4_codeword >>= (4 - u4_codesize);
294 }
295
296 DEBUG("\n[%d numcoeff, %d numtrailing ones, %d nnz]", u4_total_coeff, 0, u4_nc);
297 ENTROPY_TRACE("\tnumber of non zero coeffs ", u4_total_coeff);
298 ENTROPY_TRACE("\tnC ", u4_nc);
299 }
300
301 DEBUG("\nCOEFF TOKEN 0: %d u4_codeword, %d u4_codesize", u4_codeword, u4_codesize);
302 ENTROPY_TRACE("\tcodeword ", u4_codeword);
303 ENTROPY_TRACE("\tcodesize ", u4_codesize);
304
305 error_status = ih264e_put_bits(ps_bit_stream, u4_codeword, u4_codesize);
306
307 return error_status;
308 }
309 else
310 {
311 /* Compute zero run, number of trailing ones and their sign. */
312 u4_totzero_sign_trailone = isvce_compute_zeroruns_and_trailingones(
313 pi2_res_block, u4_total_coeff, pu1_zero_run, u4_sig_coeff_map);
314 u4_trailing_ones = u4_totzero_sign_trailone & 0xFF;
315 u4_sign1 = (u4_totzero_sign_trailone >> 8) & 0xFF;
316 u4_tot_zeros = (u4_totzero_sign_trailone >> 16) & 0xFF;
317 u4_remaining_coeff = u4_total_coeff - u4_trailing_ones;
318
319 /* write coeff_token */
320 {
321 UWORD32 u4_codeword;
322 UWORD32 u4_codesize;
323 if(u4_block_type == CAVLC_CHROMA_4x4_DC)
324 {
325 u4_codeword =
326 gu1_code_coeff_token_table_chroma[u4_trailing_ones][u4_total_coeff - 1];
327 u4_codesize =
328 gu1_size_coeff_token_table_chroma[u4_trailing_ones][u4_total_coeff - 1];
329
330 DEBUG("\n[%d numcoeff, %d numtrailing ones]", u4_total_coeff, u4_trailing_ones);
331 ENTROPY_TRACE("\tnumber of non zero coeffs ", u4_total_coeff);
332 ENTROPY_TRACE("\tnumber of trailing ones ", u4_trailing_ones);
333 }
334 else
335 {
336 UWORD32 u4_vlcnum = u4_nc >> 1;
337
338 if(u4_vlcnum > 3)
339 {
340 /* Num-FLC */
341 u4_codeword = ((u4_total_coeff - 1) << 2) + u4_trailing_ones;
342 u4_codesize = 6;
343 }
344 else
345 {
346 /* Num-VLC 0, 1, 2 */
347 if(u4_vlcnum > 1)
348 {
349 u4_vlcnum = 2;
350 }
351 u4_codeword =
352 gu1_code_coeff_token_table[u4_vlcnum][u4_trailing_ones][u4_total_coeff - 1];
353 u4_codesize =
354 gu1_size_coeff_token_table[u4_vlcnum][u4_trailing_ones][u4_total_coeff - 1];
355 }
356
357 DEBUG("\n[%d numcoeff, %d numtrailing ones, %d nnz]", u4_total_coeff,
358 u4_trailing_ones, u4_nc);
359 ENTROPY_TRACE("\tnumber of non zero coeffs ", u4_total_coeff);
360 ENTROPY_TRACE("\tnumber of trailing ones ", u4_trailing_ones);
361 ENTROPY_TRACE("\tnC ", u4_nc);
362 }
363
364 DEBUG("\nCOEFF TOKEN 0: %d u4_codeword, %d u4_codesize", u4_codeword, u4_codesize);
365 ENTROPY_TRACE("\tcodeword ", u4_codeword);
366 ENTROPY_TRACE("\tcodesize ", u4_codesize);
367
368 error_status = ih264e_put_bits(ps_bit_stream, u4_codeword, u4_codesize);
369 }
370
371 /* write sign of trailing ones */
372 if(u4_trailing_ones)
373 {
374 DEBUG("\nT1's: %d u4_codeword, %d u4_codesize", u4_sign1, u4_trailing_ones);
375 error_status = ih264e_put_bits(ps_bit_stream, u4_sign1, u4_trailing_ones);
376 ENTROPY_TRACE("\tnumber of trailing ones ", u4_trailing_ones);
377 ENTROPY_TRACE("\tsign of trailing ones ", u4_sign1);
378 }
379
380 /* write level codes */
381 if(u4_remaining_coeff)
382 {
383 WORD32 i4_level = pi2_res_block[u4_remaining_coeff - 1];
384 UWORD32 u4_escape;
385 UWORD32 u4_suffix_length = 0; // Level-VLC[N]
386 UWORD32 u4_abs_level, u4_abs_level_actual = 0;
387 WORD32 i4_sign;
388 const UWORD32 u4_rndfactor[] = {0, 0, 1, 3, 7, 15, 31};
389
390 DEBUG("\n \t%d coeff,", i4_level);
391 ENTROPY_TRACE("\tcoeff ", i4_level);
392
393 if(u4_trailing_ones < 3)
394 {
395 /* If there are less than 3 T1s, then the first non-T1 level is
396 * incremented if negative (decremented if positive)*/
397 if(i4_level < 0)
398 {
399 i4_level += 1;
400 }
401 else
402 {
403 i4_level -= 1;
404 }
405
406 u4_abs_level_actual = 1;
407
408 /* Initialize VLC table (Suffix Length) to encode the level */
409 if(u4_total_coeff > 10)
410 {
411 u4_suffix_length = 1;
412 }
413 }
414
415 i4_sign = (i4_level >> (sizeof(WORD32) * CHAR_BIT - 1));
416 u4_abs_level = ((i4_level + i4_sign) ^ i4_sign);
417
418 u4_abs_level_actual += u4_abs_level;
419
420 u4_escape = (u4_abs_level + u4_rndfactor[u4_suffix_length]) >> u4_suffix_length;
421
422 while(1)
423 {
424 UWORD32 u4_codesize;
425 UWORD32 u4_codeword;
426 UWORD32 u4_codeval;
427
428 u4_remaining_coeff--;
429
430 GATHER_CAVLC_STATS1();
431
432 {
433 u4_codeval = u4_abs_level << 1;
434 u4_codeval = u4_codeval - 2 - i4_sign;
435
436 if((!u4_suffix_length) && (u4_escape > 7) && (u4_abs_level < 16))
437 {
438 u4_codeword = (1 << 4) + (u4_codeval - 14);
439 u4_codesize = 19;
440 }
441 else if(u4_escape > 7)
442 {
443 u4_codeword = (1 << 12) + (u4_codeval - (15 << u4_suffix_length));
444 u4_codesize = 28;
445 if(!u4_suffix_length)
446 {
447 u4_codeword -= 15;
448 }
449 }
450 else
451 {
452 u4_codeword =
453 (1 << u4_suffix_length) + (u4_codeval & ((1 << u4_suffix_length) - 1));
454 u4_codesize = (u4_codeval >> u4_suffix_length) + 1 + u4_suffix_length;
455 }
456 }
457
458 /*put the level code in bitstream*/
459 DEBUG("\nLEVEL: %d u4_codeword, %d u4_codesize", u4_codeword, u4_codesize);
460 ENTROPY_TRACE("\tcodeword ", u4_codeword);
461 ENTROPY_TRACE("\tcodesize ", u4_codesize);
462 error_status = ih264e_put_bits(ps_bit_stream, u4_codeword, u4_codesize);
463
464 if(u4_remaining_coeff == 0) break;
465
466 /*update suffix length for next level*/
467 if(u4_suffix_length == 0)
468 {
469 u4_suffix_length++;
470 }
471 if(u4_suffix_length < 6)
472 {
473 if(u4_abs_level_actual > gu1_threshold_vlc_level[u4_suffix_length])
474 {
475 u4_suffix_length++;
476 }
477 }
478
479 /* next level */
480 i4_level = pi2_res_block[u4_remaining_coeff - 1];
481
482 DEBUG("\n \t%d coeff,", i4_level);
483 ENTROPY_TRACE("\tcoeff ", i4_level);
484
485 i4_sign = (i4_level >> (sizeof(WORD32) * CHAR_BIT - 1));
486 u4_abs_level = ((i4_level + i4_sign) ^ i4_sign);
487
488 u4_abs_level_actual = u4_abs_level;
489
490 u4_escape = (u4_abs_level + u4_rndfactor[u4_suffix_length]) >> u4_suffix_length;
491 }
492 }
493
494 DEBUG("\n \t %d totalzeros", u4_tot_zeros);
495 ENTROPY_TRACE("\ttotal zeros ", u4_tot_zeros);
496
497 /* Write Total Zeros */
498 if(u4_total_coeff < u4_max_num_coeff)
499 {
500 WORD32 index;
501 UWORD32 u4_codeword;
502 UWORD32 u4_codesize;
503
504 if(u4_block_type == CAVLC_CHROMA_4x4_DC)
505 {
506 UWORD8 gu1_index_zero_table_chroma[] = {0, 4, 7};
507 index = gu1_index_zero_table_chroma[u4_total_coeff - 1] + u4_tot_zeros;
508 u4_codesize = gu1_size_zero_table_chroma[index];
509 u4_codeword = gu1_code_zero_table_chroma[index];
510 }
511 else
512 {
513 index = gu1_index_zero_table[u4_total_coeff - 1] + u4_tot_zeros;
514 u4_codesize = gu1_size_zero_table[index];
515 u4_codeword = gu1_code_zero_table[index];
516 }
517
518 DEBUG("\nTOTAL ZEROS: %d u4_codeword, %d u4_codesize", u4_codeword, u4_codesize);
519 ENTROPY_TRACE("\tcodeword ", u4_codeword);
520 ENTROPY_TRACE("\tcodesize ", u4_codesize);
521 error_status = ih264e_put_bits(ps_bit_stream, u4_codeword, u4_codesize);
522 }
523
524 /* Write Run Before */
525 if(u4_tot_zeros)
526 {
527 UWORD32 u4_max_num_coef = u4_total_coeff - 1;
528 UWORD32 u4_codeword;
529 UWORD32 u4_codesize;
530 UWORD32 u4_zeros_left = u4_tot_zeros;
531
532 while(u4_max_num_coef)
533 {
534 UWORD32 u4_run_before = pu1_zero_run[u4_max_num_coef];
535 UWORD32 u4_index;
536
537 if(u4_zeros_left > MAX_ZERO_LEFT)
538 {
539 u4_index = gu1_index_run_table[MAX_ZERO_LEFT];
540 }
541 else
542 {
543 u4_index = gu1_index_run_table[u4_zeros_left - 1];
544 }
545
546 u4_codesize = gu1_size_run_table[u4_index + u4_run_before];
547 u4_codeword = gu1_code_run_table[u4_index + u4_run_before];
548
549 DEBUG("\nRUN BEFORE ZEROS: %d u4_codeword, %d u4_codesize", u4_codeword,
550 u4_codesize);
551 ENTROPY_TRACE("\tcodeword ", u4_codeword);
552 ENTROPY_TRACE("\tcodesize ", u4_codesize);
553 error_status = ih264e_put_bits(ps_bit_stream, u4_codeword, u4_codesize);
554
555 u4_zeros_left -= u4_run_before;
556 if(!u4_zeros_left)
557 {
558 break;
559 }
560 u4_max_num_coef--;
561 }
562 }
563 }
564
565 return error_status;
566 }
567
568 /**
569 *******************************************************************************
570 *
571 * @brief
572 * This function generates CAVLC coded bit stream for the given subblock
573 *
574 * @param[in] ps_ent_ctxt
575 * Pointer to entropy context
576 *
577 * @param[in] pi2_res_block
578 * Pointers to residual blocks of all the partitions for the current subblk
579 * (containing levels in scan order)
580 *
581 * @param[in] pu1_nnz
582 * Total non-zero coefficients of all the partitions for the current subblk
583 *
584 * @param[in] pu2_sig_coeff_map
585 * Significant coefficient map of all the partitions for the current subblk
586 *
587 * @param[in] u4_block_type
588 * entropy coding block type
589 *
590 * @param[in] u4_ngbr_avbl
591 * top and left availability of all the partitions for the current subblk
592 * (packed)
593 *
594 * @param[in] pu1_top_nnz
595 * pointer to the buffer containing nnz of all the subblks to the top
596 *
597 * @param[in] pu1_left_nnz
598 * pointer to the buffer containing nnz of all the subblks to the left
599 *
600 * @returns error status
601 *
602 * @remarks none
603 *
604 *******************************************************************************
605 */
isvce_write_coeff8x8_cavlc(isvce_entropy_ctxt_t * ps_ent_ctxt,WORD16 ** pi2_res_block,UWORD8 * pu1_nnz,UWORD16 * pu2_sig_coeff_map,ENTROPY_BLK_TYPE u4_block_type,UWORD32 u4_ngbr_avlb,UWORD8 * pu1_top_nnz,UWORD8 * pu1_left_nnz)606 static IH264E_ERROR_T isvce_write_coeff8x8_cavlc(isvce_entropy_ctxt_t *ps_ent_ctxt,
607 WORD16 **pi2_res_block, UWORD8 *pu1_nnz,
608 UWORD16 *pu2_sig_coeff_map,
609 ENTROPY_BLK_TYPE u4_block_type,
610 UWORD32 u4_ngbr_avlb, UWORD8 *pu1_top_nnz,
611 UWORD8 *pu1_left_nnz)
612 {
613 IH264E_ERROR_T error_status = IH264E_SUCCESS;
614 bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
615 UWORD8 *pu1_zero_run = ps_ent_ctxt->au1_zero_run, *pu1_ngbr_avbl;
616 UWORD32 u4_nC;
617 UWORD8 u1_mb_a, u1_mb_b;
618
619 pu1_ngbr_avbl = (void *) (&u4_ngbr_avlb);
620
621 /* encode ac block index 4x4 = 0*/
622 u1_mb_a = pu1_ngbr_avbl[0] & 0x0F;
623 u1_mb_b = pu1_ngbr_avbl[0] & 0xF0;
624 u4_nC = 0;
625 if(u1_mb_a) u4_nC += pu1_left_nnz[0];
626 if(u1_mb_b) u4_nC += pu1_top_nnz[0];
627 if(u1_mb_a && u1_mb_b) u4_nC = (u4_nC + 1) >> 1;
628 pu1_left_nnz[0] = pu1_top_nnz[0] = pu1_nnz[0];
629 error_status =
630 isvce_write_coeff4x4_cavlc(pi2_res_block[0], pu1_nnz[0], u4_block_type, pu1_zero_run, u4_nC,
631 ps_bitstream, pu2_sig_coeff_map[0]);
632
633 /* encode ac block index 4x4 = 1*/
634 u1_mb_a = pu1_ngbr_avbl[1] & 0x0F;
635 u1_mb_b = pu1_ngbr_avbl[1] & 0xF0;
636 u4_nC = 0;
637 if(u1_mb_a) u4_nC += pu1_left_nnz[0];
638 if(u1_mb_b) u4_nC += pu1_top_nnz[1];
639 if(u1_mb_a && u1_mb_b) u4_nC = (u4_nC + 1) >> 1;
640 pu1_left_nnz[0] = pu1_top_nnz[1] = pu1_nnz[1];
641 error_status =
642 isvce_write_coeff4x4_cavlc(pi2_res_block[1], pu1_nnz[1], u4_block_type, pu1_zero_run, u4_nC,
643 ps_bitstream, pu2_sig_coeff_map[1]);
644
645 /* encode ac block index 4x4 = 2*/
646 u1_mb_a = pu1_ngbr_avbl[2] & 0x0F;
647 u1_mb_b = pu1_ngbr_avbl[2] & 0xF0;
648 u4_nC = 0;
649 if(u1_mb_a) u4_nC += pu1_left_nnz[1];
650 if(u1_mb_b) u4_nC += pu1_top_nnz[0];
651 if(u1_mb_a && u1_mb_b) u4_nC = (u4_nC + 1) >> 1;
652 pu1_left_nnz[1] = pu1_top_nnz[0] = pu1_nnz[2];
653 error_status =
654 isvce_write_coeff4x4_cavlc(pi2_res_block[2], pu1_nnz[2], u4_block_type, pu1_zero_run, u4_nC,
655 ps_bitstream, pu2_sig_coeff_map[2]);
656
657 /* encode ac block index 4x4 = 0*/
658 u1_mb_a = pu1_ngbr_avbl[3] & 0x0F;
659 u1_mb_b = pu1_ngbr_avbl[3] & 0xF0;
660 u4_nC = 0;
661 if(u1_mb_a) u4_nC += pu1_left_nnz[1];
662 if(u1_mb_b) u4_nC += pu1_top_nnz[1];
663 if(u1_mb_a && u1_mb_b) u4_nC = (u4_nC + 1) >> 1;
664 pu1_left_nnz[1] = pu1_top_nnz[1] = pu1_nnz[3];
665 error_status =
666 isvce_write_coeff4x4_cavlc(pi2_res_block[3], pu1_nnz[3], u4_block_type, pu1_zero_run, u4_nC,
667 ps_bitstream, pu2_sig_coeff_map[3]);
668
669 return error_status;
670 }
671
672 /**
673 *******************************************************************************
674 *
675 * @brief
676 * This function encodes luma and chroma residues of a macro block when
677 * the entropy coding mode chosen is cavlc.
678 *
679 * @param[in] ps_ent_ctxt
680 * Pointer to entropy context
681 *
682 * @param[in] u4_mb_type
683 * current mb type
684 *
685 * @param[in] u4_cbp
686 * coded block pattern for the current mb
687 *
688 * @returns error code
689 *
690 * @remarks none
691 *
692 *******************************************************************************
693 */
isvce_encode_residue(isvce_entropy_ctxt_t * ps_ent_ctxt,UWORD32 u4_mb_type,UWORD32 u4_cbp)694 static IH264E_ERROR_T isvce_encode_residue(isvce_entropy_ctxt_t *ps_ent_ctxt, UWORD32 u4_mb_type,
695 UWORD32 u4_cbp)
696 {
697 /* error status */
698 IH264E_ERROR_T error_status = IH264E_SUCCESS;
699
700 /* packed residue */
701 void *pv_mb_coeff_data = ps_ent_ctxt->pv_mb_coeff_data;
702
703 /* bit stream buffer */
704 bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
705
706 /* zero run */
707 UWORD8 *pu1_zero_run = ps_ent_ctxt->au1_zero_run;
708
709 /* temp var */
710 UWORD32 u4_nC, u4_ngbr_avlb;
711 UWORD8 au1_nnz[4], *pu1_ngbr_avlb, *pu1_top_nnz, *pu1_left_nnz;
712 UWORD16 au2_sig_coeff_map[4] = {0};
713 WORD16 *pi2_res_block[4] = {NULL};
714 UWORD8 *pu1_slice_idx = ps_ent_ctxt->pu1_slice_idx;
715 tu_sblk_coeff_data_t *ps_mb_coeff_data;
716 ENTROPY_BLK_TYPE e_entropy_blk_type = CAVLC_LUMA_4x4;
717
718 /* ngbr availability */
719 UWORD8 u1_mb_a, u1_mb_b;
720
721 /* cbp */
722 UWORD32 u4_cbp_luma = u4_cbp & 0xF, u4_cbp_chroma = u4_cbp >> 4;
723
724 /* mb indices */
725 WORD32 i4_mb_x, i4_mb_y;
726
727 /* derive neighbor availability */
728 i4_mb_x = ps_ent_ctxt->i4_mb_x;
729 i4_mb_y = ps_ent_ctxt->i4_mb_y;
730 pu1_slice_idx += (i4_mb_y * ps_ent_ctxt->i4_wd_mbs);
731 /* left macroblock availability */
732 u1_mb_a = (i4_mb_x == 0 || (pu1_slice_idx[i4_mb_x - 1] != pu1_slice_idx[i4_mb_x])) ? 0 : 1;
733 /* top macroblock availability */
734 u1_mb_b = (i4_mb_y == 0 ||
735 (pu1_slice_idx[i4_mb_x - ps_ent_ctxt->i4_wd_mbs] != pu1_slice_idx[i4_mb_x]))
736 ? 0
737 : 1;
738
739 pu1_ngbr_avlb = (void *) (&u4_ngbr_avlb);
740 pu1_top_nnz = ps_ent_ctxt->pu1_top_nnz_luma[ps_ent_ctxt->i4_mb_x];
741 pu1_left_nnz = (UWORD8 *) &ps_ent_ctxt->u4_left_nnz_luma;
742
743 /* encode luma residue */
744
745 /* mb type intra 16x16 */
746 if(u4_mb_type == I16x16)
747 {
748 /* parse packed coeff data structure for residual data */
749 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[0],
750 au2_sig_coeff_map[0], pi2_res_block[0]);
751 /* estimate nnz for the current mb */
752 u4_nC = 0;
753 if(u1_mb_a) u4_nC += pu1_left_nnz[0];
754 if(u1_mb_b) u4_nC += pu1_top_nnz[0];
755 if(u1_mb_a && u1_mb_b) u4_nC = (u4_nC + 1) >> 1;
756
757 /* encode dc block */
758 ENTROPY_TRACE("Luma DC blk idx %d", 0);
759 error_status =
760 isvce_write_coeff4x4_cavlc(pi2_res_block[0], au1_nnz[0], CAVLC_LUMA_4x4_DC,
761 pu1_zero_run, u4_nC, ps_bitstream, au2_sig_coeff_map[0]);
762
763 e_entropy_blk_type = CAVLC_LUMA_4x4_AC;
764 }
765
766 if(u4_cbp_luma & 1)
767 {
768 /* encode ac block index 8x8 = 0*/
769 /* parse packed coeff data structure for residual data */
770 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[0],
771 au2_sig_coeff_map[0], pi2_res_block[0]);
772 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[1],
773 au2_sig_coeff_map[1], pi2_res_block[1]);
774 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[2],
775 au2_sig_coeff_map[2], pi2_res_block[2]);
776 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[3],
777 au2_sig_coeff_map[3], pi2_res_block[3]);
778 /* derive sub block neighbor availability */
779
780 pu1_ngbr_avlb[0] = (u1_mb_b << 4) | (u1_mb_a);
781 pu1_ngbr_avlb[1] = (u1_mb_b << 4) | 1;
782 pu1_ngbr_avlb[2] = (1 << 4) | (u1_mb_a);
783 pu1_ngbr_avlb[3] = 0x11;
784 /* encode sub blk */
785 ENTROPY_TRACE("Luma blk idx %d", 0);
786 error_status =
787 isvce_write_coeff8x8_cavlc(ps_ent_ctxt, pi2_res_block, au1_nnz, au2_sig_coeff_map,
788 e_entropy_blk_type, u4_ngbr_avlb, pu1_top_nnz, pu1_left_nnz);
789 }
790 else
791 {
792 pu1_top_nnz[0] = pu1_top_nnz[1] = 0;
793 pu1_left_nnz[0] = pu1_left_nnz[1] = 0;
794 }
795
796 if(u4_cbp_luma & 2)
797 {
798 /* encode ac block index 8x8 = 1*/
799 /* parse packed coeff data structure for residual data */
800 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[0],
801 au2_sig_coeff_map[0], pi2_res_block[0]);
802 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[1],
803 au2_sig_coeff_map[1], pi2_res_block[1]);
804 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[2],
805 au2_sig_coeff_map[2], pi2_res_block[2]);
806 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[3],
807 au2_sig_coeff_map[3], pi2_res_block[3]);
808
809 /* derive sub block neighbor availability */
810 pu1_ngbr_avlb[1] = pu1_ngbr_avlb[0] = (u1_mb_b << 4) | 1;
811 pu1_ngbr_avlb[3] = pu1_ngbr_avlb[2] = 0x11;
812 /* encode sub blk */
813 ENTROPY_TRACE("Luma blk idx %d", 1);
814 error_status = isvce_write_coeff8x8_cavlc(ps_ent_ctxt, pi2_res_block, au1_nnz,
815 au2_sig_coeff_map, e_entropy_blk_type,
816 u4_ngbr_avlb, pu1_top_nnz + 2, pu1_left_nnz);
817 }
818 else
819 {
820 (pu1_top_nnz + 2)[0] = (pu1_top_nnz + 2)[1] = 0;
821 pu1_left_nnz[0] = pu1_left_nnz[1] = 0;
822 }
823
824 if(u4_cbp_luma & 0x4)
825 {
826 /* encode ac block index 8x8 = 2*/
827 /* parse packed coeff data structure for residual data */
828 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[0],
829 au2_sig_coeff_map[0], pi2_res_block[0]);
830 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[1],
831 au2_sig_coeff_map[1], pi2_res_block[1]);
832 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[2],
833 au2_sig_coeff_map[2], pi2_res_block[2]);
834 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[3],
835 au2_sig_coeff_map[3], pi2_res_block[3]);
836
837 /* derive sub block neighbor availability */
838 pu1_ngbr_avlb[2] = pu1_ngbr_avlb[0] = (1 << 4) | u1_mb_a;
839 pu1_ngbr_avlb[1] = pu1_ngbr_avlb[3] = 0x11;
840 /* encode sub blk */
841 ENTROPY_TRACE("Luma blk idx %d", 2);
842 error_status = isvce_write_coeff8x8_cavlc(ps_ent_ctxt, pi2_res_block, au1_nnz,
843 au2_sig_coeff_map, e_entropy_blk_type,
844 u4_ngbr_avlb, pu1_top_nnz, (pu1_left_nnz + 2));
845 }
846 else
847 {
848 pu1_top_nnz[0] = pu1_top_nnz[1] = 0;
849 (pu1_left_nnz + 2)[0] = (pu1_left_nnz + 2)[1] = 0;
850 }
851
852 if(u4_cbp_luma & 0x8)
853 {
854 /* encode ac block index 8x8 = 3*/
855 /* parse packed coeff data structure for residual data */
856 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[0],
857 au2_sig_coeff_map[0], pi2_res_block[0]);
858 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[1],
859 au2_sig_coeff_map[1], pi2_res_block[1]);
860 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[2],
861 au2_sig_coeff_map[2], pi2_res_block[2]);
862 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[3],
863 au2_sig_coeff_map[3], pi2_res_block[3]);
864
865 /* derive sub block neighbor availability */
866 u4_ngbr_avlb = 0x11111111;
867 /* encode sub blk */
868 ENTROPY_TRACE("Luma blk idx %d", 3);
869 error_status = isvce_write_coeff8x8_cavlc(ps_ent_ctxt, pi2_res_block, au1_nnz,
870 au2_sig_coeff_map, e_entropy_blk_type,
871 u4_ngbr_avlb, pu1_top_nnz + 2, pu1_left_nnz + 2);
872 }
873 else
874 {
875 (pu1_top_nnz + 2)[0] = (pu1_top_nnz + 2)[1] = 0;
876 (pu1_left_nnz + 2)[0] = (pu1_left_nnz + 2)[1] = 0;
877 }
878
879 /* encode chroma residue */
880 if(u4_cbp_chroma & 3)
881 {
882 /* parse packed coeff data structure for residual data */
883 /* cb, cr */
884 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[0],
885 au2_sig_coeff_map[0], pi2_res_block[0]);
886 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[1],
887 au2_sig_coeff_map[1], pi2_res_block[1]);
888
889 /* encode dc block */
890 /* cb, cr */
891 ENTROPY_TRACE("Chroma DC blk idx %d", 0);
892 error_status =
893 isvce_write_coeff4x4_cavlc(pi2_res_block[0], au1_nnz[0], CAVLC_CHROMA_4x4_DC,
894 pu1_zero_run, 0, ps_bitstream, au2_sig_coeff_map[0]);
895 ENTROPY_TRACE("Chroma DC blk idx %d", 1);
896 error_status =
897 isvce_write_coeff4x4_cavlc(pi2_res_block[1], au1_nnz[1], CAVLC_CHROMA_4x4_DC,
898 pu1_zero_run, 0, ps_bitstream, au2_sig_coeff_map[1]);
899 }
900
901 pu1_top_nnz = ps_ent_ctxt->pu1_top_nnz_cbcr[ps_ent_ctxt->i4_mb_x];
902 pu1_left_nnz = (UWORD8 *) &ps_ent_ctxt->u4_left_nnz_cbcr;
903
904 /* encode sub blk */
905 if(u4_cbp_chroma & 0x2)
906 {
907 /* encode ac block index 8x8 = 0*/
908 /* derive sub block neighbor availability */
909 pu1_ngbr_avlb[0] = (u1_mb_b << 4) | (u1_mb_a);
910 pu1_ngbr_avlb[1] = (u1_mb_b << 4) | 1;
911 pu1_ngbr_avlb[2] = (1 << 4) | (u1_mb_a);
912 pu1_ngbr_avlb[3] = 0x11;
913
914 /* parse packed coeff data structure for residual data */
915 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[0],
916 au2_sig_coeff_map[0], pi2_res_block[0]);
917 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[1],
918 au2_sig_coeff_map[1], pi2_res_block[1]);
919 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[2],
920 au2_sig_coeff_map[2], pi2_res_block[2]);
921 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[3],
922 au2_sig_coeff_map[3], pi2_res_block[3]);
923
924 ENTROPY_TRACE("Chroma AC blk idx %d", 0);
925 error_status = isvce_write_coeff8x8_cavlc(ps_ent_ctxt, pi2_res_block, au1_nnz,
926 au2_sig_coeff_map, CAVLC_CHROMA_4x4_AC,
927 u4_ngbr_avlb, pu1_top_nnz, pu1_left_nnz);
928 }
929 else
930 {
931 pu1_top_nnz[0] = pu1_top_nnz[1] = 0;
932 pu1_left_nnz[0] = pu1_left_nnz[1] = 0;
933 }
934
935 pu1_top_nnz += 2;
936 pu1_left_nnz += 2;
937
938 /* encode sub blk */
939 if(u4_cbp_chroma & 0x2)
940 {
941 /* parse packed coeff data structure for residual data */
942 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[0],
943 au2_sig_coeff_map[0], pi2_res_block[0]);
944 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[1],
945 au2_sig_coeff_map[1], pi2_res_block[1]);
946 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[2],
947 au2_sig_coeff_map[2], pi2_res_block[2]);
948 PARSE_COEFF_DATA_BLOCK_4x4(pv_mb_coeff_data, ps_mb_coeff_data, au1_nnz[3],
949 au2_sig_coeff_map[3], pi2_res_block[3]);
950
951 ENTROPY_TRACE("Chroma AC blk idx %d", 1);
952 error_status = isvce_write_coeff8x8_cavlc(ps_ent_ctxt, pi2_res_block, au1_nnz,
953 au2_sig_coeff_map, CAVLC_CHROMA_4x4_AC,
954 u4_ngbr_avlb, pu1_top_nnz, pu1_left_nnz);
955 }
956 else
957 {
958 pu1_top_nnz[0] = pu1_top_nnz[1] = 0;
959 pu1_left_nnz[0] = pu1_left_nnz[1] = 0;
960 }
961
962 /* store the index of the next mb coeff data */
963 ps_ent_ctxt->pv_mb_coeff_data = pv_mb_coeff_data;
964
965 return error_status;
966 }
967
968 /**
969 *******************************************************************************
970 *
971 * @brief
972 * This function generates CAVLC coded bit stream for an Intra Slice.
973 *
974 * @description
975 * The mb syntax layer for intra slices constitutes luma mb mode, luma sub modes
976 * (if present), mb qp delta, coded block pattern, chroma mb mode and
977 * luma/chroma residue. These syntax elements are written as directed by table
978 * 7.3.5 of h264 specification.
979 *
980 * @param[in] ps_ent_ctxt
981 * pointer to entropy context
982 *
983 * @returns error code
984 *
985 * @remarks none
986 *
987 *******************************************************************************
988 */
isvce_write_islice_mb_cavlc(isvce_entropy_ctxt_t * ps_ent_ctxt)989 IH264E_ERROR_T isvce_write_islice_mb_cavlc(isvce_entropy_ctxt_t *ps_ent_ctxt)
990 {
991 /* error status */
992 IH264E_ERROR_T error_status = IH264E_SUCCESS;
993
994 /* bit stream ptr */
995 bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
996
997 /* packed header data */
998 UWORD8 *pu1_byte = ps_ent_ctxt->pv_mb_header_data;
999 isvce_mb_hdr_common_t *ps_mb_hdr = (isvce_mb_hdr_common_t *) ps_ent_ctxt->pv_mb_header_data;
1000
1001 /* mb header info */
1002 /*
1003 * mb_tpm : mb type plus mode
1004 * mb_type : luma mb type and chroma mb type are packed
1005 * cbp : coded block pattern
1006 * mb_qp_delta : mb qp delta
1007 * chroma_intra_mode : chroma intra mode
1008 * luma_intra_mode : luma intra mode
1009 */
1010 WORD32 mb_tpm, mb_type, cbp, chroma_intra_mode, luma_intra_mode;
1011 WORD8 mb_qp_delta;
1012
1013 /* temp var */
1014 WORD32 i, mb_type_stream;
1015
1016 WORD32 bitstream_start_offset, bitstream_end_offset;
1017
1018 svc_slice_header_t *ps_svc_slice_header =
1019 ps_ent_ctxt->ps_svc_slice_hdr_base +
1020 (ps_ent_ctxt->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
1021
1022 /* Starting bitstream offset for header in bits */
1023 bitstream_start_offset = isvce_get_num_bits(ps_bitstream);
1024
1025 /********************************************************************/
1026 /* BEGIN HEADER GENERATION */
1027 /********************************************************************/
1028
1029 if(ps_ent_ctxt->u1_spatial_layer_id && ps_svc_slice_header->i1_adaptive_base_mode_flag)
1030 {
1031 /* write base_mode_flag */
1032 PUT_BITS(ps_bitstream, ps_mb_hdr->u1_base_mode_flag, 1, error_status, "base_mode_flag");
1033 }
1034 else
1035 {
1036 ps_mb_hdr->u1_base_mode_flag = 0;
1037 }
1038
1039 /* mb header info */
1040 mb_tpm = ps_mb_hdr->u1_mb_type_mode;
1041 cbp = ps_mb_hdr->u1_cbp;
1042 mb_qp_delta =
1043 ((WORD16) ps_mb_hdr->u1_mb_qp) - ((WORD16) ps_ent_ctxt->ps_mb_qp_ctxt->u1_cur_mb_qp);
1044
1045 /* mb type */
1046 mb_type = mb_tpm & 0xF;
1047 /* is intra ? */
1048 if(!ps_mb_hdr->u1_base_mode_flag)
1049 {
1050 if(mb_type == I16x16)
1051 {
1052 UWORD32 u4_cbp_l, u4_cbp_c;
1053
1054 u4_cbp_c = (cbp >> 4);
1055 u4_cbp_l = (cbp & 0xF);
1056 luma_intra_mode = (mb_tpm >> 4) & 3;
1057 chroma_intra_mode = (mb_tpm >> 6);
1058
1059 mb_type_stream = luma_intra_mode + 1 + (u4_cbp_c << 2) + (u4_cbp_l == 15) * 12;
1060
1061 /* write mb type */
1062 PUT_BITS_UEV(ps_bitstream, mb_type_stream, error_status, "mb type");
1063
1064 /* intra_chroma_pred_mode */
1065 PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1066
1067 pu1_byte += sizeof(isvce_mb_hdr_i16x16_t);
1068 }
1069 else if(mb_type == I4x4)
1070 {
1071 isvce_mb_hdr_i4x4_t *ps_mb_hdr_i4x4 =
1072 (isvce_mb_hdr_i4x4_t *) ps_ent_ctxt->pv_mb_header_data;
1073
1074 /* mb sub blk modes */
1075 WORD32 intra_pred_mode_flag, rem_intra_mode;
1076 WORD32 byte;
1077
1078 chroma_intra_mode = (mb_tpm >> 6);
1079
1080 /* write mb type */
1081 PUT_BITS_UEV(ps_bitstream, 0, error_status, "mb type");
1082
1083 for(i = 0; i < 16; i += 2)
1084 {
1085 /* sub blk idx 1 */
1086 byte = ps_mb_hdr_i4x4->au1_sub_blk_modes[i >> 1];
1087
1088 intra_pred_mode_flag = byte & 0x1;
1089
1090 /* prev_intra4x4_pred_mode_flag */
1091 PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
1092 "prev_intra4x4_pred_mode_flag");
1093
1094 /* rem_intra4x4_pred_mode */
1095 if(!intra_pred_mode_flag)
1096 {
1097 rem_intra_mode = (byte & 0xF) >> 1;
1098 PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
1099 "rem_intra4x4_pred_mode");
1100 }
1101
1102 /* sub blk idx 2 */
1103 byte >>= 4;
1104
1105 intra_pred_mode_flag = byte & 0x1;
1106
1107 /* prev_intra4x4_pred_mode_flag */
1108 PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
1109 "prev_intra4x4_pred_mode_flag");
1110
1111 /* rem_intra4x4_pred_mode */
1112 if(!intra_pred_mode_flag)
1113 {
1114 rem_intra_mode = (byte & 0xF) >> 1;
1115 PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
1116 "rem_intra4x4_pred_mode");
1117 }
1118 }
1119
1120 /* intra_chroma_pred_mode */
1121 PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1122
1123 pu1_byte += sizeof(isvce_mb_hdr_i4x4_t);
1124 }
1125 else if(mb_type == I8x8)
1126 {
1127 /* transform 8x8 flag */
1128 UWORD32 u4_transform_size_8x8_flag = ps_ent_ctxt->i1_transform_8x8_mode_flag;
1129 isvce_mb_hdr_i8x8_t *ps_mb_hdr_i8x8 =
1130 (isvce_mb_hdr_i8x8_t *) ps_ent_ctxt->pv_mb_header_data;
1131
1132 /* mb sub blk modes */
1133 WORD32 intra_pred_mode_flag, rem_intra_mode;
1134 WORD32 byte;
1135
1136 chroma_intra_mode = (mb_tpm >> 6);
1137
1138 ASSERT(0);
1139
1140 /* write mb type */
1141 PUT_BITS_UEV(ps_bitstream, 0, error_status, "mb type");
1142
1143 /* u4_transform_size_8x8_flag */
1144 PUT_BITS(ps_bitstream, u4_transform_size_8x8_flag, 1, error_status,
1145 "u4_transform_size_8x8_flag");
1146
1147 /* write sub block modes */
1148 for(i = 0; i < 4; i++)
1149 {
1150 /* sub blk idx 1 */
1151 byte = ps_mb_hdr_i8x8->au1_sub_blk_modes[i >> 1];
1152
1153 intra_pred_mode_flag = byte & 0x1;
1154
1155 /* prev_intra4x4_pred_mode_flag */
1156 PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
1157 "prev_intra4x4_pred_mode_flag");
1158
1159 /* rem_intra4x4_pred_mode */
1160 if(!intra_pred_mode_flag)
1161 {
1162 rem_intra_mode = (byte & 0xF) >> 1;
1163 PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
1164 "rem_intra4x4_pred_mode");
1165 }
1166
1167 /* sub blk idx 2 */
1168 byte >>= 4;
1169
1170 intra_pred_mode_flag = byte & 0x1;
1171
1172 /* prev_intra4x4_pred_mode_flag */
1173 PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
1174 "prev_intra4x4_pred_mode_flag");
1175
1176 /* rem_intra4x4_pred_mode */
1177 if(!intra_pred_mode_flag)
1178 {
1179 rem_intra_mode = (byte & 0xF) >> 1;
1180 PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
1181 "rem_intra4x4_pred_mode");
1182 }
1183 }
1184
1185 /* intra_chroma_pred_mode */
1186 PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1187
1188 pu1_byte += sizeof(isvce_mb_hdr_i8x8_t);
1189 }
1190 }
1191 else
1192 {
1193 pu1_byte += sizeof(isvce_mb_hdr_base_mode_t);
1194 }
1195
1196 /* coded_block_pattern */
1197 if(ps_mb_hdr->u1_base_mode_flag || mb_type != I16x16)
1198 {
1199 PUT_BITS_UEV(ps_bitstream, gu1_cbp_map_tables[cbp][ps_mb_hdr->u1_base_mode_flag],
1200 error_status, "coded_block_pattern");
1201
1202 if(cbp % 16 > 0 && ps_ent_ctxt->i1_transform_8x8_mode_flag &&
1203 (ps_mb_hdr->u1_base_mode_flag || (mb_type == I8x8 || mb_type == I4x4)))
1204 {
1205 PUT_BITS(ps_bitstream, ps_ent_ctxt->i1_transform_8x8_mode_flag, 1, error_status,
1206 "u4_transform_size_8x8_flag");
1207 }
1208 }
1209
1210 if((cbp > 0) || (mb_type == I16x16))
1211 {
1212 /* mb_qp_delta */
1213 PUT_BITS_SEV(ps_bitstream, mb_qp_delta, error_status, "mb_qp_delta");
1214 ps_ent_ctxt->ps_mb_qp_ctxt->u1_cur_mb_qp = ps_mb_hdr->u1_mb_qp;
1215 }
1216
1217 /* Ending bitstream offset for header in bits */
1218 bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
1219
1220 ps_ent_ctxt->u4_header_bits[0] += bitstream_end_offset - bitstream_start_offset;
1221
1222 /* Starting bitstream offset for residue */
1223 bitstream_start_offset = bitstream_end_offset;
1224
1225 /* residual */
1226 error_status = isvce_encode_residue(ps_ent_ctxt, mb_type, cbp);
1227
1228 /* Ending bitstream offset for reside in bits */
1229 bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
1230 ps_ent_ctxt->u4_residue_bits[0] += bitstream_end_offset - bitstream_start_offset;
1231
1232 /* store the index of the next mb syntax layer */
1233 ps_ent_ctxt->pv_mb_header_data = pu1_byte;
1234
1235 return error_status;
1236 }
1237
1238 /**
1239 *******************************************************************************
1240 *
1241 * @brief
1242 * This function generates CAVLC coded bit stream for Inter slices
1243 *
1244 * @description
1245 * The mb syntax layer for inter slices constitutes luma mb mode, luma sub modes
1246 * (if present), mb qp delta, coded block pattern, chroma mb mode and
1247 * luma/chroma residue. These syntax elements are written as directed by table
1248 * 7.3.5 of h264 specification
1249 *
1250 * @param[in] ps_ent_ctxt
1251 * pointer to entropy context
1252 *
1253 * @returns error code
1254 *
1255 * @remarks none
1256 *
1257 *******************************************************************************
1258 */
isvce_write_pslice_mb_cavlc(isvce_entropy_ctxt_t * ps_ent_ctxt)1259 IH264E_ERROR_T isvce_write_pslice_mb_cavlc(isvce_entropy_ctxt_t *ps_ent_ctxt)
1260 {
1261 /* mb header info */
1262 /*
1263 * mb_tpm : mb type plus mode
1264 * mb_type : luma mb type and chroma mb type are packed
1265 * cbp : coded block pattern
1266 * mb_qp_delta : mb qp delta
1267 * chroma_intra_mode : chroma intra mode
1268 * luma_intra_mode : luma intra mode
1269 * ps_pu : Pointer to the array of structures having motion vectors, size
1270 * and position of sub partitions
1271 */
1272 WORD32 mb_tpm, mb_type, cbp, chroma_intra_mode, luma_intra_mode;
1273 WORD8 mb_qp_delta;
1274 WORD32 i, mb_type_stream;
1275 WORD32 bitstream_start_offset, bitstream_end_offset;
1276 UWORD8 u1_is_intra_mb;
1277
1278 bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
1279 isvce_mb_hdr_common_t *ps_mb_hdr = (isvce_mb_hdr_common_t *) ps_ent_ctxt->pv_mb_header_data;
1280 svc_slice_header_t *ps_svc_slice_header =
1281 ps_ent_ctxt->ps_svc_slice_hdr_base +
1282 (ps_ent_ctxt->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
1283
1284 IH264E_ERROR_T error_status = IH264E_SUCCESS;
1285
1286 UWORD8 *pu1_byte = ps_ent_ctxt->pv_mb_header_data;
1287 WORD32 cbptable = 1;
1288 WORD32 is_inter = 0;
1289
1290 /* Starting bitstream offset for header in bits */
1291 bitstream_start_offset = isvce_get_num_bits(ps_bitstream);
1292
1293 /********************************************************************/
1294 /* BEGIN HEADER GENERATION */
1295 /********************************************************************/
1296
1297 /* mb header info */
1298 mb_tpm = ps_mb_hdr->u1_mb_type_mode;
1299
1300 /* mb type */
1301 mb_type = mb_tpm & 0xF;
1302 u1_is_intra_mb = (mb_type == I16x16) || (mb_type == I8x8) || (mb_type == I4x4);
1303
1304 /* check for skip */
1305 if(mb_type == PSKIP)
1306 {
1307 UWORD32 *nnz;
1308
1309 is_inter = 1;
1310
1311 /* increment skip counter */
1312 (*ps_ent_ctxt->pi4_mb_skip_run)++;
1313
1314 /* store the index of the next mb syntax layer */
1315 pu1_byte += sizeof(isvce_mb_hdr_pskip_t);
1316 ps_ent_ctxt->pv_mb_header_data = pu1_byte;
1317
1318 /* set nnz to zero */
1319 ps_ent_ctxt->u4_left_nnz_luma = 0;
1320 nnz = (UWORD32 *) ps_ent_ctxt->pu1_top_nnz_luma[ps_ent_ctxt->i4_mb_x];
1321 *nnz = 0;
1322 ps_ent_ctxt->u4_left_nnz_cbcr = 0;
1323 nnz = (UWORD32 *) ps_ent_ctxt->pu1_top_nnz_cbcr[ps_ent_ctxt->i4_mb_x];
1324 *nnz = 0;
1325
1326 /* residual */
1327 error_status = isvce_encode_residue(ps_ent_ctxt, P16x16, 0);
1328
1329 bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
1330
1331 ps_ent_ctxt->u4_header_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
1332
1333 return error_status;
1334 }
1335
1336 /* remaining mb header info */
1337 cbp = ps_mb_hdr->u1_cbp;
1338 mb_qp_delta =
1339 ((WORD16) ps_mb_hdr->u1_mb_qp) - ((WORD16) ps_ent_ctxt->ps_mb_qp_ctxt->u1_cur_mb_qp);
1340
1341 /* mb skip run */
1342 PUT_BITS_UEV(ps_bitstream, *ps_ent_ctxt->pi4_mb_skip_run, error_status, "mb skip run");
1343
1344 /* reset skip counter */
1345 *ps_ent_ctxt->pi4_mb_skip_run = 0;
1346
1347 if(ps_ent_ctxt->u1_spatial_layer_id && ps_svc_slice_header->i1_adaptive_base_mode_flag)
1348 {
1349 /* write base_mode_flag */
1350 PUT_BITS(ps_bitstream, ps_mb_hdr->u1_base_mode_flag, 1, error_status, "base_mode_flag");
1351 }
1352 else
1353 {
1354 ps_mb_hdr->u1_base_mode_flag = 0;
1355 }
1356
1357 if(!ps_mb_hdr->u1_base_mode_flag)
1358 {
1359 /* is intra ? */
1360 if(mb_type == I16x16)
1361 {
1362 UWORD32 u4_cbp_l, u4_cbp_c;
1363
1364 is_inter = 0;
1365
1366 u4_cbp_c = (cbp >> 4);
1367 u4_cbp_l = (cbp & 0xF);
1368 luma_intra_mode = (mb_tpm >> 4) & 3;
1369 chroma_intra_mode = (mb_tpm >> 6);
1370
1371 mb_type_stream = luma_intra_mode + 1 + (u4_cbp_c << 2) + (u4_cbp_l == 15) * 12;
1372
1373 mb_type_stream += 5;
1374
1375 /* write mb type */
1376 PUT_BITS_UEV(ps_bitstream, mb_type_stream, error_status, "mb type");
1377
1378 /* intra_chroma_pred_mode */
1379 PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1380 pu1_byte += sizeof(isvce_mb_hdr_i16x16_t);
1381 }
1382 else if(mb_type == I4x4)
1383 {
1384 isvce_mb_hdr_i4x4_t *ps_mb_hdr_i4x4 =
1385 (isvce_mb_hdr_i4x4_t *) ps_ent_ctxt->pv_mb_header_data;
1386
1387 /* mb sub blk modes */
1388 WORD32 intra_pred_mode_flag, rem_intra_mode;
1389 WORD32 byte;
1390
1391 is_inter = 0;
1392
1393 chroma_intra_mode = (mb_tpm >> 6);
1394 cbptable = 0;
1395
1396 /* write mb type */
1397 PUT_BITS_UEV(ps_bitstream, 5, error_status, "mb type");
1398
1399 for(i = 0; i < 16; i += 2)
1400 {
1401 /* sub blk idx 1 */
1402 byte = ps_mb_hdr_i4x4->au1_sub_blk_modes[i >> 1];
1403
1404 intra_pred_mode_flag = byte & 0x1;
1405
1406 /* prev_intra4x4_pred_mode_flag */
1407 PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
1408 "prev_intra4x4_pred_mode_flag");
1409
1410 /* rem_intra4x4_pred_mode */
1411 if(!intra_pred_mode_flag)
1412 {
1413 rem_intra_mode = (byte & 0xF) >> 1;
1414 PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
1415 "rem_intra4x4_pred_mode");
1416 }
1417
1418 /* sub blk idx 2 */
1419 byte >>= 4;
1420
1421 intra_pred_mode_flag = byte & 0x1;
1422
1423 /* prev_intra4x4_pred_mode_flag */
1424 PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
1425 "prev_intra4x4_pred_mode_flag");
1426
1427 /* rem_intra4x4_pred_mode */
1428 if(!intra_pred_mode_flag)
1429 {
1430 rem_intra_mode = (byte & 0xF) >> 1;
1431 PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
1432 "rem_intra4x4_pred_mode");
1433 }
1434 }
1435
1436 /* intra_chroma_pred_mode */
1437 PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1438
1439 pu1_byte += sizeof(isvce_mb_hdr_i4x4_t);
1440 }
1441 else if(mb_type == I8x8)
1442 {
1443 isvce_mb_hdr_i8x8_t *ps_mb_hdr_i8x8 =
1444 (isvce_mb_hdr_i8x8_t *) ps_ent_ctxt->pv_mb_header_data;
1445
1446 /* transform 8x8 flag */
1447 UWORD32 u4_transform_size_8x8_flag = ps_ent_ctxt->i1_transform_8x8_mode_flag;
1448
1449 /* mb sub blk modes */
1450 WORD32 intra_pred_mode_flag, rem_intra_mode;
1451 WORD32 byte;
1452
1453 is_inter = 0;
1454
1455 chroma_intra_mode = (mb_tpm >> 6);
1456 cbptable = 0;
1457
1458 ASSERT(0);
1459
1460 /* write mb type */
1461 PUT_BITS_UEV(ps_bitstream, 5, error_status, "mb type");
1462
1463 /* u4_transform_size_8x8_flag */
1464 PUT_BITS(ps_bitstream, u4_transform_size_8x8_flag, 1, error_status,
1465 "u4_transform_size_8x8_flag");
1466
1467 /* write sub block modes */
1468 for(i = 0; i < 4; i++)
1469 {
1470 /* sub blk idx 1 */
1471 byte = ps_mb_hdr_i8x8->au1_sub_blk_modes[i >> 1];
1472
1473 intra_pred_mode_flag = byte & 0x1;
1474
1475 /* prev_intra4x4_pred_mode_flag */
1476 PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
1477 "prev_intra4x4_pred_mode_flag");
1478
1479 /* rem_intra4x4_pred_mode */
1480 if(!intra_pred_mode_flag)
1481 {
1482 rem_intra_mode = (byte & 0xF) >> 1;
1483 PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
1484 "rem_intra4x4_pred_mode");
1485 }
1486
1487 /* sub blk idx 2 */
1488 byte >>= 4;
1489
1490 intra_pred_mode_flag = byte & 0x1;
1491
1492 /* prev_intra4x4_pred_mode_flag */
1493 PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
1494 "prev_intra4x4_pred_mode_flag");
1495
1496 /* rem_intra4x4_pred_mode */
1497 if(!intra_pred_mode_flag)
1498 {
1499 rem_intra_mode = (byte & 0xF) >> 1;
1500 PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
1501 "rem_intra4x4_pred_mode");
1502 }
1503 }
1504
1505 /* intra_chroma_pred_mode */
1506 PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1507
1508 pu1_byte += sizeof(isvce_mb_hdr_i8x8_t);
1509 }
1510 else
1511 {
1512 isvce_mb_hdr_p16x16_t *ps_mb_hdr_p16x16 =
1513 (isvce_mb_hdr_p16x16_t *) ps_ent_ctxt->pv_mb_header_data;
1514
1515 /* inter macro block partition cnt */
1516 const UWORD8 au1_part_cnt[] = {1, 2, 2, 4};
1517
1518 /* mv ptr */
1519 WORD16 *pi2_mv_ptr = (WORD16 *) ps_mb_hdr_p16x16->ai2_mvd;
1520
1521 /* number of partitions for the current mb */
1522 UWORD32 u4_part_cnt = au1_part_cnt[mb_type - 3];
1523
1524 is_inter = 1;
1525
1526 /* write mb type */
1527 PUT_BITS_UEV(ps_bitstream, mb_type - 3, error_status, "mb type");
1528
1529 for(i = 0; i < (WORD32) u4_part_cnt; i++)
1530 {
1531 if(ps_ent_ctxt->u1_spatial_layer_id &&
1532 ps_svc_slice_header->i1_adaptive_motion_prediction_flag)
1533 {
1534 PUT_BITS(ps_bitstream, ps_mb_hdr_p16x16->u1_mvp_idx, 1, error_status,
1535 "motion_prediction_flag_l0");
1536 }
1537 }
1538
1539 for(i = 0; i < (WORD32) u4_part_cnt; i++)
1540 {
1541 PUT_BITS_SEV(ps_bitstream, pi2_mv_ptr[i], error_status, "mv x");
1542 PUT_BITS_SEV(ps_bitstream, pi2_mv_ptr[i + 1], error_status, "mv y");
1543 }
1544
1545 pu1_byte += sizeof(isvce_mb_hdr_p16x16_t);
1546 }
1547 }
1548 else
1549 {
1550 pu1_byte += sizeof(isvce_mb_hdr_base_mode_t);
1551 }
1552
1553 if(ps_ent_ctxt->u1_spatial_layer_id &&
1554 ps_svc_slice_header->i1_adaptive_residual_prediction_flag &&
1555 !ps_ent_ctxt
1556 ->ps_svc_nalu_ext_base[1 + (ps_ent_ctxt->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT)]
1557 .u1_idr_flag &&
1558 (ps_mb_hdr->u1_base_mode_flag || !u1_is_intra_mb))
1559 {
1560 PUT_BITS(ps_bitstream, ps_mb_hdr->u1_residual_prediction_flag, 1, error_status,
1561 "residual_prediction_flag");
1562 }
1563
1564 /* coded_block_pattern */
1565 if(ps_mb_hdr->u1_base_mode_flag || (mb_type != I16x16))
1566 {
1567 PUT_BITS_UEV(ps_bitstream, gu1_cbp_map_tables[cbp][cbptable], error_status,
1568 "coded_block_pattern");
1569 }
1570
1571 if((cbp > 0) || (mb_type == I16x16))
1572 {
1573 /* mb_qp_delta */
1574 PUT_BITS_SEV(ps_bitstream, mb_qp_delta, error_status, "mb_qp_delta");
1575 ps_ent_ctxt->ps_mb_qp_ctxt->u1_cur_mb_qp = ps_mb_hdr->u1_mb_qp;
1576 }
1577
1578 /* Ending bitstream offset for header in bits */
1579 bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
1580
1581 ps_ent_ctxt->u4_header_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
1582
1583 /* start bitstream offset for residue in bits */
1584 bitstream_start_offset = bitstream_end_offset;
1585
1586 /* residual */
1587 error_status = isvce_encode_residue(ps_ent_ctxt, mb_type, cbp);
1588
1589 /* Ending bitstream offset for residue in bits */
1590 bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
1591
1592 ps_ent_ctxt->u4_residue_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
1593
1594 /* store the index of the next mb syntax layer */
1595 ps_ent_ctxt->pv_mb_header_data = pu1_byte;
1596
1597 return error_status;
1598 }
1599
1600 /**
1601 *******************************************************************************
1602 *
1603 * @brief
1604 * This function generates CAVLC coded bit stream for B slices
1605 *
1606 * @description
1607 * The mb syntax layer for inter slices constitutes luma mb mode, luma sub modes
1608 * (if present), mb qp delta, coded block pattern, chroma mb mode and
1609 * luma/chroma residue. These syntax elements are written as directed by table
1610 * 7.3.5 of h264 specification
1611 *
1612 * @param[in] ps_ent_ctxt
1613 * pointer to entropy context
1614 *
1615 * @returns error code
1616 *
1617 * @remarks none
1618 *
1619 *******************************************************************************
1620 */
isvce_write_bslice_mb_cavlc(isvce_entropy_ctxt_t * ps_ent_ctxt)1621 IH264E_ERROR_T isvce_write_bslice_mb_cavlc(isvce_entropy_ctxt_t *ps_ent_ctxt)
1622 {
1623 /* mb header info */
1624 /*
1625 * mb_tpm : mb type plus mode
1626 * mb_type : luma mb type and chroma mb type are packed
1627 * cbp : coded block pattern
1628 * mb_qp_delta : mb qp delta
1629 * chroma_intra_mode : chroma intra mode
1630 * luma_intra_mode : luma intra mode
1631 * ps_pu : Pointer to the array of structures having motion vectors, size
1632 * and position of sub partitions
1633 */
1634 WORD32 mb_tpm, mb_type, cbp, chroma_intra_mode, luma_intra_mode;
1635 WORD8 mb_qp_delta;
1636 WORD32 i, j;
1637 WORD32 mb_type_stream;
1638 WORD32 bitstream_start_offset, bitstream_end_offset;
1639 UWORD8 u1_is_intra_mb;
1640
1641 bitstrm_t *ps_bitstream = ps_ent_ctxt->ps_bitstrm;
1642 isvce_mb_hdr_common_t *ps_mb_hdr = (isvce_mb_hdr_common_t *) ps_ent_ctxt->pv_mb_header_data;
1643 svc_slice_header_t *ps_svc_slice_header =
1644 ps_ent_ctxt->ps_svc_slice_hdr_base +
1645 (ps_ent_ctxt->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
1646
1647 IH264E_ERROR_T error_status = IH264E_SUCCESS;
1648
1649 UWORD8 *pu1_byte = ps_ent_ctxt->pv_mb_header_data;
1650 WORD32 cbptable = 1;
1651 WORD32 is_inter = 0;
1652
1653 /* Starting bitstream offset for header in bits */
1654 bitstream_start_offset = isvce_get_num_bits(ps_bitstream);
1655
1656 /********************************************************************/
1657 /* BEGIN HEADER GENERATION */
1658 /********************************************************************/
1659
1660 mb_tpm = ps_mb_hdr->u1_mb_type_mode;
1661
1662 /* mb type */
1663 mb_type = mb_tpm & 0xF;
1664 u1_is_intra_mb = (mb_type == I16x16) || (mb_type == I8x8) || (mb_type == I4x4);
1665
1666 /* check for skip */
1667 if(mb_type == BSKIP)
1668 {
1669 UWORD32 *nnz;
1670
1671 is_inter = 1;
1672
1673 /* increment skip counter */
1674 (*ps_ent_ctxt->pi4_mb_skip_run)++;
1675
1676 /* store the index of the next mb syntax layer */
1677 pu1_byte += sizeof(isvce_mb_hdr_bskip_t);
1678 ps_ent_ctxt->pv_mb_header_data = pu1_byte;
1679
1680 /* set nnz to zero */
1681 ps_ent_ctxt->u4_left_nnz_luma = 0;
1682 nnz = (UWORD32 *) ps_ent_ctxt->pu1_top_nnz_luma[ps_ent_ctxt->i4_mb_x];
1683 *nnz = 0;
1684 ps_ent_ctxt->u4_left_nnz_cbcr = 0;
1685 nnz = (UWORD32 *) ps_ent_ctxt->pu1_top_nnz_cbcr[ps_ent_ctxt->i4_mb_x];
1686 *nnz = 0;
1687
1688 /* residual */
1689 error_status = isvce_encode_residue(ps_ent_ctxt, B16x16, 0);
1690
1691 bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
1692
1693 ps_ent_ctxt->u4_header_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
1694
1695 return error_status;
1696 }
1697
1698 /* remaining mb header info */
1699 cbp = ps_mb_hdr->u1_cbp;
1700 mb_qp_delta =
1701 ((WORD16) ps_mb_hdr->u1_mb_qp) - ((WORD16) ps_ent_ctxt->ps_mb_qp_ctxt->u1_cur_mb_qp);
1702
1703 /* mb skip run */
1704 PUT_BITS_UEV(ps_bitstream, *ps_ent_ctxt->pi4_mb_skip_run, error_status, "mb skip run");
1705
1706 /* reset skip counter */
1707 *ps_ent_ctxt->pi4_mb_skip_run = 0;
1708
1709 if(ps_ent_ctxt->u1_spatial_layer_id && ps_svc_slice_header->i1_adaptive_base_mode_flag)
1710 {
1711 /* write base_mode_flag */
1712 PUT_BITS(ps_bitstream, ps_mb_hdr->u1_base_mode_flag, 1, error_status, "base_mode_flag");
1713 }
1714 else
1715 {
1716 ps_mb_hdr->u1_base_mode_flag = 0;
1717 }
1718
1719 if(!ps_mb_hdr->u1_base_mode_flag)
1720 {
1721 /* is intra ? */
1722 if(mb_type == I16x16)
1723 {
1724 UWORD32 u4_cbp_l, u4_cbp_c;
1725
1726 is_inter = 0;
1727
1728 u4_cbp_c = (cbp >> 4);
1729 u4_cbp_l = (cbp & 0xF);
1730 luma_intra_mode = (mb_tpm >> 4) & 3;
1731 chroma_intra_mode = (mb_tpm >> 6);
1732
1733 mb_type_stream = luma_intra_mode + 1 + (u4_cbp_c << 2) + (u4_cbp_l == 15) * 12;
1734
1735 mb_type_stream += 23;
1736
1737 /* write mb type */
1738 PUT_BITS_UEV(ps_bitstream, mb_type_stream, error_status, "mb type");
1739
1740 /* intra_chroma_pred_mode */
1741 PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1742 pu1_byte += sizeof(isvce_mb_hdr_i16x16_t);
1743 }
1744 else if(mb_type == I4x4)
1745 {
1746 isvce_mb_hdr_i4x4_t *ps_mb_hdr_i4x4 =
1747 (isvce_mb_hdr_i4x4_t *) ps_ent_ctxt->pv_mb_header_data;
1748
1749 /* mb sub blk modes */
1750 WORD32 intra_pred_mode_flag, rem_intra_mode;
1751 WORD32 byte;
1752
1753 is_inter = 0;
1754
1755 chroma_intra_mode = (mb_tpm >> 6);
1756 cbptable = 0;
1757
1758 /* write mb type */
1759 PUT_BITS_UEV(ps_bitstream, 23, error_status, "mb type");
1760
1761 for(i = 0; i < 16; i += 2)
1762 {
1763 /* sub blk idx 1 */
1764 byte = ps_mb_hdr_i4x4->au1_sub_blk_modes[i >> 1];
1765
1766 intra_pred_mode_flag = byte & 0x1;
1767
1768 /* prev_intra4x4_pred_mode_flag */
1769 PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
1770 "prev_intra4x4_pred_mode_flag");
1771
1772 /* rem_intra4x4_pred_mode */
1773 if(!intra_pred_mode_flag)
1774 {
1775 rem_intra_mode = (byte & 0xF) >> 1;
1776 PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
1777 "rem_intra4x4_pred_mode");
1778 }
1779
1780 /* sub blk idx 2 */
1781 byte >>= 4;
1782
1783 intra_pred_mode_flag = byte & 0x1;
1784
1785 /* prev_intra4x4_pred_mode_flag */
1786 PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
1787 "prev_intra4x4_pred_mode_flag");
1788
1789 /* rem_intra4x4_pred_mode */
1790 if(!intra_pred_mode_flag)
1791 {
1792 rem_intra_mode = (byte & 0xF) >> 1;
1793 PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
1794 "rem_intra4x4_pred_mode");
1795 }
1796 }
1797
1798 /* intra_chroma_pred_mode */
1799 PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1800 pu1_byte += sizeof(isvce_mb_hdr_i4x4_t);
1801 }
1802 else if(mb_type == I8x8)
1803 {
1804 isvce_mb_hdr_i8x8_t *ps_mb_hdr_i8x8 =
1805 (isvce_mb_hdr_i8x8_t *) ps_ent_ctxt->pv_mb_header_data;
1806
1807 /* transform 8x8 flag */
1808 UWORD32 u4_transform_size_8x8_flag = ps_ent_ctxt->i1_transform_8x8_mode_flag;
1809
1810 /* mb sub blk modes */
1811 WORD32 intra_pred_mode_flag, rem_intra_mode;
1812 WORD32 byte;
1813
1814 is_inter = 0;
1815
1816 chroma_intra_mode = (mb_tpm >> 6);
1817 cbptable = 0;
1818
1819 ASSERT(0);
1820
1821 /* write mb type */
1822 PUT_BITS_UEV(ps_bitstream, 23, error_status, "mb type");
1823
1824 /* u4_transform_size_8x8_flag */
1825 PUT_BITS(ps_bitstream, u4_transform_size_8x8_flag, 1, error_status,
1826 "u4_transform_size_8x8_flag");
1827
1828 /* write sub block modes */
1829 for(i = 0; i < 4; i++)
1830 {
1831 /* sub blk idx 1 */
1832 byte = ps_mb_hdr_i8x8->au1_sub_blk_modes[i >> 1];
1833
1834 intra_pred_mode_flag = byte & 0x1;
1835
1836 /* prev_intra4x4_pred_mode_flag */
1837 PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
1838 "prev_intra4x4_pred_mode_flag");
1839
1840 /* rem_intra4x4_pred_mode */
1841 if(!intra_pred_mode_flag)
1842 {
1843 rem_intra_mode = (byte & 0xF) >> 1;
1844 PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
1845 "rem_intra4x4_pred_mode");
1846 }
1847
1848 /* sub blk idx 2 */
1849 byte >>= 4;
1850
1851 intra_pred_mode_flag = byte & 0x1;
1852
1853 /* prev_intra4x4_pred_mode_flag */
1854 PUT_BITS(ps_bitstream, intra_pred_mode_flag, 1, error_status,
1855 "prev_intra4x4_pred_mode_flag");
1856
1857 /* rem_intra4x4_pred_mode */
1858 if(!intra_pred_mode_flag)
1859 {
1860 rem_intra_mode = (byte & 0xF) >> 1;
1861 PUT_BITS(ps_bitstream, rem_intra_mode, 3, error_status,
1862 "rem_intra4x4_pred_mode");
1863 }
1864 }
1865
1866 /* intra_chroma_pred_mode */
1867 PUT_BITS_UEV(ps_bitstream, chroma_intra_mode, error_status, "intra_chroma_pred_mode");
1868 pu1_byte += sizeof(isvce_mb_hdr_i8x8_t);
1869 }
1870 else if(mb_type == BDIRECT)
1871 {
1872 is_inter = 1;
1873 /* write mb type */
1874 PUT_BITS_UEV(ps_bitstream, B_DIRECT_16x16, error_status, "mb type");
1875 pu1_byte += sizeof(isvce_mb_hdr_bdirect_t);
1876 }
1877 else
1878 {
1879 isvce_mb_hdr_b16x16_t *ps_mb_hdr_b16x16 =
1880 (isvce_mb_hdr_b16x16_t *) ps_ent_ctxt->pv_mb_header_data;
1881
1882 /* inter macro block partition cnt for 16x16 16x8 8x16 8x8 */
1883 const UWORD8 au1_part_cnt[] = {1, 2, 2, 4};
1884
1885 /* number of partitions for the current mb */
1886 UWORD32 u4_part_cnt = au1_part_cnt[mb_type - B16x16];
1887
1888 /* Get the pred modes */
1889 WORD32 i4_mb_part_pred_mode = (mb_tpm >> 4);
1890
1891 ASSERT(mb_type == B16x16);
1892
1893 is_inter = 1;
1894
1895 mb_type_stream = mb_type - B16x16 + B_L0_16x16 + i4_mb_part_pred_mode;
1896
1897 /* write mb type */
1898 PUT_BITS_UEV(ps_bitstream, mb_type_stream, error_status, "mb type");
1899
1900 for(i = 0; i < (WORD32) u4_part_cnt; i++)
1901 {
1902 for(j = 0; j < NUM_PRED_DIRS; j++)
1903 {
1904 PRED_MODE_T e_pred_mode = (PRED_MODE_T) j;
1905 PRED_MODE_T e_cmpl_pred_mode = (e_pred_mode == L0) ? L1 : L0;
1906
1907 if(((PRED_MODE_T) i4_mb_part_pred_mode) != e_pred_mode)
1908 {
1909 if(ps_svc_slice_header->i1_adaptive_motion_prediction_flag &&
1910 ps_ent_ctxt->u1_spatial_layer_id)
1911 {
1912 PUT_BITS(ps_bitstream, ps_mb_hdr_b16x16->au1_mvp_idx[e_cmpl_pred_mode],
1913 1, error_status, "motion_prediction_flag_l0");
1914 }
1915 }
1916 }
1917 }
1918
1919 for(i = 0; i < (WORD32) u4_part_cnt; i++)
1920 {
1921 if(i4_mb_part_pred_mode != L1)
1922 {
1923 PUT_BITS_SEV(ps_bitstream, ps_mb_hdr_b16x16->ai2_mvd[0][0], error_status,
1924 "mv l0 x");
1925 PUT_BITS_SEV(ps_bitstream, ps_mb_hdr_b16x16->ai2_mvd[0][1], error_status,
1926 "mv l0 y");
1927 }
1928 if(i4_mb_part_pred_mode != L0)
1929 {
1930 PUT_BITS_SEV(ps_bitstream, ps_mb_hdr_b16x16->ai2_mvd[1][0], error_status,
1931 "mv l1 x");
1932 PUT_BITS_SEV(ps_bitstream, ps_mb_hdr_b16x16->ai2_mvd[1][1], error_status,
1933 "mv l1 y");
1934 }
1935 }
1936
1937 pu1_byte += sizeof(isvce_mb_hdr_b16x16_t);
1938 }
1939 }
1940
1941 if(ps_svc_slice_header->i1_adaptive_residual_prediction_flag &&
1942 ps_ent_ctxt->u1_spatial_layer_id && (ps_mb_hdr->u1_base_mode_flag || !u1_is_intra_mb))
1943 {
1944 PUT_BITS(ps_bitstream, ps_mb_hdr->u1_residual_prediction_flag, 1, error_status,
1945 "residual_prediction_flag");
1946 }
1947
1948 /* coded_block_pattern */
1949 if(ps_mb_hdr->u1_base_mode_flag || mb_type != I16x16)
1950 {
1951 PUT_BITS_UEV(ps_bitstream, gu1_cbp_map_tables[cbp][cbptable], error_status,
1952 "coded_block_pattern");
1953 }
1954
1955 if((cbp > 0) || (mb_type == I16x16))
1956 {
1957 /* mb_qp_delta */
1958 PUT_BITS_SEV(ps_bitstream, mb_qp_delta, error_status, "mb_qp_delta");
1959 ps_ent_ctxt->ps_mb_qp_ctxt->u1_cur_mb_qp = ps_mb_hdr->u1_mb_qp;
1960 }
1961
1962 /* Ending bitstream offset for header in bits */
1963 bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
1964
1965 ps_ent_ctxt->u4_header_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
1966
1967 /* start bitstream offset for residue in bits */
1968 bitstream_start_offset = bitstream_end_offset;
1969
1970 /* residual */
1971 error_status = isvce_encode_residue(ps_ent_ctxt, mb_type, cbp);
1972
1973 /* Ending bitstream offset for residue in bits */
1974 bitstream_end_offset = isvce_get_num_bits(ps_bitstream);
1975
1976 ps_ent_ctxt->u4_residue_bits[is_inter] += bitstream_end_offset - bitstream_start_offset;
1977
1978 /* store the index of the next mb syntax layer */
1979 ps_ent_ctxt->pv_mb_header_data = pu1_byte;
1980
1981 return error_status;
1982 }
1983
1984 #if ENABLE_RE_ENC_AS_SKIP
1985 /**
1986 ******************************************************************************
1987 *
1988 * @brief re-encode frame as all skip MBs
1989 *
1990 * @par Description
1991 * The frame is encoded as all skip MBs to comply with VBV restrictions
1992 *
1993 * @param[in] ps_entropy
1994 * pointer to entropy context (handle)
1995 *
1996 * @return success or failure error code
1997 *
1998 ******************************************************************************
1999 */
isvce_reencode_as_skip_frame_cavlc(isvce_entropy_ctxt_t * ps_entropy)2000 IH264E_ERROR_T isvce_reencode_as_skip_frame_cavlc(isvce_entropy_ctxt_t *ps_entropy)
2001 {
2002 WORD32 i4_mb_skip_run;
2003
2004 bitstrm_t *ps_bitstrm = ps_entropy->ps_bitstrm;
2005 bitstrm_t *ps_bitstrm_after_slice_hdr = ps_entropy->ps_bitstrm_after_slice_hdr;
2006
2007 ps_bitstrm->i4_bits_left_in_cw = ps_bitstrm_after_slice_hdr->i4_bits_left_in_cw;
2008 ps_bitstrm->u4_cur_word = ps_bitstrm_after_slice_hdr->u4_cur_word;
2009 ps_bitstrm->u4_strm_buf_offset = ps_bitstrm_after_slice_hdr->u4_strm_buf_offset;
2010 ps_bitstrm->i4_zero_bytes_run = ps_bitstrm_after_slice_hdr->i4_zero_bytes_run;
2011
2012 /* mb skip run */
2013 i4_mb_skip_run = ps_entropy->i4_wd_mbs * ps_entropy->i4_ht_mbs;
2014 PUT_BITS_UEV(ps_bitstrm, i4_mb_skip_run, ps_entropy->i4_error_code, "mb skip run");
2015
2016 /* put rbsp trailing bits */
2017 ps_entropy->i4_error_code = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
2018
2019 return ps_entropy->i4_error_code;
2020 }
2021 #endif
2022