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