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