1 /******************************************************************************
2 *
3 * Copyright (C) 2022 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************
18 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20
21 /**
22 *******************************************************************************
23 * @file
24 * isvce_process.c
25 *
26 * @brief
27 * Contains functions for codec thread
28 *
29 * @author
30 * Harish
31 *
32 * @par List of Functions:
33 * - isvce_generate_sps_pps()
34 * - isvce_init_entropy_ctxt()
35 * - isvce_entropy()
36 * - isvce_pack_header_data()
37 * - isvce_update_proc_ctxt()
38 * - isvce_init_proc_ctxt()
39 * - isvce_pad_recon_buffer()
40 * - isvce_dblk_n_mbs()
41 * - isvce_process()
42 * - isvce_set_rc_pic_params()
43 * - isvce_update_rc_post_enc()
44 * - isvce_isvce_isvce_process_ctxt_thread()
45 *
46 * @remarks
47 * None
48 *
49 *******************************************************************************
50 */
51
52 #include <stdio.h>
53 #include <stddef.h>
54 #include <stdlib.h>
55 #include <string.h>
56 #include <limits.h>
57 #include <assert.h>
58 #include <math.h>
59 #include <stdbool.h>
60
61 #include "ih264_typedefs.h"
62 /* Dependencies of ih264_buf_mgr.h */
63 /* Dependencies of ih264_list.h */
64 #include "ih264_error.h"
65 /* Dependencies of ih264_common_tables.h */
66 #include "ih264_defs.h"
67 #include "ih264_structs.h"
68 #include "ih264_buf_mgr.h"
69 #include "ih264_common_tables.h"
70 #include "ih264_list.h"
71 #include "ih264_platform_macros.h"
72 #include "ih264_trans_data.h"
73 #include "ih264_size_defs.h"
74 /* Dependencies of ih264e_cabac_structs.h */
75 #include "ih264_cabac_tables.h"
76 /* Dependencies of ime_structs.h */
77 #include "ime_defs.h"
78 #include "ime_distortion_metrics.h"
79 /* Dependencies of ih264e_structs.h */
80 #include "iv2.h"
81 #include "ive2.h"
82 #include "ih264_defs.h"
83 #include "ih264_deblk_edge_filters.h"
84 #include "ih264_inter_pred_filters.h"
85 #include "ih264_structs.h"
86 #include "ih264_trans_quant_itrans_iquant.h"
87 /* Dependencies of ih264e_bitstream.h */
88 #include "ih264e_error.h"
89 #include "ih264e_bitstream.h"
90 #include "ih264e_cabac_structs.h"
91 #include "irc_cntrl_param.h"
92 #include "irc_frame_info_collector.h"
93 #include "ime_statistics.h"
94 #include "ime_structs.h"
95 /* Dependencies of 'ih264e_utils.h' */
96 #include "ih264e_defs.h"
97 #include "ih264e_structs.h"
98 #include "ih264e_utils.h"
99 #include "ime.h"
100 #include "isvce_cabac.h"
101 #include "isvce_cavlc.h"
102 #include "isvce_deblk.h"
103 #include "isvce_defs.h"
104 #include "isvce_downscaler.h"
105 #include "isvce_encode_header.h"
106 #include "isvce_ibl_eval.h"
107 #include "isvce_ilp_mv.h"
108 #include "isvce_intra_modes_eval.h"
109 #include "isvce_me.h"
110 #include "isvce_rate_control.h"
111 #include "isvce_residual_pred.h"
112 #include "isvce_sub_pic_rc.h"
113 #include "isvce_utils.h"
114
115 /*****************************************************************************/
116 /* Function Definitions */
117 /*****************************************************************************/
118
119 /**
120 ******************************************************************************
121 *
122 * @brief This function generates sps, pps set on request
123 *
124 * @par Description
125 * When the encoder is set in header generation mode, the following function
126 * is called. This generates sps and pps headers and returns the control back
127 * to caller.
128 *
129 * @param[in] ps_codec
130 * pointer to codec context
131 *
132 * @return success or failure error code
133 *
134 ******************************************************************************
135 */
isvce_generate_sps_pps(isvce_codec_t * ps_codec,isvce_inp_buf_t * ps_inp_buf)136 IH264E_ERROR_T isvce_generate_sps_pps(isvce_codec_t *ps_codec, isvce_inp_buf_t *ps_inp_buf)
137 {
138 sps_t *ps_sps;
139 pps_t *ps_pps;
140 subset_sps_t *ps_subset_sps;
141
142 WORD32 i;
143
144 isvce_process_ctxt_t *ps_proc = ps_codec->as_process;
145 isvce_entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
146 bitstrm_t *ps_bitstrm = ps_entropy->ps_bitstrm;
147 isvce_out_buf_t *ps_out_buf = ps_codec->as_out_buf;
148
149 UWORD8 u1_profile_idc = IH264_PROFILE_BASELINE;
150
151 ASSERT(1 == MAX_CTXT_SETS);
152
153 ih264e_bitstrm_init(ps_bitstrm, ps_out_buf->as_bits_buf[ps_proc->u1_spatial_layer_id].pv_buf,
154 ps_out_buf->as_bits_buf[ps_proc->u1_spatial_layer_id].u4_bufsize);
155
156 ps_sps = ps_codec->ps_sps_base;
157 isvce_populate_sps(ps_codec, ps_sps, 0, u1_profile_idc, ps_inp_buf, 0);
158
159 ps_pps = ps_codec->ps_pps_base;
160 isvce_populate_pps(ps_codec, ps_pps, 0, 0, 0);
161
162 for(i = 1; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers; i++)
163 {
164 ps_subset_sps = ps_codec->ps_subset_sps_base + i;
165 isvce_populate_subset_sps(ps_codec, ps_subset_sps, i, ps_inp_buf, i);
166
167 ps_pps = ps_codec->ps_pps_base + i;
168 isvce_populate_pps(ps_codec, ps_pps, i, i, i);
169 }
170
171 ps_entropy->i4_error_code = IH264E_SUCCESS;
172
173 ps_entropy->i4_error_code = isvce_generate_sps(ps_bitstrm, ps_sps, NAL_SPS);
174 if(ps_entropy->i4_error_code != IH264E_SUCCESS)
175 {
176 return ps_entropy->i4_error_code;
177 }
178
179 ps_pps = ps_codec->ps_pps_base;
180 ps_entropy->i4_error_code = isvce_generate_pps(ps_bitstrm, ps_pps, ps_sps);
181
182 for(i = 1; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers; i++)
183 {
184 ps_subset_sps = ps_codec->ps_subset_sps_base + i;
185 isvce_generate_subset_sps(ps_bitstrm, ps_subset_sps);
186
187 /* populate pps header */
188 ps_pps = ps_codec->ps_pps_base + i;
189 isvce_generate_pps(ps_bitstrm, ps_pps, &ps_subset_sps->s_sps);
190 }
191
192 /* queue output buffer */
193 ps_out_buf->as_bits_buf[ps_proc->u1_spatial_layer_id].u4_bytes = ps_bitstrm->u4_strm_buf_offset;
194
195 return ps_entropy->i4_error_code;
196 }
197
198 /**
199 *******************************************************************************
200 *
201 * @brief initialize entropy context.
202 *
203 * @par Description:
204 * Before invoking the call to perform to entropy coding the entropy context
205 * associated with the job needs to be initialized. This involves the start
206 * mb address, end mb address, slice index and the pointer to location at
207 * which the mb residue info and mb header info are packed.
208 *
209 * @param[in] ps_proc
210 * Pointer to the current process context
211 *
212 * @returns error status
213 *
214 * @remarks none
215 *
216 *******************************************************************************
217 */
isvce_init_entropy_ctxt(isvce_process_ctxt_t * ps_proc)218 IH264E_ERROR_T isvce_init_entropy_ctxt(isvce_process_ctxt_t *ps_proc)
219 {
220 /* codec context */
221 isvce_codec_t *ps_codec = ps_proc->ps_codec;
222
223 /* entropy ctxt */
224 isvce_entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
225
226 /* start address */
227 ps_entropy->i4_mb_start_add = ps_entropy->i4_mb_y * ps_entropy->i4_wd_mbs + ps_entropy->i4_mb_x;
228
229 /* end address */
230 ps_entropy->i4_mb_end_add = ps_entropy->i4_mb_start_add + ps_entropy->i4_mb_cnt;
231
232 /* slice index */
233 ps_entropy->i4_cur_slice_idx = ps_proc->pu1_slice_idx[ps_entropy->i4_mb_start_add];
234
235 /* sof */
236 /* @ start of frame or start of a new slice, set sof flag */
237 if(ps_entropy->i4_mb_start_add == 0)
238 {
239 ps_entropy->i4_sof = 1;
240 }
241
242 if(ps_entropy->i4_mb_x == 0)
243 {
244 /* packed mb coeff data */
245 ps_entropy->pv_mb_coeff_data = ((UWORD8 *) ps_entropy->pv_pic_mb_coeff_data) +
246 ps_entropy->i4_mb_y * ps_codec->u4_size_coeff_data;
247
248 /* packed mb header data */
249 ps_entropy->pv_mb_header_data = ((UWORD8 *) ps_entropy->pv_pic_mb_header_data) +
250 ps_entropy->i4_mb_y * ps_codec->u4_size_header_data;
251 }
252
253 return IH264E_SUCCESS;
254 }
255
256 /**
257 *******************************************************************************
258 *
259 * @brief
260 * Function to update rc context after encoding
261 *
262 * @par Description
263 * This function updates the rate control context after the frame is encoded.
264 * Number of bits consumed by the current frame, frame distortion, frame cost,
265 * number of intra/inter mb's, ... are passed on to rate control context for
266 * updating the rc model.
267 *
268 * @param[in] ps_codec
269 * Handle to codec context
270 *
271 * @param[in] ctxt_sel
272 * frame context selector
273 *
274 * @param[in] pic_cnt
275 * pic count
276 *
277 * @returns i4_stuffing_byte
278 * number of stuffing bytes (if necessary)
279 *
280 * @remarks
281 *
282 *******************************************************************************
283 */
isvce_update_rc_post_enc(isvce_codec_t * ps_codec,WORD32 ctxt_sel,WORD32 i4_is_first_frm)284 WORD32 isvce_update_rc_post_enc(isvce_codec_t *ps_codec, WORD32 ctxt_sel, WORD32 i4_is_first_frm)
285 {
286 WORD32 i4_proc_ctxt_sel_base = ctxt_sel ? (MAX_PROCESS_CTXT / 2) : 0;
287
288 isvce_process_ctxt_t *ps_proc = &ps_codec->as_process[i4_proc_ctxt_sel_base];
289
290 #if ENABLE_RE_ENC_AS_SKIP
291 isvce_entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
292
293 UWORD8 u1_is_post_enc_skip = 0;
294 #endif
295
296 /* frame qp */
297 UWORD8 u1_frame_qp = ps_codec->au4_frame_qp[ps_proc->u1_spatial_layer_id];
298
299 /* cbr rc return status */
300 WORD32 i4_stuffing_byte = 0;
301
302 /* current frame stats */
303 frame_info_t s_frame_info;
304 picture_type_e rc_pic_type = I_PIC;
305
306 /* temp var */
307 WORD32 i, j;
308
309 /********************************************************************/
310 /* BEGIN INIT */
311 /********************************************************************/
312
313 /* init frame info */
314 irc_init_frame_info(&s_frame_info);
315
316 /* get frame info */
317 for(i = 0; i < (WORD32) ps_codec->s_cfg.u4_num_cores; i++)
318 {
319 /*****************************************************************/
320 /* One frame can be encoded by max of u4_num_cores threads */
321 /* Accumulating the num mbs, sad, qp and intra_mb_cost from */
322 /* u4_num_cores threads */
323 /*****************************************************************/
324 for(j = 0; j < MAX_MB_TYPE; j++)
325 {
326 s_frame_info.num_mbs[j] += ps_proc[i].s_frame_info.num_mbs[j];
327
328 s_frame_info.tot_mb_sad[j] += ps_proc[i].s_frame_info.tot_mb_sad[j];
329
330 s_frame_info.qp_sum[j] += ps_proc[i].s_frame_info.qp_sum[j];
331 }
332
333 s_frame_info.intra_mb_cost_sum += ps_proc[i].s_frame_info.intra_mb_cost_sum;
334
335 s_frame_info.activity_sum += ps_proc[i].s_frame_info.activity_sum;
336
337 /*****************************************************************/
338 /* gather number of residue and header bits consumed by the frame*/
339 /*****************************************************************/
340 isvce_update_rc_bits_info(&s_frame_info, &ps_proc[i].s_entropy);
341 }
342
343 /* get pic type */
344 switch(ps_codec->pic_type)
345 {
346 case PIC_I:
347 case PIC_IDR:
348 rc_pic_type = I_PIC;
349 break;
350 case PIC_P:
351 rc_pic_type = P_PIC;
352 break;
353 case PIC_B:
354 rc_pic_type = B_PIC;
355 break;
356 default:
357 assert(0);
358 break;
359 }
360
361 /* update rc lib with current frame stats */
362 i4_stuffing_byte = isvce_rc_post_enc(
363 ps_codec->s_rate_control.apps_rate_control_api[ps_proc->u1_spatial_layer_id],
364 &(s_frame_info), ps_codec->s_rate_control.pps_pd_frm_rate,
365 ps_codec->s_rate_control.pps_time_stamp, ps_codec->s_rate_control.pps_frame_time,
366 (ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs), &rc_pic_type, i4_is_first_frm,
367 &ps_codec->s_rate_control.post_encode_skip[ctxt_sel], u1_frame_qp,
368 &ps_codec->s_rate_control.ai4_num_intra_in_prev_frame[ps_proc->u1_spatial_layer_id],
369 &ps_codec->s_rate_control.ai4_avg_activity[ps_proc->u1_spatial_layer_id]
370 #if ENABLE_RE_ENC_AS_SKIP
371 ,
372 &u1_is_post_enc_skip
373 #endif
374 );
375
376 #if ENABLE_RE_ENC_AS_SKIP
377 if(u1_is_post_enc_skip)
378 {
379 buffer_container_t s_dst;
380
381 WORD32 i;
382
383 isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
384 mem_fxns_t *ps_mem_fxns = &ps_isa_dependent_fxns->s_mem_fxns;
385 svc_ilp_data_t *ps_svc_ilp_data = &ps_codec->s_svc_ilp_data;
386
387 UWORD8 u1_spatial_layer_id = ps_proc->u1_spatial_layer_id;
388 UWORD8 u1_num_spatial_layers = ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers;
389
390 UWORD32 u4_wd = ps_codec->s_cfg.u4_wd;
391 UWORD32 u4_ht = ps_codec->s_cfg.u4_ht;
392 DOUBLE d_spatial_res_ratio = ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio;
393
394 WORD32 i4_layer_luma_wd =
395 (WORD32) (((DOUBLE) u4_wd /
396 pow(d_spatial_res_ratio, u1_num_spatial_layers - u1_spatial_layer_id - 1)) +
397 0.99);
398 WORD32 i4_layer_luma_ht =
399 (WORD32) (((DOUBLE) u4_ht /
400 pow(d_spatial_res_ratio, u1_num_spatial_layers - u1_spatial_layer_id - 1)) +
401 0.99);
402
403 if(CABAC == ps_entropy->u1_entropy_coding_mode_flag)
404 {
405 isvce_reencode_as_skip_frame_cabac(ps_entropy);
406 }
407 else
408 {
409 isvce_reencode_as_skip_frame_cavlc(ps_entropy);
410 }
411
412 if(u1_num_spatial_layers > 1)
413 {
414 for(i = 0; i < ps_proc->i4_ht_mbs; i++)
415 {
416 for(j = 0; j < ps_proc->i4_wd_mbs; j++)
417 {
418 isvce_update_ibl_info(ps_proc->ps_intra_pred_ctxt, u1_num_spatial_layers,
419 u1_spatial_layer_id, PSKIP, j, i, 0);
420 }
421 }
422
423 if(ENABLE_ILP_MV)
424 {
425 svc_layer_data_t *ps_layer_data;
426
427 svc_au_data_t *ps_svc_au_data = ps_svc_ilp_data->ps_svc_au_data;
428
429 WORD32 i4_num_mbs = ps_proc->i4_ht_mbs * ps_proc->i4_wd_mbs;
430
431 ps_layer_data = &ps_svc_au_data->ps_svc_layer_data[ps_entropy->u1_spatial_layer_id];
432
433 memset(ps_layer_data->ps_mb_info, 0,
434 i4_num_mbs * sizeof(ps_layer_data->ps_mb_info[0]));
435
436 for(i = 0; i < i4_num_mbs; i++)
437 {
438 ps_layer_data->pu4_num_pus_in_mb[i] = 1;
439 }
440 }
441 }
442
443 for(i = 0; i < NUM_SP_COMPONENTS; i++)
444 {
445 UWORD8 u1_is_chroma = (Y != ((COMPONENT_TYPE) i));
446 WORD32 i4_src_strd = ps_proc->aps_ref_pic[0]
447 ->ps_layer_yuv_buf_props[u1_spatial_layer_id]
448 .as_component_bufs[i]
449 .i4_data_stride;
450 WORD32 i4_dst_strd = ps_proc->ps_cur_pic->ps_layer_yuv_buf_props[u1_spatial_layer_id]
451 .as_component_bufs[i]
452 .i4_data_stride;
453
454 if(u1_spatial_layer_id < (u1_num_spatial_layers - 1))
455 {
456 s_dst.i4_data_stride = ps_svc_ilp_data->ps_intra_recon_bufs[u1_spatial_layer_id]
457 .as_component_bufs[i]
458 .i4_data_stride;
459 s_dst.pv_data =
460 ((UWORD8 *) ps_svc_ilp_data->ps_intra_recon_bufs[u1_spatial_layer_id]
461 .as_component_bufs[i]
462 .pv_data);
463
464 ps_mem_fxns->pf_memset_2d((UWORD8 *) s_dst.pv_data, s_dst.i4_data_stride, 0,
465 i4_layer_luma_wd, (i4_layer_luma_ht >> u1_is_chroma));
466
467 if(ENABLE_RESIDUAL_PREDICTION)
468 {
469 WORD16 *pi2_res;
470 yuv_buf_props_t *ps_residual_buf =
471 &ps_codec->s_svc_ilp_data.ps_residual_bufs[u1_spatial_layer_id];
472
473 pi2_res = ps_residual_buf->as_component_bufs[u1_is_chroma].pv_data;
474
475 ps_mem_fxns->pf_memset_2d(
476 (UWORD8 *) pi2_res,
477 ps_residual_buf->as_component_bufs[u1_is_chroma].i4_data_stride *
478 (sizeof(WORD16) / sizeof(UWORD8)),
479 0,
480 ps_residual_buf->as_component_bufs[u1_is_chroma].i4_data_stride *
481 (sizeof(WORD16) / sizeof(UWORD8)),
482 i4_layer_luma_ht >> u1_is_chroma);
483 }
484 }
485
486 ps_mem_fxns->pf_copy_2d(
487 (UWORD8 *) (ps_proc->ps_cur_pic->ps_layer_yuv_buf_props[u1_spatial_layer_id]
488 .as_component_bufs[i]
489 .pv_data) -
490 PAD_LEFT - (PAD_TOP * i4_dst_strd),
491 i4_dst_strd,
492 (UWORD8 *) (ps_proc->aps_ref_pic[0]
493 ->ps_layer_yuv_buf_props[u1_spatial_layer_id]
494 .as_component_bufs[i]
495 .pv_data) -
496 PAD_LEFT - (PAD_TOP * i4_src_strd),
497 i4_src_strd, (i4_layer_luma_wd + PAD_WD),
498 (i4_layer_luma_ht >> u1_is_chroma) + PAD_HT);
499 }
500
501 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
502 }
503
504 #endif
505 return i4_stuffing_byte;
506 }
507
508 /**
509 *******************************************************************************
510 *
511 * @brief entry point for entropy coding
512 *
513 * @par Description
514 * This function calls lower level functions to perform entropy coding for a
515 * group (n rows) of mb's. After encoding 1 row of mb's, the function takes
516 * back the control, updates the ctxt and calls lower level functions again.
517 * This process is repeated till all the rows or group of mb's (which ever is
518 * minimum) are coded
519 *
520 * @param[in] ps_proc
521 * process context
522 *
523 * @returns error status
524 *
525 * @remarks
526 *
527 *******************************************************************************
528 */
isvce_entropy(isvce_process_ctxt_t * ps_proc)529 IH264E_ERROR_T isvce_entropy(isvce_process_ctxt_t *ps_proc)
530 {
531 svc_nalu_ext_t *aps_svc_nalu_ext[2];
532 isvce_out_buf_t s_out_buf;
533 sei_params_t s_sei;
534 nalu_info_t *ps_slice_nalu_info;
535 nalu_info_t *ps_non_vcl_nalu_info;
536
537 UWORD8 *pu1_proc_map;
538 UWORD8 *pu1_entropy_map_curr;
539 WORD32 i4_wd_mbs, i4_ht_mbs;
540 UWORD32 u4_mb_cnt, u4_mb_idx, u4_mb_end_idx, u4_insert_per_idr;
541 WORD32 bitstream_start_offset, bitstream_end_offset;
542
543 isvce_codec_t *ps_codec = ps_proc->ps_codec;
544 isvce_entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
545 isvce_cabac_ctxt_t *ps_cabac_ctxt = ps_entropy->ps_cabac;
546 sps_t *ps_sps = ps_entropy->ps_sps_base;
547 subset_sps_t *ps_subset_sps = ps_entropy->ps_subset_sps_base;
548 pps_t *ps_pps = ps_entropy->ps_pps_base;
549 slice_header_t *ps_slice_hdr =
550 ps_entropy->ps_slice_hdr_base + (ps_entropy->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
551 svc_slice_header_t *ps_svc_slice_hdr = NULL;
552 bitstrm_t *ps_bitstrm = ps_entropy->ps_bitstrm;
553 #if ENABLE_RE_ENC_AS_SKIP
554 bitstrm_t *ps_bitstrm_after_slice_hdr = ps_entropy->ps_bitstrm_after_slice_hdr;
555 #endif
556 nalu_descriptors_t *ps_nalu_descriptor =
557 &ps_codec->as_nalu_descriptors[ps_proc->u1_spatial_layer_id];
558
559 WORD32 i4_slice_type = ps_proc->i4_slice_type;
560 WORD32 ctxt_sel = ps_proc->i4_encode_api_call_cnt % MAX_CTXT_SETS;
561
562 aps_svc_nalu_ext[0] =
563 ps_entropy->ps_svc_nalu_ext_base + (ps_entropy->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
564 aps_svc_nalu_ext[1] = ps_entropy->ps_svc_nalu_ext_base + 1 +
565 (ps_entropy->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
566
567 /********************************************************************/
568 /* BEGIN INIT */
569 /********************************************************************/
570
571 /* entropy encode start address */
572 u4_mb_idx = ps_entropy->i4_mb_start_add;
573
574 /* entropy encode end address */
575 u4_mb_end_idx = ps_entropy->i4_mb_end_add;
576
577 /* width in mbs */
578 i4_wd_mbs = ps_entropy->i4_wd_mbs;
579
580 /* height in mbs */
581 i4_ht_mbs = ps_entropy->i4_ht_mbs;
582
583 /* total mb cnt */
584 u4_mb_cnt = i4_wd_mbs * i4_ht_mbs;
585
586 /* proc map */
587 pu1_proc_map = ps_proc->pu1_proc_map + ps_entropy->i4_mb_y * i4_wd_mbs;
588
589 /* entropy map */
590 pu1_entropy_map_curr = ps_entropy->pu1_entropy_map + ps_entropy->i4_mb_y * i4_wd_mbs;
591
592 /********************************************************************/
593 /* @ start of frame / slice, */
594 /* initialize the output buffer, */
595 /* initialize the bit stream buffer, */
596 /* check if sps and pps headers have to be generated, */
597 /* populate and generate slice header */
598 /********************************************************************/
599 if(ps_entropy->i4_sof)
600 {
601 /********************************************************************/
602 /* initialize the output buffer */
603 /********************************************************************/
604 s_out_buf = ps_codec->as_out_buf[ctxt_sel];
605
606 /* is last frame to encode */
607 s_out_buf.u4_is_last = ps_entropy->u4_is_last;
608
609 /* frame idx */
610 s_out_buf.u4_timestamp_high = ps_entropy->u4_timestamp_high;
611 s_out_buf.u4_timestamp_low = ps_entropy->u4_timestamp_low;
612
613 /********************************************************************/
614 /* initialize the bit stream buffer */
615 /********************************************************************/
616 ih264e_bitstrm_init(ps_bitstrm, s_out_buf.as_bits_buf[ps_proc->u1_spatial_layer_id].pv_buf,
617 s_out_buf.as_bits_buf[ps_proc->u1_spatial_layer_id].u4_bufsize);
618
619 /********************************************************************/
620 /* BEGIN HEADER GENERATION */
621 /********************************************************************/
622 if(1 == ps_entropy->i4_gen_header)
623 {
624 WORD32 i;
625
626 ps_non_vcl_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
627 isvce_nalu_info_buf_init(ps_non_vcl_nalu_info,
628 -((WORD32) isvce_get_num_bits(ps_bitstrm)), NAL_SPS,
629 ps_proc->u1_spatial_layer_id,
630 ps_proc->ps_cur_pic->i1_temporal_id, 1, !!ps_proc->u4_is_idr);
631
632 ps_entropy->i4_error_code = isvce_generate_sps(ps_bitstrm, ps_sps, NAL_SPS);
633 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
634
635 ps_non_vcl_nalu_info->i8_num_bits += isvce_get_num_bits(ps_bitstrm);
636 isvce_update_nalu_count(ps_nalu_descriptor);
637
638 for(i = 1; i < ps_proc->s_svc_params.u1_num_spatial_layers; i++)
639 {
640 ps_subset_sps = ps_entropy->ps_subset_sps_base + i;
641
642 ps_non_vcl_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
643 isvce_nalu_info_buf_init(
644 ps_non_vcl_nalu_info, -((WORD32) isvce_get_num_bits(ps_bitstrm)),
645 NAL_SUBSET_SPS, ps_proc->u1_spatial_layer_id,
646 ps_proc->ps_cur_pic->i1_temporal_id, 1, !!ps_proc->u4_is_idr);
647
648 ps_entropy->i4_error_code = isvce_generate_subset_sps(ps_bitstrm, ps_subset_sps);
649
650 ps_non_vcl_nalu_info->i8_num_bits += isvce_get_num_bits(ps_bitstrm);
651 isvce_update_nalu_count(ps_nalu_descriptor);
652 }
653
654 ps_non_vcl_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
655 isvce_nalu_info_buf_init(ps_non_vcl_nalu_info,
656 -((WORD32) isvce_get_num_bits(ps_bitstrm)), NAL_PPS,
657 ps_proc->u1_spatial_layer_id,
658 ps_proc->ps_cur_pic->i1_temporal_id, 1, !!ps_proc->u4_is_idr);
659
660 ps_entropy->i4_error_code = isvce_generate_pps(ps_bitstrm, ps_pps, ps_sps);
661 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
662
663 ps_non_vcl_nalu_info->i8_num_bits += isvce_get_num_bits(ps_bitstrm);
664 isvce_update_nalu_count(ps_nalu_descriptor);
665
666 for(i = 1; i < ps_proc->s_svc_params.u1_num_spatial_layers; i++)
667 {
668 ps_pps = ps_entropy->ps_pps_base + i;
669 ps_subset_sps = ps_entropy->ps_subset_sps_base + i;
670
671 ps_non_vcl_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
672 isvce_nalu_info_buf_init(
673 ps_non_vcl_nalu_info, -((WORD32) isvce_get_num_bits(ps_bitstrm)), NAL_PPS,
674 ps_proc->u1_spatial_layer_id, ps_proc->ps_cur_pic->i1_temporal_id, 1,
675 !!ps_proc->u4_is_idr);
676
677 ps_entropy->i4_error_code =
678 isvce_generate_pps(ps_bitstrm, ps_pps, &ps_subset_sps->s_sps);
679
680 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
681
682 ps_non_vcl_nalu_info->i8_num_bits += isvce_get_num_bits(ps_bitstrm);
683 isvce_update_nalu_count(ps_nalu_descriptor);
684 }
685
686 ps_entropy->i4_gen_header = 0;
687 }
688
689 ps_svc_slice_hdr = ps_entropy->ps_svc_slice_hdr_base +
690 (ps_entropy->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
691
692 if((ps_codec->s_cfg.s_svc_params.u1_num_temporal_layers > 1) ||
693 (ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers > 1))
694 {
695 isvce_populate_svc_nalu_extension(ps_proc, aps_svc_nalu_ext[0], NAL_PREFIX,
696 ps_proc->u4_is_idr);
697
698 if(ps_proc->u1_spatial_layer_id > 0)
699 {
700 isvce_populate_svc_nalu_extension(ps_proc, aps_svc_nalu_ext[1],
701 NAL_CODED_SLICE_EXTENSION, ps_proc->u4_is_idr);
702 }
703 }
704 else
705 {
706 isvce_populate_svc_nalu_extension(ps_proc, aps_svc_nalu_ext[0], NAL_PREFIX,
707 ps_proc->u4_is_idr);
708 }
709
710 if(ps_proc->u1_spatial_layer_id > 0)
711 {
712 ps_subset_sps = ps_entropy->ps_subset_sps_base + ps_proc->u1_spatial_layer_id;
713 ps_pps = ps_entropy->ps_pps_base + ps_proc->u1_spatial_layer_id;
714
715 ps_entropy->i4_error_code = isvce_populate_svc_slice(
716 ps_proc, ps_svc_slice_hdr, ps_pps, ps_subset_sps, aps_svc_nalu_ext[1]);
717
718 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
719
720 ps_slice_hdr = &ps_svc_slice_hdr->s_slice_header;
721 }
722 else
723 {
724 ps_pps = ps_entropy->ps_pps_base;
725 ps_sps = ps_entropy->ps_sps_base;
726
727 ps_entropy->i4_error_code = isvce_populate_slice_header(
728 ps_proc, ps_slice_hdr, ps_pps, ps_sps, aps_svc_nalu_ext[0]->u1_idr_flag);
729
730 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
731 }
732
733 /* generate sei */
734 u4_insert_per_idr = (NAL_SLICE_IDR == ps_slice_hdr->i1_nal_unit_type);
735
736 memset(&s_sei, 0, sizeof(sei_params_t));
737 s_sei.u1_sei_mdcv_params_present_flag =
738 ps_codec->s_cfg.s_sei.u1_sei_mdcv_params_present_flag;
739 s_sei.s_sei_mdcv_params = ps_codec->s_cfg.s_sei.s_sei_mdcv_params;
740 s_sei.u1_sei_cll_params_present_flag = ps_codec->s_cfg.s_sei.u1_sei_cll_params_present_flag;
741 s_sei.s_sei_cll_params = ps_codec->s_cfg.s_sei.s_sei_cll_params;
742 s_sei.u1_sei_ave_params_present_flag = ps_codec->s_cfg.s_sei.u1_sei_ave_params_present_flag;
743 s_sei.s_sei_ave_params = ps_codec->s_cfg.s_sei.s_sei_ave_params;
744 s_sei.u1_sei_ccv_params_present_flag = 0;
745 s_sei.s_sei_ccv_params =
746 ps_codec->as_inp_list[ps_codec->i4_poc % SVC_MAX_NUM_INP_FRAMES].s_inp_props.s_sei_ccv;
747
748 if((1 == ps_sps->i1_vui_parameters_present_flag) &&
749 (1 == ps_codec->s_cfg.s_vui.u1_video_signal_type_present_flag) &&
750 (1 == ps_codec->s_cfg.s_vui.u1_colour_description_present_flag) &&
751 (2 != ps_codec->s_cfg.s_vui.u1_colour_primaries) &&
752 (2 != ps_codec->s_cfg.s_vui.u1_matrix_coefficients) &&
753 (2 != ps_codec->s_cfg.s_vui.u1_transfer_characteristics) &&
754 (4 != ps_codec->s_cfg.s_vui.u1_transfer_characteristics) &&
755 (5 != ps_codec->s_cfg.s_vui.u1_transfer_characteristics))
756 {
757 s_sei.u1_sei_ccv_params_present_flag =
758 ps_codec->as_inp_list[ps_codec->i4_poc % SVC_MAX_NUM_INP_FRAMES]
759 .s_inp_props.u1_sei_ccv_params_present_flag;
760 }
761
762 if((1 == s_sei.u1_sei_mdcv_params_present_flag && u4_insert_per_idr) ||
763 (1 == s_sei.u1_sei_cll_params_present_flag && u4_insert_per_idr) ||
764 (1 == s_sei.u1_sei_ave_params_present_flag && u4_insert_per_idr) ||
765 (1 == s_sei.u1_sei_ccv_params_present_flag))
766 {
767 ps_non_vcl_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
768 isvce_nalu_info_buf_init(ps_non_vcl_nalu_info,
769 -((WORD32) isvce_get_num_bits(ps_bitstrm)), NAL_SEI,
770 ps_proc->u1_spatial_layer_id,
771 ps_proc->ps_cur_pic->i1_temporal_id, 1, !!ps_proc->u4_is_idr);
772
773 ps_entropy->i4_error_code = ih264e_generate_sei(ps_bitstrm, &s_sei, u4_insert_per_idr);
774 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
775
776 ps_non_vcl_nalu_info->i8_num_bits += isvce_get_num_bits(ps_bitstrm);
777 isvce_update_nalu_count(ps_nalu_descriptor);
778 }
779
780 ps_codec->as_inp_list[ps_codec->i4_poc % SVC_MAX_NUM_INP_FRAMES]
781 .s_inp_props.u1_sei_ccv_params_present_flag = 0;
782
783 if((ps_proc->u1_spatial_layer_id == 0) &&
784 (ps_codec->s_cfg.s_svc_params.u1_num_temporal_layers > 1 ||
785 ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers > 1))
786 {
787 ps_non_vcl_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
788 isvce_nalu_info_buf_init(ps_non_vcl_nalu_info,
789 -((WORD32) isvce_get_num_bits(ps_bitstrm)), NAL_PREFIX,
790 ps_proc->u1_spatial_layer_id,
791 ps_proc->ps_cur_pic->i1_temporal_id, 1, !!ps_proc->u4_is_idr);
792
793 ps_entropy->i4_error_code =
794 isvce_generate_svc_nalu_extension(ps_bitstrm, aps_svc_nalu_ext[0], NAL_PREFIX);
795
796 ps_entropy->i4_error_code = isvce_generate_prefix_nal(
797 ps_bitstrm, aps_svc_nalu_ext[0], ps_slice_hdr, ps_sps->u1_max_num_ref_frames,
798 ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers);
799 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
800
801 ps_non_vcl_nalu_info->i8_num_bits += isvce_get_num_bits(ps_bitstrm);
802 isvce_update_nalu_count(ps_nalu_descriptor);
803 }
804
805 ps_slice_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
806 isvce_nalu_info_buf_init(ps_slice_nalu_info, -((WORD32) isvce_get_num_bits(ps_bitstrm)),
807 ps_slice_hdr->i1_nal_unit_type, ps_proc->u1_spatial_layer_id,
808 ps_proc->ps_cur_pic->i1_temporal_id, 1, !!ps_proc->u4_is_idr);
809
810 if(ps_proc->u1_spatial_layer_id > 0)
811 {
812 ps_subset_sps = ps_entropy->ps_subset_sps_base + ps_proc->u1_spatial_layer_id;
813 ps_pps = ps_entropy->ps_pps_base + ps_proc->u1_spatial_layer_id;
814
815 ps_entropy->i4_error_code = isvce_generate_svc_nalu_extension(
816 ps_bitstrm, aps_svc_nalu_ext[1], NAL_CODED_SLICE_EXTENSION);
817
818 ps_entropy->i4_error_code = isvce_generate_slice_header_svc(
819 ps_bitstrm, ps_pps, aps_svc_nalu_ext[1], ps_svc_slice_hdr, ps_subset_sps);
820
821 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
822 }
823 else
824 {
825 /* generate slice header */
826 ps_entropy->i4_error_code = isvce_generate_slice_header(
827 ps_bitstrm, ps_slice_hdr, ps_pps, ps_sps, aps_svc_nalu_ext[0]->u1_idr_flag);
828
829 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
830 }
831
832 /* once start of frame / slice is done, you can reset it */
833 /* it is the responsibility of the caller to set this flag */
834 ps_entropy->i4_sof = 0;
835
836 if(CABAC == ps_entropy->u1_entropy_coding_mode_flag)
837 {
838 BITSTREAM_BYTE_ALIGN(ps_bitstrm);
839 BITSTREAM_FLUSH(ps_bitstrm, ps_entropy->i4_error_code);
840 isvce_init_cabac_ctxt(ps_entropy, ps_slice_hdr);
841 }
842
843 #if ENABLE_RE_ENC_AS_SKIP
844 ps_bitstrm_after_slice_hdr[0] = ps_bitstrm[0];
845 #endif
846 }
847
848 /* begin entropy coding for the mb set */
849 while(u4_mb_idx < u4_mb_end_idx)
850 {
851 mb_bits_info_t s_mb_bits = {
852 .i8_header_bits = -((WORD64) ps_entropy->u4_header_bits[i4_slice_type == PSLICE]),
853 .i8_texture_bits = -((WORD64) ps_entropy->u4_residue_bits[i4_slice_type == PSLICE])};
854
855 /* init ptrs/indices */
856 if(ps_entropy->i4_mb_x == i4_wd_mbs)
857 {
858 ps_entropy->i4_mb_y++;
859 ps_entropy->i4_mb_x = 0;
860
861 /* packed mb coeff data */
862 ps_entropy->pv_mb_coeff_data = ((UWORD8 *) ps_entropy->pv_pic_mb_coeff_data) +
863 ps_entropy->i4_mb_y * ps_codec->u4_size_coeff_data;
864
865 /* packed mb header data */
866 ps_entropy->pv_mb_header_data = ((UWORD8 *) ps_entropy->pv_pic_mb_header_data) +
867 ps_entropy->i4_mb_y * ps_codec->u4_size_header_data;
868
869 /* proc map */
870 pu1_proc_map = ps_proc->pu1_proc_map + ps_entropy->i4_mb_y * i4_wd_mbs;
871
872 /* entropy map */
873 pu1_entropy_map_curr = ps_entropy->pu1_entropy_map + ps_entropy->i4_mb_y * i4_wd_mbs;
874 }
875
876 DEBUG("\nmb indices x, y %d, %d", ps_entropy->i4_mb_x, ps_entropy->i4_mb_y);
877 ENTROPY_TRACE("mb index x %d", ps_entropy->i4_mb_x);
878 ENTROPY_TRACE("mb index y %d", ps_entropy->i4_mb_y);
879
880 /* wait until the curr mb is core coded */
881 /* The wait for curr mb to be core coded is essential when entropy is
882 * launched as a separate job
883 */
884 while(1)
885 {
886 volatile UWORD8 *pu1_buf1;
887 WORD32 idx = ps_entropy->i4_mb_x;
888
889 pu1_buf1 = pu1_proc_map + idx;
890 if(*pu1_buf1) break;
891 ithread_yield();
892 }
893
894 /* write mb layer */
895 ps_entropy->i4_error_code =
896 ps_codec->pf_write_mb_syntax_layer[ps_entropy->u1_entropy_coding_mode_flag]
897 [i4_slice_type](ps_entropy);
898 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
899
900 /* Starting bitstream offset for header in bits */
901 bitstream_start_offset = isvce_get_num_bits(ps_bitstrm);
902
903 /* set entropy map */
904 pu1_entropy_map_curr[ps_entropy->i4_mb_x] = 1;
905 ASSERT(ps_entropy->i4_mb_x < i4_wd_mbs);
906
907 u4_mb_idx++;
908 ps_entropy->i4_mb_x++;
909 /* check for eof */
910 if(CABAC == ps_entropy->u1_entropy_coding_mode_flag)
911 {
912 if(ps_entropy->i4_mb_x < i4_wd_mbs)
913 {
914 isvce_cabac_encode_terminate(ps_cabac_ctxt, 0);
915 }
916 }
917
918 if(ps_entropy->i4_mb_x == i4_wd_mbs)
919 {
920 /* if slices are enabled */
921 if(ps_codec->s_cfg.e_slice_mode == IVE_SLICE_MODE_BLOCKS)
922 {
923 /* current slice index */
924 WORD32 i4_curr_slice_idx = ps_entropy->i4_cur_slice_idx;
925
926 /* slice map */
927 UWORD8 *pu1_slice_idx = ps_entropy->pu1_slice_idx;
928
929 /* No need to open a slice at end of frame. The current slice can be
930 * closed at the time of signaling eof flag.
931 */
932 if((u4_mb_idx != u4_mb_cnt) && (i4_curr_slice_idx != pu1_slice_idx[u4_mb_idx]))
933 {
934 if(CAVLC == ps_entropy->u1_entropy_coding_mode_flag)
935 { /* mb skip run */
936 if((i4_slice_type != ISLICE) && *ps_entropy->pi4_mb_skip_run)
937 {
938 if(*ps_entropy->pi4_mb_skip_run)
939 {
940 PUT_BITS_UEV(ps_bitstrm, *ps_entropy->pi4_mb_skip_run,
941 ps_entropy->i4_error_code, "mb skip run");
942 *ps_entropy->pi4_mb_skip_run = 0;
943 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
944 }
945 }
946 /* put rbsp trailing bits for the previous slice */
947 ps_entropy->i4_error_code = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
948 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
949 }
950 else
951 {
952 isvce_cabac_encode_terminate(ps_cabac_ctxt, 1);
953 }
954
955 /* update slice header pointer */
956 i4_curr_slice_idx = pu1_slice_idx[u4_mb_idx];
957 ps_entropy->i4_cur_slice_idx = i4_curr_slice_idx;
958 ps_slice_hdr =
959 ps_entropy->ps_slice_hdr_base + (i4_curr_slice_idx % SVC_MAX_SLICE_HDR_CNT);
960
961 ps_entropy->u1_spatial_layer_id = ps_proc->u1_spatial_layer_id;
962
963 /* populate slice header */
964 ps_entropy->i4_mb_start_add = u4_mb_idx;
965
966 /* generate slice header */
967 if(ps_proc->u1_spatial_layer_id > 0)
968 {
969 ps_entropy->i4_error_code =
970 isvce_generate_slice_header_svc(ps_bitstrm, ps_pps, aps_svc_nalu_ext[1],
971 ps_svc_slice_hdr, ps_subset_sps);
972
973 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
974
975 ps_slice_hdr = &ps_svc_slice_hdr->s_slice_header;
976 }
977 else
978 {
979 ps_entropy->i4_error_code =
980 isvce_populate_slice_header(ps_proc, ps_slice_hdr, ps_pps, ps_sps,
981 aps_svc_nalu_ext[0]->u1_idr_flag);
982
983 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
984
985 ps_entropy->i4_error_code =
986 isvce_generate_slice_header(ps_bitstrm, ps_slice_hdr, ps_pps, ps_sps,
987 aps_svc_nalu_ext[0]->u1_idr_flag);
988
989 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
990 }
991
992 if(CABAC == ps_entropy->u1_entropy_coding_mode_flag)
993 {
994 BITSTREAM_BYTE_ALIGN(ps_bitstrm);
995 BITSTREAM_FLUSH(ps_bitstrm, ps_entropy->i4_error_code);
996 isvce_init_cabac_ctxt(ps_entropy, ps_slice_hdr);
997 }
998 }
999 else
1000 {
1001 if(CABAC == ps_entropy->u1_entropy_coding_mode_flag && u4_mb_idx != u4_mb_cnt)
1002 {
1003 isvce_cabac_encode_terminate(ps_cabac_ctxt, 0);
1004 }
1005 }
1006 }
1007 }
1008
1009 /* Ending bitstream offset for header in bits */
1010 bitstream_end_offset = isvce_get_num_bits(ps_bitstrm);
1011 ps_entropy->u4_header_bits[i4_slice_type == PSLICE] +=
1012 bitstream_end_offset - bitstream_start_offset;
1013
1014 {
1015 svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt = ps_proc->ps_sub_pic_rc_ctxt;
1016 svc_sub_pic_rc_entropy_variables_t *ps_sub_pic_rc_variables =
1017 &ps_sub_pic_rc_ctxt->s_sub_pic_rc_entropy_variables;
1018
1019 s_mb_bits.i8_header_bits += ps_entropy->u4_header_bits[i4_slice_type == PSLICE];
1020 s_mb_bits.i8_texture_bits += ps_entropy->u4_residue_bits[i4_slice_type == PSLICE];
1021
1022 ps_sub_pic_rc_variables->s_mb_bits = s_mb_bits;
1023 ps_sub_pic_rc_variables->u1_spatial_layer_id = ps_proc->u1_spatial_layer_id;
1024 ps_sub_pic_rc_variables->s_mb_pos.i4_abscissa = ps_entropy->i4_mb_x - 1;
1025 ps_sub_pic_rc_variables->s_mb_pos.i4_ordinate = ps_entropy->i4_mb_y;
1026
1027 isvce_sub_pic_rc_get_entropy_data(ps_proc->ps_sub_pic_rc_ctxt);
1028 }
1029 }
1030
1031 /* check for eof */
1032 if(u4_mb_idx == u4_mb_cnt)
1033 {
1034 /* set end of frame flag */
1035 ps_entropy->i4_eof = 1;
1036 }
1037 else
1038 {
1039 if(CABAC == ps_entropy->u1_entropy_coding_mode_flag &&
1040 ps_codec->s_cfg.e_slice_mode != IVE_SLICE_MODE_BLOCKS)
1041 {
1042 isvce_cabac_encode_terminate(ps_cabac_ctxt, 0);
1043 }
1044 }
1045
1046 if(ps_entropy->i4_eof)
1047 {
1048 if(CAVLC == ps_entropy->u1_entropy_coding_mode_flag)
1049 {
1050 /* mb skip run */
1051 if((i4_slice_type != ISLICE) && *ps_entropy->pi4_mb_skip_run)
1052 {
1053 if(*ps_entropy->pi4_mb_skip_run)
1054 {
1055 PUT_BITS_UEV(ps_bitstrm, *ps_entropy->pi4_mb_skip_run,
1056 ps_entropy->i4_error_code, "mb skip run");
1057 *ps_entropy->pi4_mb_skip_run = 0;
1058 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
1059 }
1060 }
1061 /* put rbsp trailing bits */
1062 ps_entropy->i4_error_code = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
1063 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
1064 }
1065 else
1066 {
1067 isvce_cabac_encode_terminate(ps_cabac_ctxt, 1);
1068 }
1069
1070 /* update current frame stats to rc library */
1071 /* number of bytes to stuff */
1072 {
1073 WORD32 i4_stuff_bytes;
1074
1075 /* update */
1076 i4_stuff_bytes = isvce_update_rc_post_enc(ps_codec, ctxt_sel, (ps_codec->i4_poc == 0));
1077
1078 if(ps_proc->u1_spatial_layer_id == (ps_proc->s_svc_params.u1_num_spatial_layers - 1))
1079 {
1080 /* cbr rc - house keeping */
1081 if(ps_codec->s_rate_control.post_encode_skip[ctxt_sel])
1082 {
1083 ps_entropy->ps_bitstrm->u4_strm_buf_offset = 0;
1084 }
1085 else if(i4_stuff_bytes > 0)
1086 {
1087 /* add filler nal units */
1088 ps_entropy->i4_error_code =
1089 ih264e_add_filler_nal_unit(ps_bitstrm, i4_stuff_bytes);
1090 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
1091 }
1092 }
1093 }
1094
1095 /*
1096 *Frame number is to be incremented only if the current frame is a
1097 * reference frame. After each successful frame encode, we increment
1098 * frame number by 1
1099 */
1100 if(!ps_codec->s_rate_control.post_encode_skip[ctxt_sel] && ps_codec->u4_is_curr_frm_ref &&
1101 (ps_proc->u1_spatial_layer_id == ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers - 1))
1102 {
1103 ps_codec->i4_frame_num++;
1104 }
1105
1106 /********************************************************************/
1107 /* signal the output */
1108 /********************************************************************/
1109 ps_codec->as_out_buf[ctxt_sel].as_bits_buf[ps_entropy->u1_spatial_layer_id].u4_bytes =
1110 ps_bitstrm->u4_strm_buf_offset;
1111
1112 ps_slice_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
1113 ps_slice_nalu_info->i8_num_bits += isvce_get_num_bits(ps_bitstrm);
1114 isvce_update_nalu_count(ps_nalu_descriptor);
1115
1116 DEBUG("entropy status %x", ps_entropy->i4_error_code);
1117 ps_entropy->i4_eof = 0;
1118 }
1119
1120 /* Dont execute any further instructions until store synchronization took
1121 * place */
1122 DATA_SYNC();
1123
1124 /* allow threads to dequeue entropy jobs */
1125 ps_codec->ae_entropy_thread_exit_state[ctxt_sel] = INACTIVE;
1126
1127 return ps_entropy->i4_error_code;
1128 }
1129
1130 /**
1131 *******************************************************************************
1132 *
1133 * @brief Packs header information of a mb in to a buffer
1134 *
1135 * @par Description:
1136 * After the deciding the mode info of a macroblock, the syntax elements
1137 * associated with the mb are packed and stored. The entropy thread unpacks
1138 * this buffer and generates the end bit stream.
1139 *
1140 * @param[in] ps_proc
1141 * Pointer to the current process context
1142 *
1143 * @returns error status
1144 *
1145 * @remarks none
1146 *
1147 *******************************************************************************
1148 */
isvce_pack_header_data(isvce_process_ctxt_t * ps_proc)1149 IH264E_ERROR_T isvce_pack_header_data(isvce_process_ctxt_t *ps_proc)
1150 {
1151 /* curr mb type */
1152 UWORD32 u4_mb_type = ps_proc->ps_mb_info->u2_mb_type;
1153
1154 /* pack mb syntax layer of curr mb (used for entropy coding) */
1155 if(u4_mb_type == I4x4)
1156 {
1157 /* pointer to mb header storage space */
1158 UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
1159 isvce_mb_hdr_i4x4_t *ps_mb_hdr = (isvce_mb_hdr_i4x4_t *) ps_proc->pv_mb_header_data;
1160
1161 /* temp var */
1162 WORD32 i4, byte;
1163
1164 /* mb type plus mode */
1165 ps_mb_hdr->common.u1_mb_type_mode = (ps_proc->u1_c_i8_mode << 6) + u4_mb_type;
1166
1167 /* cbp */
1168 ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
1169
1170 /* mb qp delta */
1171 ps_mb_hdr->common.u1_mb_qp = ps_proc->u1_mb_qp;
1172
1173 ps_mb_hdr->common.u1_residual_prediction_flag =
1174 ps_proc->ps_mb_info->u1_residual_prediction_flag;
1175
1176 ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
1177
1178 /* sub mb modes */
1179 for(i4 = 0; i4 < 16; i4++)
1180 {
1181 byte = 0;
1182
1183 if(ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i4] ==
1184 ps_proc->au1_intra_luma_mb_4x4_modes[i4])
1185 {
1186 byte |= 1;
1187 }
1188 else
1189 {
1190 if(ps_proc->au1_intra_luma_mb_4x4_modes[i4] <
1191 ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i4])
1192 {
1193 byte |= (ps_proc->au1_intra_luma_mb_4x4_modes[i4] << 1);
1194 }
1195 else
1196 {
1197 byte |= (ps_proc->au1_intra_luma_mb_4x4_modes[i4] - 1) << 1;
1198 }
1199 }
1200
1201 i4++;
1202
1203 if(ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i4] ==
1204 ps_proc->au1_intra_luma_mb_4x4_modes[i4])
1205 {
1206 byte |= 16;
1207 }
1208 else
1209 {
1210 if(ps_proc->au1_intra_luma_mb_4x4_modes[i4] <
1211 ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i4])
1212 {
1213 byte |= (ps_proc->au1_intra_luma_mb_4x4_modes[i4] << 5);
1214 }
1215 else
1216 {
1217 byte |= (ps_proc->au1_intra_luma_mb_4x4_modes[i4] - 1) << 5;
1218 }
1219 }
1220
1221 ps_mb_hdr->au1_sub_blk_modes[i4 >> 1] = byte;
1222 }
1223
1224 /* end of mb layer */
1225 pu1_ptr += sizeof(isvce_mb_hdr_i4x4_t);
1226 ps_proc->pv_mb_header_data = pu1_ptr;
1227 }
1228 else if(u4_mb_type == I16x16)
1229 {
1230 /* pointer to mb header storage space */
1231 UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
1232 isvce_mb_hdr_i16x16_t *ps_mb_hdr = (isvce_mb_hdr_i16x16_t *) ps_proc->pv_mb_header_data;
1233
1234 /* mb type plus mode */
1235 ps_mb_hdr->common.u1_mb_type_mode =
1236 (ps_proc->u1_c_i8_mode << 6) + (ps_proc->u1_l_i16_mode << 4) + u4_mb_type;
1237
1238 /* cbp */
1239 ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
1240
1241 /* mb qp delta */
1242 ps_mb_hdr->common.u1_mb_qp = ps_proc->u1_mb_qp;
1243
1244 ps_mb_hdr->common.u1_residual_prediction_flag =
1245 ps_proc->ps_mb_info->u1_residual_prediction_flag;
1246
1247 ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
1248
1249 /* end of mb layer */
1250 pu1_ptr += sizeof(isvce_mb_hdr_i16x16_t);
1251 ps_proc->pv_mb_header_data = pu1_ptr;
1252 }
1253 else if(u4_mb_type == P16x16)
1254 {
1255 /* pointer to mb header storage space */
1256 UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
1257 isvce_mb_hdr_p16x16_t *ps_mb_hdr = (isvce_mb_hdr_p16x16_t *) ps_proc->pv_mb_header_data;
1258
1259 /* mb type */
1260 ps_mb_hdr->common.u1_mb_type_mode = u4_mb_type;
1261
1262 /* cbp */
1263 ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
1264
1265 /* mb qp delta */
1266 ps_mb_hdr->common.u1_mb_qp = ps_proc->u1_mb_qp;
1267
1268 ps_mb_hdr->common.u1_residual_prediction_flag =
1269 ps_proc->ps_mb_info->u1_residual_prediction_flag;
1270
1271 ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
1272
1273 ps_mb_hdr->u1_mvp_idx = ps_proc->ps_mb_info->as_pu->au1_mvp_idx[L0];
1274
1275 if(0 == ps_proc->ps_mb_info->as_pu->au1_mvp_idx[L0])
1276 {
1277 ps_mb_hdr->ai2_mvd[0] = ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvx -
1278 ps_proc->ps_pred_mv[L0].s_mv.i2_mvx;
1279 ps_mb_hdr->ai2_mvd[1] = ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvy -
1280 ps_proc->ps_pred_mv[L0].s_mv.i2_mvy;
1281 }
1282 else
1283 {
1284 ps_mb_hdr->ai2_mvd[0] = ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvx -
1285 ps_proc->ps_ilp_mv->as_mv[0][L0].s_mv.i2_mvx;
1286 ps_mb_hdr->ai2_mvd[1] = ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvy -
1287 ps_proc->ps_ilp_mv->as_mv[0][L0].s_mv.i2_mvy;
1288 }
1289
1290 /* end of mb layer */
1291 pu1_ptr += sizeof(isvce_mb_hdr_p16x16_t);
1292 ps_proc->pv_mb_header_data = pu1_ptr;
1293 }
1294 else if(u4_mb_type == PSKIP)
1295 {
1296 /* pointer to mb header storage space */
1297 UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
1298 isvce_mb_hdr_pskip_t *ps_mb_hdr = (isvce_mb_hdr_pskip_t *) ps_proc->pv_mb_header_data;
1299
1300 /* mb type */
1301 ps_mb_hdr->common.u1_mb_type_mode = u4_mb_type;
1302
1303 ps_mb_hdr->common.u1_residual_prediction_flag =
1304 ps_proc->ps_mb_info->u1_residual_prediction_flag;
1305
1306 ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
1307
1308 /* end of mb layer */
1309 pu1_ptr += sizeof(isvce_mb_hdr_pskip_t);
1310 ps_proc->pv_mb_header_data = pu1_ptr;
1311 }
1312 else if(u4_mb_type == B16x16)
1313 {
1314 WORD32 i;
1315
1316 /* pointer to mb header storage space */
1317 UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
1318 isvce_mb_hdr_b16x16_t *ps_mb_hdr = (isvce_mb_hdr_b16x16_t *) ps_proc->pv_mb_header_data;
1319
1320 UWORD32 u4_pred_mode = ps_proc->ps_mb_info->as_pu->u1_pred_mode;
1321
1322 /* mb type plus mode */
1323 ps_mb_hdr->common.u1_mb_type_mode = (u4_pred_mode << 4) + u4_mb_type;
1324
1325 /* cbp */
1326 ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
1327
1328 /* mb qp delta */
1329 ps_mb_hdr->common.u1_mb_qp = ps_proc->u1_mb_qp;
1330
1331 ps_mb_hdr->common.u1_residual_prediction_flag =
1332 ps_proc->ps_mb_info->u1_residual_prediction_flag;
1333
1334 ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
1335
1336 for(i = 0; i < NUM_PRED_DIRS; i++)
1337 {
1338 PRED_MODE_T e_pred_mode = (PRED_MODE_T) i;
1339 PRED_MODE_T e_cmpl_pred_mode = (e_pred_mode == L0) ? L1 : L0;
1340
1341 if(u4_pred_mode != e_pred_mode)
1342 {
1343 ps_mb_hdr->au1_mvp_idx[e_cmpl_pred_mode] =
1344 ps_proc->ps_mb_info->as_pu->au1_mvp_idx[e_cmpl_pred_mode];
1345
1346 if(0 == ps_proc->ps_mb_info->as_pu->au1_mvp_idx[e_cmpl_pred_mode])
1347 {
1348 ps_mb_hdr->ai2_mvd[e_cmpl_pred_mode][0] =
1349 ps_proc->ps_mb_info->as_pu->as_me_info[e_cmpl_pred_mode].s_mv.i2_mvx -
1350 ps_proc->ps_pred_mv[e_cmpl_pred_mode].s_mv.i2_mvx;
1351 ps_mb_hdr->ai2_mvd[e_cmpl_pred_mode][1] =
1352 ps_proc->ps_mb_info->as_pu->as_me_info[e_cmpl_pred_mode].s_mv.i2_mvy -
1353 ps_proc->ps_pred_mv[e_cmpl_pred_mode].s_mv.i2_mvy;
1354 }
1355 else
1356 {
1357 ps_mb_hdr->ai2_mvd[e_cmpl_pred_mode][0] =
1358 ps_proc->ps_mb_info->as_pu->as_me_info[e_cmpl_pred_mode].s_mv.i2_mvx -
1359 ps_proc->ps_ilp_mv->as_mv[0][e_cmpl_pred_mode].s_mv.i2_mvx;
1360 ps_mb_hdr->ai2_mvd[e_cmpl_pred_mode][1] =
1361 ps_proc->ps_mb_info->as_pu->as_me_info[e_cmpl_pred_mode].s_mv.i2_mvy -
1362 ps_proc->ps_ilp_mv->as_mv[0][e_cmpl_pred_mode].s_mv.i2_mvy;
1363 }
1364 }
1365 }
1366
1367 /* end of mb layer */
1368 pu1_ptr += sizeof(isvce_mb_hdr_b16x16_t);
1369 ps_proc->pv_mb_header_data = pu1_ptr;
1370 }
1371 else if(u4_mb_type == BDIRECT)
1372 {
1373 /* pointer to mb header storage space */
1374 UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
1375 isvce_mb_hdr_bdirect_t *ps_mb_hdr = (isvce_mb_hdr_bdirect_t *) ps_proc->pv_mb_header_data;
1376
1377 /* mb type plus mode */
1378 ps_mb_hdr->common.u1_mb_type_mode = u4_mb_type;
1379
1380 /* cbp */
1381 ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
1382
1383 /* mb qp delta */
1384 ps_mb_hdr->common.u1_mb_qp = ps_proc->u1_mb_qp;
1385
1386 ps_mb_hdr->common.u1_residual_prediction_flag =
1387 ps_proc->ps_mb_info->u1_residual_prediction_flag;
1388
1389 ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
1390
1391 /* end of mb layer */
1392 pu1_ptr += sizeof(isvce_mb_hdr_bdirect_t);
1393 ps_proc->pv_mb_header_data = pu1_ptr;
1394 }
1395 else if(u4_mb_type == BSKIP)
1396 {
1397 UWORD32 u4_pred_mode = ps_proc->ps_mb_info->as_pu->u1_pred_mode;
1398
1399 /* pointer to mb header storage space */
1400 UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
1401 isvce_mb_hdr_bskip_t *ps_mb_hdr = (isvce_mb_hdr_bskip_t *) ps_proc->pv_mb_header_data;
1402
1403 /* mb type plus mode */
1404 ps_mb_hdr->common.u1_mb_type_mode = (u4_pred_mode << 4) + u4_mb_type;
1405
1406 ps_mb_hdr->common.u1_residual_prediction_flag =
1407 ps_proc->ps_mb_info->u1_residual_prediction_flag;
1408
1409 ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
1410
1411 /* end of mb layer */
1412 pu1_ptr += sizeof(isvce_mb_hdr_bskip_t);
1413 ps_proc->pv_mb_header_data = pu1_ptr;
1414 }
1415 else if(u4_mb_type == BASE_MODE)
1416 {
1417 isvce_mb_hdr_base_mode_t *ps_mb_hdr =
1418 (isvce_mb_hdr_base_mode_t *) ps_proc->pv_mb_header_data;
1419
1420 UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
1421
1422 ASSERT(ps_proc->ps_mb_info->u1_base_mode_flag == 1);
1423
1424 ps_mb_hdr->common.u1_mb_type_mode = u4_mb_type;
1425
1426 ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
1427
1428 ps_mb_hdr->common.u1_mb_qp = ps_proc->u1_mb_qp;
1429
1430 ps_mb_hdr->common.u1_residual_prediction_flag =
1431 ps_proc->ps_mb_info->u1_residual_prediction_flag;
1432
1433 ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
1434
1435 pu1_ptr += sizeof(isvce_mb_hdr_base_mode_t);
1436 ps_proc->pv_mb_header_data = pu1_ptr;
1437 }
1438
1439 return IH264E_SUCCESS;
1440 }
1441
1442 /**
1443 *******************************************************************************
1444 *
1445 * @brief update process context after encoding an mb. This involves preserving
1446 * the current mb information for later use, initialize the proc ctxt elements to
1447 * encode next mb.
1448 *
1449 * @par Description:
1450 * This function performs house keeping tasks after encoding an mb.
1451 * After encoding an mb, various elements of the process context needs to be
1452 * updated to encode the next mb. For instance, the source, recon and reference
1453 * pointers, mb indices have to be adjusted to the next mb. The slice index of
1454 * the current mb needs to be updated. If mb qp modulation is enabled, then if
1455 * the qp changes the quant param structure needs to be updated. Also to
1456 *encoding the next mb, the current mb info is used as part of mode prediction or
1457 *mv prediction. Hence the current mb info has to preserved at top/top left/left
1458 * locations.
1459 *
1460 * @param[in] ps_proc
1461 * Pointer to the current process context
1462 *
1463 * @returns none
1464 *
1465 * @remarks none
1466 *
1467 *******************************************************************************
1468 */
isvce_update_proc_ctxt(isvce_process_ctxt_t * ps_proc)1469 WORD32 isvce_update_proc_ctxt(isvce_process_ctxt_t *ps_proc)
1470 {
1471 /* error status */
1472 WORD32 error_status = IH264_SUCCESS;
1473
1474 /* codec context */
1475 isvce_codec_t *ps_codec = ps_proc->ps_codec;
1476 isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
1477 mem_fxns_t *ps_mem_fxns = &ps_isa_dependent_fxns->s_mem_fxns;
1478
1479 /* curr mb indices */
1480 WORD32 i4_mb_x = ps_proc->i4_mb_x;
1481 WORD32 i4_mb_y = ps_proc->i4_mb_y;
1482
1483 /* mb syntax elements of neighbors */
1484 isvce_mb_info_t *ps_left_syn = ps_proc->s_nbr_info.ps_left_mb_info;
1485 isvce_mb_info_t *ps_top_syn =
1486 ps_proc->s_nbr_info_base.ps_layer_nbr_info[ps_proc->u1_spatial_layer_id]
1487 .ps_top_row_mb_info +
1488 i4_mb_x + i4_mb_y * ps_proc->i4_wd_mbs;
1489
1490 /* curr mb type */
1491 UWORD32 u4_mb_type = ps_proc->ps_mb_info->u2_mb_type;
1492
1493 /* curr mb type */
1494 UWORD32 u4_is_intra = ps_proc->ps_mb_info->u1_is_intra;
1495
1496 /* width in mbs */
1497 WORD32 i4_wd_mbs = ps_proc->i4_wd_mbs;
1498
1499 /*height in mbs*/
1500 WORD32 i4_ht_mbs = ps_proc->i4_ht_mbs;
1501
1502 /* proc map */
1503 UWORD8 *pu1_proc_map = ps_proc->pu1_proc_map + (i4_mb_y * i4_wd_mbs);
1504
1505 /* deblk context */
1506 isvce_deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
1507
1508 /* deblk bs context */
1509 isvce_bs_ctxt_t *ps_bs = &(ps_deblk->s_bs_ctxt);
1510
1511 /* sub mb modes */
1512 UWORD8 *pu1_top_mb_intra_modes =
1513 (ps_proc->s_nbr_info_base.ps_layer_nbr_info[ps_proc->u1_spatial_layer_id]
1514 .ps_top_mb_intra_modes +
1515 i4_mb_x + i4_mb_y * ps_proc->i4_wd_mbs)
1516 ->au1_intra_modes;
1517
1518 /*************************************************************/
1519 /* During MV prediction, when top right mb is not available, */
1520 /* top left mb info. is used for prediction. Hence the curr */
1521 /* top, which will be top left for the next mb needs to be */
1522 /* preserved before updating it with curr mb info. */
1523 /*************************************************************/
1524
1525 /*************************************************/
1526 /* update top and left with curr mb info results */
1527 /*************************************************/
1528 ps_left_syn[0] = ps_top_syn[0] = ps_proc->ps_mb_info[0];
1529 ps_left_syn->u2_mb_type = ps_top_syn->u2_mb_type = u4_mb_type;
1530 ps_left_syn->i4_mb_distortion = ps_top_syn->i4_mb_distortion = ps_proc->i4_mb_distortion;
1531
1532 if(u4_is_intra)
1533 {
1534 /* mb / sub mb modes */
1535 if(I16x16 == u4_mb_type)
1536 {
1537 pu1_top_mb_intra_modes[0] =
1538 ps_proc->s_nbr_info.ps_left_mb_intra_modes->au1_intra_modes[0] =
1539 ps_proc->u1_l_i16_mode;
1540 }
1541 else if(I4x4 == u4_mb_type)
1542 {
1543 ps_mem_fxns->pf_mem_cpy_mul8(
1544 ps_proc->s_nbr_info.ps_left_mb_intra_modes->au1_intra_modes,
1545 ps_proc->au1_intra_luma_mb_4x4_modes, 16);
1546 ps_mem_fxns->pf_mem_cpy_mul8(pu1_top_mb_intra_modes,
1547 ps_proc->au1_intra_luma_mb_4x4_modes, 16);
1548 }
1549 else if(I8x8 == u4_mb_type)
1550 {
1551 memcpy(ps_proc->s_nbr_info.ps_left_mb_intra_modes->au1_intra_modes,
1552 ps_proc->au1_intra_luma_mb_8x8_modes, 4);
1553 memcpy(pu1_top_mb_intra_modes, ps_proc->au1_intra_luma_mb_8x8_modes, 4);
1554 }
1555
1556 *ps_proc->pu4_mb_pu_cnt = 1;
1557 }
1558
1559 /*
1560 * Mark that the MB has been coded intra
1561 * So that future AIRs can skip it
1562 */
1563 ps_proc->pu1_is_intra_coded[i4_mb_x + (i4_mb_y * i4_wd_mbs)] = u4_is_intra;
1564
1565 /**************************************************/
1566 /* pack mb header info. for entropy coding */
1567 /**************************************************/
1568 isvce_pack_header_data(ps_proc);
1569
1570 /*
1571 * We need to sync the cache to make sure that the nmv content of proc
1572 * is updated to cache properly
1573 */
1574 DATA_SYNC();
1575
1576 /* Just before finishing the row, enqueue the job in to entropy queue.
1577 * The master thread depending on its convenience shall dequeue it and
1578 * performs entropy.
1579 *
1580 * WARN !! Placing this block post proc map update can cause queuing of
1581 * entropy jobs in out of order.
1582 */
1583 if(i4_mb_x == i4_wd_mbs - 1)
1584 {
1585 /* job structures */
1586 job_t s_job;
1587
1588 /* job class */
1589 s_job.i4_cmd = CMD_ENTROPY;
1590
1591 /* number of mbs to be processed in the current job */
1592 s_job.i2_mb_cnt = ps_proc->i4_wd_mbs;
1593
1594 /* job start index x */
1595 s_job.i2_mb_x = 0;
1596
1597 /* job start index y */
1598 s_job.i2_mb_y = ps_proc->i4_mb_y;
1599
1600 /* queue the job */
1601 error_status = ih264_list_queue(ps_proc->pv_entropy_jobq, &s_job, 1);
1602
1603 if(error_status != IH264_SUCCESS)
1604 {
1605 return error_status;
1606 }
1607
1608 if(ps_proc->i4_mb_y == (i4_ht_mbs - 1))
1609 {
1610 ih264_list_terminate(ps_codec->pv_entropy_jobq);
1611 }
1612 }
1613
1614 /* update proc map */
1615 pu1_proc_map[i4_mb_x] = 1;
1616 ASSERT(i4_mb_x < i4_wd_mbs);
1617
1618 /**************************************************/
1619 /* update proc ctxt elements for encoding next mb */
1620 /**************************************************/
1621 /* update indices */
1622 i4_mb_x++;
1623 ps_proc->i4_mb_x = i4_mb_x;
1624
1625 if(ps_proc->i4_mb_x == i4_wd_mbs)
1626 {
1627 ps_proc->i4_mb_y++;
1628 ps_proc->i4_mb_x = 0;
1629 }
1630
1631 /* update slice index */
1632 ps_proc->i4_cur_slice_idx =
1633 ps_proc->pu1_slice_idx[ps_proc->i4_mb_y * i4_wd_mbs + ps_proc->i4_mb_x];
1634
1635 /* update buffers pointers */
1636 ps_proc->s_src_buf_props.as_component_bufs[0].pv_data =
1637 ((UWORD8 *) ps_proc->s_src_buf_props.as_component_bufs[0].pv_data) + MB_SIZE;
1638 ps_proc->s_rec_buf_props.as_component_bufs[0].pv_data =
1639 ((UWORD8 *) ps_proc->s_rec_buf_props.as_component_bufs[0].pv_data) + MB_SIZE;
1640 ps_proc->as_ref_buf_props[0].as_component_bufs[0].pv_data =
1641 ((UWORD8 *) ps_proc->as_ref_buf_props[0].as_component_bufs[0].pv_data) + MB_SIZE;
1642 ps_proc->as_ref_buf_props[1].as_component_bufs[0].pv_data =
1643 ((UWORD8 *) ps_proc->as_ref_buf_props[1].as_component_bufs[0].pv_data) + MB_SIZE;
1644
1645 /*
1646 * Note: Although chroma mb size is 8, as the chroma buffers are
1647 * interleaved, the stride per MB is MB_SIZE
1648 */
1649 ps_proc->s_src_buf_props.as_component_bufs[1].pv_data =
1650 ((UWORD8 *) ps_proc->s_src_buf_props.as_component_bufs[1].pv_data) + MB_SIZE;
1651 ps_proc->s_rec_buf_props.as_component_bufs[1].pv_data =
1652 ((UWORD8 *) ps_proc->s_rec_buf_props.as_component_bufs[1].pv_data) + MB_SIZE;
1653 ps_proc->as_ref_buf_props[0].as_component_bufs[1].pv_data =
1654 ((UWORD8 *) ps_proc->as_ref_buf_props[0].as_component_bufs[1].pv_data) + MB_SIZE;
1655 ps_proc->as_ref_buf_props[1].as_component_bufs[1].pv_data =
1656 ((UWORD8 *) ps_proc->as_ref_buf_props[1].as_component_bufs[1].pv_data) + MB_SIZE;
1657
1658 /* Reset cost, distortion params */
1659 ps_proc->i4_mb_cost = INT_MAX;
1660 ps_proc->i4_mb_distortion = SHRT_MAX;
1661
1662 ps_proc->ps_mb_info++;
1663 ps_proc->pu4_mb_pu_cnt++;
1664
1665 /* Update colocated pu */
1666 if(ps_proc->i4_slice_type == BSLICE)
1667 {
1668 ps_proc->ps_col_mb++;
1669 }
1670
1671 if(ps_proc->u4_disable_deblock_level != 1)
1672 {
1673 ps_bs->i4_mb_x = ps_proc->i4_mb_x;
1674 ps_bs->i4_mb_y = ps_proc->i4_mb_y;
1675
1676 #ifndef N_MB_ENABLE /* For N MB processing update take place inside deblocking \
1677 function */
1678 ASSERT(0);
1679 ps_deblk->i4_mb_x++;
1680
1681 ((UWORD8 *) ps_deblk->s_rec_pic_buf_props.as_component_bufs[0].pv_data) += MB_SIZE;
1682 /*
1683 * Note: Although chroma mb size is 8, as the chroma buffers are
1684 * interleaved, the stride per MB is MB_SIZE
1685 */
1686 ((UWORD8 *) ps_deblk->s_rec_pic_buf_props.as_component_bufs[1].pv_data) += MB_SIZE;
1687 #endif
1688 }
1689
1690 return error_status;
1691 }
1692
1693 /**
1694 *******************************************************************************
1695 *
1696 * @brief This function performs luma & chroma padding
1697 *
1698 * @par Description:
1699 *
1700 * @param[in] ps_proc
1701 * Process context corresponding to the job
1702 *
1703 * @param[in] pu1_curr_pic_luma
1704 * Pointer to luma buffer
1705 *
1706 * @param[in] pu1_curr_pic_chroma
1707 * Pointer to chroma buffer
1708 *
1709 * @param[in] i4_mb_x
1710 * mb index x
1711 *
1712 * @param[in] i4_mb_y
1713 * mb index y
1714 *
1715 * @param[in] i4_pad_ht
1716 * number of rows to be padded
1717 *
1718 * @returns error status
1719 *
1720 * @remarks none
1721 *
1722 *******************************************************************************
1723 */
isvce_pad_recon_buffer(isvce_process_ctxt_t * ps_proc,UWORD8 * pu1_curr_pic_luma,WORD32 i4_luma_stride,UWORD8 * pu1_curr_pic_chroma,WORD32 i4_chroma_stride,WORD32 i4_mb_x,WORD32 i4_mb_y,WORD32 i4_pad_ht)1724 IH264E_ERROR_T isvce_pad_recon_buffer(isvce_process_ctxt_t *ps_proc, UWORD8 *pu1_curr_pic_luma,
1725 WORD32 i4_luma_stride, UWORD8 *pu1_curr_pic_chroma,
1726 WORD32 i4_chroma_stride, WORD32 i4_mb_x, WORD32 i4_mb_y,
1727 WORD32 i4_pad_ht)
1728 {
1729 /* codec context */
1730 isvce_codec_t *ps_codec = ps_proc->ps_codec;
1731
1732 if(i4_mb_x == 0)
1733 {
1734 /* padding left luma */
1735 ps_codec->pf_pad_left_luma(pu1_curr_pic_luma, i4_luma_stride, i4_pad_ht, PAD_LEFT);
1736
1737 /* padding left chroma */
1738 ps_codec->pf_pad_left_chroma(pu1_curr_pic_chroma, i4_chroma_stride, i4_pad_ht >> 1,
1739 PAD_LEFT);
1740 }
1741 if(i4_mb_x == ps_proc->i4_wd_mbs - 1)
1742 {
1743 /* padding right luma */
1744 ps_codec->pf_pad_right_luma(pu1_curr_pic_luma + MB_SIZE, i4_luma_stride, i4_pad_ht,
1745 PAD_RIGHT);
1746
1747 /* padding right chroma */
1748 ps_codec->pf_pad_right_chroma(pu1_curr_pic_chroma + MB_SIZE, i4_chroma_stride,
1749 i4_pad_ht >> 1, PAD_RIGHT);
1750
1751 if(i4_mb_y == ps_proc->i4_ht_mbs - 1)
1752 {
1753 UWORD8 *pu1_rec_luma =
1754 pu1_curr_pic_luma + MB_SIZE + PAD_RIGHT + ((i4_pad_ht - 1) * i4_luma_stride);
1755 UWORD8 *pu1_rec_chroma = pu1_curr_pic_chroma + MB_SIZE + PAD_RIGHT +
1756 (((i4_pad_ht >> 1) - 1) * i4_chroma_stride);
1757
1758 /* padding bottom luma */
1759 ps_codec->pf_pad_bottom(pu1_rec_luma, i4_luma_stride, i4_luma_stride, PAD_BOT);
1760
1761 /* padding bottom chroma */
1762 ps_codec->pf_pad_bottom(pu1_rec_chroma, i4_chroma_stride, i4_chroma_stride,
1763 (PAD_BOT >> 1));
1764 }
1765 }
1766
1767 if(i4_mb_y == 0)
1768 {
1769 UWORD8 *pu1_rec_luma = pu1_curr_pic_luma;
1770 UWORD8 *pu1_rec_chroma = pu1_curr_pic_chroma;
1771 WORD32 wd = MB_SIZE;
1772
1773 if(i4_mb_x == 0)
1774 {
1775 pu1_rec_luma -= PAD_LEFT;
1776 pu1_rec_chroma -= PAD_LEFT;
1777
1778 wd += PAD_LEFT;
1779 }
1780 if(i4_mb_x == ps_proc->i4_wd_mbs - 1)
1781 {
1782 wd += PAD_RIGHT;
1783 }
1784
1785 /* padding top luma */
1786 ps_codec->pf_pad_top(pu1_rec_luma, i4_luma_stride, wd, PAD_TOP);
1787
1788 /* padding top chroma */
1789 ps_codec->pf_pad_top(pu1_rec_chroma, i4_chroma_stride, wd, (PAD_TOP >> 1));
1790 }
1791
1792 return IH264E_SUCCESS;
1793 }
1794
1795 /**
1796 *******************************************************************************
1797 *
1798 * @brief This function performs deblocking
1799 *
1800 * @par Description:
1801 *
1802 * @param[in] ps_proc
1803 * Process context corresponding to the job
1804 *
1805 * @returns error status
1806 *
1807 * @remarks none
1808 *
1809 *******************************************************************************
1810 */
isvce_dblk_n_mbs(isvce_process_ctxt_t * ps_proc,UWORD8 u1_inter_layer_deblk_flag)1811 static IH264E_ERROR_T isvce_dblk_n_mbs(isvce_process_ctxt_t *ps_proc,
1812 UWORD8 u1_inter_layer_deblk_flag)
1813 {
1814 WORD32 i;
1815 WORD32 row, col;
1816
1817 n_mb_process_ctxt_t *ps_n_mb_ctxt = &ps_proc->s_n_mb_ctxt;
1818 isvce_deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
1819
1820 UWORD8 *pu1_deblk_map = ps_proc->pu1_deblk_map + ps_deblk->i4_mb_y * ps_proc->i4_wd_mbs;
1821 UWORD8 *pu1_deblk_map_prev_row = pu1_deblk_map - ps_proc->i4_wd_mbs;
1822 WORD32 u4_deblk_prev_row = 0;
1823 WORD32 i4_n_mbs = ps_n_mb_ctxt->i4_n_mbs;
1824 WORD32 i4_n_mb_process_count = 0;
1825 WORD32 i4_mb_x = ps_proc->i4_mb_x;
1826 WORD32 i4_mb_y = ps_proc->i4_mb_y;
1827
1828 ASSERT(i4_n_mbs == ps_proc->i4_wd_mbs);
1829
1830 if(ps_proc->u4_disable_deblock_level != 1)
1831 {
1832 if((i4_mb_y > 0) || (i4_mb_y == (ps_proc->i4_ht_mbs - 1)))
1833 {
1834 /* if number of mb's to be processed are less than 'N', go back.
1835 * exception to the above clause is end of row */
1836 if(((i4_mb_x - (ps_n_mb_ctxt->i4_mb_x - 1)) < i4_n_mbs) &&
1837 (i4_mb_x < (ps_proc->i4_wd_mbs - 1)))
1838 {
1839 return IH264E_SUCCESS;
1840 }
1841 else
1842 {
1843 WORD32 i4_num_deblk_rows = 1;
1844
1845 if(i4_mb_y == (ps_proc->i4_ht_mbs - 1))
1846 {
1847 i4_num_deblk_rows += (ps_proc->i4_ht_mbs > 1);
1848 }
1849
1850 if(1 == ps_proc->i4_ht_mbs)
1851 {
1852 ps_deblk->i4_mb_y = 0;
1853 pu1_deblk_map_prev_row = pu1_deblk_map;
1854 }
1855
1856 for(i = 0; i < i4_num_deblk_rows; i++)
1857 {
1858 if(i == 1)
1859 {
1860 /* Deblock last row */
1861 ps_n_mb_ctxt->i4_mb_x = 0;
1862 ps_n_mb_ctxt->i4_mb_y = ps_proc->i4_mb_y;
1863 ps_deblk->i4_mb_x = 0;
1864 ps_deblk->i4_mb_y = ps_proc->i4_mb_y;
1865 pu1_deblk_map_prev_row = pu1_deblk_map;
1866 pu1_deblk_map += ps_proc->i4_wd_mbs;
1867 }
1868
1869 i4_n_mb_process_count = MIN(i4_mb_x - (ps_n_mb_ctxt->i4_mb_x - 1), i4_n_mbs);
1870
1871 /* performing deblocking for required number of MBs */
1872 u4_deblk_prev_row = 1;
1873
1874 /* checking whether the top rows are deblocked */
1875 for(col = 0; col < i4_n_mb_process_count; col++)
1876 {
1877 u4_deblk_prev_row &= pu1_deblk_map_prev_row[ps_deblk->i4_mb_x + col];
1878 }
1879
1880 /* checking whether the top right MB is deblocked */
1881 if((ps_deblk->i4_mb_x + i4_n_mb_process_count) != ps_proc->i4_wd_mbs)
1882 {
1883 u4_deblk_prev_row &=
1884 pu1_deblk_map_prev_row[ps_deblk->i4_mb_x + i4_n_mb_process_count];
1885 }
1886
1887 /* Top or Top right MBs not deblocked */
1888 if((u4_deblk_prev_row != 1) && (i4_mb_y > 0))
1889 {
1890 return IH264E_SUCCESS;
1891 }
1892
1893 for(row = 0; row < i4_n_mb_process_count; row++)
1894 {
1895 isvce_deblock_mb(ps_proc, ps_deblk, u1_inter_layer_deblk_flag);
1896
1897 pu1_deblk_map[ps_deblk->i4_mb_x] = 1;
1898
1899 ps_deblk->i4_mb_x++;
1900 }
1901 }
1902 }
1903 }
1904 }
1905
1906 return IH264E_SUCCESS;
1907 }
1908
1909 /**
1910 *******************************************************************************
1911 *
1912 * @brief This function performs 'intra base' deblocking
1913 *
1914 * @par Description:
1915 *
1916 * @param[in] ps_proc
1917 * Process context corresponding to the job
1918 *
1919 * @returns error status
1920 *
1921 * @remarks none
1922 *
1923 *******************************************************************************
1924 */
isvce_intra_base_dblk(isvce_process_ctxt_t * ps_proc)1925 static IH264E_ERROR_T isvce_intra_base_dblk(isvce_process_ctxt_t *ps_proc)
1926 {
1927 isvce_codec_t *ps_codec = ps_proc->ps_codec;
1928 isvce_deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
1929
1930 IH264E_ERROR_T e_ret = IH264E_SUCCESS;
1931
1932 if(ps_proc->u1_spatial_layer_id < (ps_proc->s_svc_params.u1_num_spatial_layers - 1))
1933 {
1934 ps_deblk->i4_mb_x = ps_proc->i4_mb_x;
1935 ps_deblk->i4_mb_y = ps_proc->i4_mb_y - 1;
1936
1937 ps_deblk->s_rec_pic_buf_props =
1938 ps_codec->s_svc_ilp_data.ps_intra_recon_bufs[ps_proc->u1_spatial_layer_id];
1939
1940 e_ret = isvce_dblk_n_mbs(ps_proc, 1);
1941
1942 ps_deblk->s_rec_pic_buf_props = ps_proc->s_rec_pic_buf_props;
1943 }
1944
1945 return e_ret;
1946 }
1947
1948 /**
1949 *******************************************************************************
1950 *
1951 * @brief This function performs luma & chroma core coding for a set of mb's.
1952 *
1953 * @par Description:
1954 * The mb to be coded is taken and is evaluated over a predefined set of modes
1955 * (intra (i16, i4, i8)/inter (mv, skip)) for best cost. The mode with least
1956 *cost is selected and using intra/inter prediction filters, prediction is
1957 *carried out. The deviation between src and pred signal constitutes error
1958 *signal. This error signal is transformed (hierarchical transform if necessary)
1959 *and quantized. The quantized residue is packed in to entropy buffer for entropy
1960 *coding. This is repeated for all the mb's enlisted under the job.
1961 *
1962 * @param[in] ps_proc
1963 * Process context corresponding to the job
1964 *
1965 * @returns error status
1966 *
1967 * @remarks none
1968 *
1969 *******************************************************************************
1970 */
isvce_process(isvce_process_ctxt_t * ps_proc)1971 WORD32 isvce_process(isvce_process_ctxt_t *ps_proc)
1972 {
1973 UWORD32 u4_cbp_l, u4_cbp_c;
1974 WORD32 i4_mb_idx;
1975 WORD32 luma_idx, chroma_idx, is_intra;
1976
1977 isvce_codec_t *ps_codec = ps_proc->ps_codec;
1978 isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
1979 enc_loop_fxns_t *ps_enc_loop_fxns = &ps_isa_dependent_fxns->s_enc_loop_fxns;
1980
1981 WORD32 error_status = IH264_SUCCESS;
1982 WORD32 i4_wd_mbs = ps_proc->i4_wd_mbs;
1983 WORD32 i4_mb_cnt = ps_proc->i4_mb_cnt;
1984 UWORD32 u4_valid_modes = 0;
1985 WORD32 i4_gate_threshold = 0;
1986 WORD32 ctxt_sel = ps_proc->i4_encode_api_call_cnt % MAX_CTXT_SETS;
1987 bool b_enable_intra4x4_eval = true;
1988
1989 /*
1990 * list of modes for evaluation
1991 * -------------------------------------------------------------------------
1992 * Note on enabling I4x4 and I16x16
1993 * At very low QP's the hadamard transform in I16x16 will push up the maximum
1994 * coeff value very high. CAVLC may not be able to represent the value and
1995 * hence the stream may not be decodable in some clips.
1996 * Hence at low QPs, we will enable I4x4 and disable I16x16 irrespective of
1997 * preset.
1998 */
1999 if(ps_proc->i4_slice_type == ISLICE)
2000 {
2001 u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_16x16 ? (1 << I16x16) : 0;
2002
2003 /* enable intra 8x8 */
2004 u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_8x8 ? (1 << I8x8) : 0;
2005
2006 /* enable intra 4x4 */
2007 u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_4x4 ? (1 << I4x4) : 0;
2008 u4_valid_modes |= (ps_proc->u1_frame_qp <= 10) << I4x4;
2009 }
2010 else if(ps_proc->i4_slice_type == PSLICE)
2011 {
2012 u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_16x16 ? (1 << I16x16) : 0;
2013
2014 /* enable intra 4x4 */
2015 if(ps_codec->s_cfg.u4_enc_speed_preset == IVE_SLOWEST)
2016 {
2017 u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_4x4 ? (1 << I4x4) : 0;
2018 }
2019 u4_valid_modes |= (ps_proc->u1_frame_qp <= 10) << I4x4;
2020
2021 /* enable inter P16x16 */
2022 u4_valid_modes |= (1 << P16x16);
2023 }
2024 else if(ps_proc->i4_slice_type == BSLICE)
2025 {
2026 u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_16x16 ? (1 << I16x16) : 0;
2027
2028 /* enable intra 4x4 */
2029 if(ps_codec->s_cfg.u4_enc_speed_preset == IVE_SLOWEST)
2030 {
2031 u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_4x4 ? (1 << I4x4) : 0;
2032 }
2033 u4_valid_modes |= (ps_proc->u1_frame_qp <= 10) << I4x4;
2034
2035 /* enable inter B16x16 */
2036 u4_valid_modes |= (1 << B16x16);
2037 }
2038
2039 ps_proc->s_entropy.i4_mb_x = ps_proc->i4_mb_x;
2040 ps_proc->s_entropy.i4_mb_y = ps_proc->i4_mb_y;
2041 ps_proc->s_entropy.i4_mb_cnt = MIN(ps_proc->i4_nmb_ntrpy, i4_wd_mbs - ps_proc->i4_mb_x);
2042
2043 /* compute recon when :
2044 * 1. current frame is to be used as a reference
2045 * 2. dump recon for bit stream sanity check
2046 */
2047 ps_proc->u4_compute_recon = ((ps_proc->s_svc_params.u1_num_spatial_layers > 1) &&
2048 (ENABLE_RESIDUAL_PREDICTION || ENABLE_IBL_MODE)) ||
2049 ps_codec->u4_is_curr_frm_ref || ps_codec->s_cfg.u4_enable_recon;
2050
2051 for(i4_mb_idx = 0; i4_mb_idx < i4_mb_cnt; i4_mb_idx++)
2052 {
2053 /* since we have not yet found sad, we have not yet got min sad */
2054 /* we need to initialize these variables for each MB */
2055 /* TODO how to get the min sad into the codec */
2056 ps_proc->u4_min_sad = ps_codec->s_cfg.i4_min_sad;
2057 ps_proc->u4_min_sad_reached = 0;
2058
2059 ps_proc->ps_mb_info->u1_mb_qp = ps_proc->u1_mb_qp;
2060
2061 /* wait until the proc of [top + 1] mb is computed.
2062 * We wait till the proc dependencies are satisfied */
2063 if(ps_proc->i4_mb_y > 0)
2064 {
2065 UWORD8 *pu1_proc_map_top;
2066
2067 pu1_proc_map_top = ps_proc->pu1_proc_map + ((ps_proc->i4_mb_y - 1) * i4_wd_mbs);
2068
2069 while(1)
2070 {
2071 volatile UWORD8 *pu1_buf;
2072 WORD32 idx = MIN(i4_mb_cnt - 1, i4_mb_idx + 1);
2073
2074 idx = MIN(idx, ((WORD32) ps_codec->s_cfg.i4_wd_mbs - 1));
2075 pu1_buf = pu1_proc_map_top + idx;
2076 if(*pu1_buf) break;
2077 ithread_yield();
2078 }
2079 }
2080
2081 if(ENABLE_ILP_MV && (ps_proc->u1_spatial_layer_id > 0) &&
2082 (ps_proc->i4_slice_type != ISLICE))
2083 {
2084 svc_ilp_mv_ctxt_t *ps_svc_ilp_mv_ctxt = ps_proc->ps_svc_ilp_mv_ctxt;
2085 coordinates_t s_mb_pos = {ps_proc->i4_mb_x, ps_proc->i4_mb_y};
2086
2087 ps_svc_ilp_mv_ctxt->s_ilp_mv_variables.ps_svc_ilp_data = &ps_codec->s_svc_ilp_data;
2088 ps_svc_ilp_mv_ctxt->s_ilp_mv_variables.s_mb_pos = s_mb_pos;
2089 ps_svc_ilp_mv_ctxt->s_ilp_mv_variables.u1_spatial_layer_id =
2090 ps_proc->u1_spatial_layer_id;
2091
2092 isvce_get_mb_ilp_mv(ps_svc_ilp_mv_ctxt);
2093
2094 ps_proc->ps_ilp_mv = &ps_svc_ilp_mv_ctxt->s_ilp_mv_outputs.s_ilp_mv;
2095 ps_proc->s_me_ctxt.ps_ilp_me_cands =
2096 &ps_svc_ilp_mv_ctxt->s_ilp_mv_outputs.s_ilp_me_cands;
2097 }
2098 else
2099 {
2100 ps_proc->ps_ilp_mv = NULL;
2101 ps_proc->s_me_ctxt.ps_ilp_me_cands = NULL;
2102 }
2103
2104 ps_proc->ps_mb_info->u2_mb_type = INVALID_MB_TYPE;
2105 ps_proc->i4_mb_distortion = SHRT_MAX;
2106
2107 {
2108 WORD32 i4_mb_id = ps_proc->i4_mb_x + ps_proc->i4_mb_y * i4_wd_mbs;
2109
2110 WORD32 i4_air_enable_inter =
2111 (ps_codec->s_cfg.e_air_mode == IVE_AIR_MODE_NONE) ||
2112 (ps_codec->pu2_intr_rfrsh_map[i4_mb_id] != ps_codec->i4_air_pic_cnt);
2113
2114 if((u4_valid_modes & (1 << P16x16)) || (u4_valid_modes & (1 << B16x16)))
2115 {
2116 if(ps_proc->i4_mb_x % ps_proc->u4_nmb_me == 0)
2117 {
2118 isvce_compute_me_nmb(
2119 ps_proc, MIN((WORD32) ps_proc->u4_nmb_me, i4_wd_mbs - ps_proc->i4_mb_x));
2120 }
2121
2122 {
2123 UWORD32 u4_mb_index = ps_proc->i4_mb_x % ps_proc->u4_nmb_me;
2124
2125 ps_proc->u4_min_sad_reached =
2126 ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad_reached;
2127 ps_proc->u4_min_sad = ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad;
2128
2129 ps_proc->ps_skip_mv = &(ps_proc->ps_nmb_info[u4_mb_index].as_skip_mv[0]);
2130 ps_proc->ps_ngbr_avbl = &(ps_proc->ps_nmb_info[u4_mb_index].s_ngbr_avbl);
2131 ps_proc->ps_pred_mv = &(ps_proc->ps_nmb_info[u4_mb_index].as_pred_mv[0]);
2132
2133 ps_proc->i4_mb_distortion = ps_proc->ps_nmb_info[u4_mb_index].i4_mb_distortion;
2134
2135 ps_proc->i4_mb_cost = ps_proc->ps_nmb_info[u4_mb_index].i4_mb_cost;
2136 ps_proc->u4_min_sad = ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad;
2137 ps_proc->u4_min_sad_reached =
2138 ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad_reached;
2139 ps_proc->ps_mb_info->u2_mb_type = ps_proc->ps_nmb_info[u4_mb_index].u4_mb_type;
2140
2141 ps_proc->pu1_best_subpel_buf =
2142 ps_proc->ps_nmb_info[u4_mb_index].pu1_best_sub_pel_buf;
2143 ps_proc->u4_bst_spel_buf_strd =
2144 ps_proc->ps_nmb_info[u4_mb_index].u4_bst_spel_buf_strd;
2145 }
2146
2147 isvce_derive_nghbr_avbl_of_mbs(ps_proc);
2148 }
2149 else
2150 {
2151 ps_proc->ps_ngbr_avbl = &ps_proc->s_ngbr_avbl;
2152
2153 isvce_derive_nghbr_avbl_of_mbs(ps_proc);
2154 }
2155
2156 /*
2157 * If air says intra, we need to force the following code path to evaluate
2158 * intra The easy way is just to say that the inter cost is too much
2159 */
2160 if(!i4_air_enable_inter)
2161 {
2162 ps_proc->u4_min_sad_reached = 0;
2163 ps_proc->i4_mb_cost = INT_MAX;
2164 ps_proc->i4_mb_distortion = INT_MAX;
2165 }
2166 else if(ps_proc->ps_mb_info->u2_mb_type == PSKIP)
2167 {
2168 ps_proc->ps_mb_info->u1_base_mode_flag = 0;
2169 ps_proc->ps_mb_info->u1_residual_prediction_flag = 0;
2170 goto UPDATE_MB_INFO;
2171 }
2172
2173 /* If we already have the minimum sad, there is no point in searching for
2174 * sad again */
2175 if((ps_proc->u4_min_sad_reached == 0) ||
2176 (ps_codec->s_cfg.u4_enc_speed_preset != IVE_FASTEST))
2177 {
2178 /* intra gating in inter slices */
2179 /* No need of gating if we want to force intra, we need to find the
2180 * threshold only if inter is enabled by AIR*/
2181 if((ps_proc->i4_slice_type != ISLICE) &&
2182 (FORCE_DISTORTION_BASED_INTRA_4X4_GATING ||
2183 (i4_air_enable_inter && ps_codec->u4_inter_gate)))
2184 {
2185 WORD32 i4_distortion[4];
2186
2187 if((ps_proc->i4_mb_x > 0) && (ps_proc->i4_mb_y > 0))
2188 {
2189 i4_distortion[0] = ps_proc->s_nbr_info.ps_left_mb_info->i4_mb_distortion;
2190
2191 i4_distortion[1] = ps_proc->s_nbr_info.ps_top_row_mb_info[ps_proc->i4_mb_x]
2192 .i4_mb_distortion;
2193
2194 i4_distortion[2] =
2195 ps_proc->s_nbr_info.ps_top_row_mb_info[ps_proc->i4_mb_x + 1]
2196 .i4_mb_distortion;
2197
2198 i4_distortion[3] =
2199 ps_proc->s_nbr_info.ps_top_row_mb_info[ps_proc->i4_mb_x - 1]
2200 .i4_mb_distortion;
2201
2202 i4_gate_threshold = (i4_distortion[0] + i4_distortion[1] +
2203 i4_distortion[2] + i4_distortion[3]) /
2204 4;
2205 }
2206 }
2207
2208 b_enable_intra4x4_eval = true;
2209
2210 if(ENABLE_IBL_MODE && (ps_proc->u1_spatial_layer_id > 0) &&
2211 (ps_proc->s_svc_params.d_spatial_res_ratio == 2.) && !ps_proc->ps_ilp_mv)
2212 {
2213 isvce_evaluate_IBL_mode(ps_proc);
2214 }
2215 else
2216 {
2217 ps_proc->ps_mb_info->u1_base_mode_flag = 0;
2218 }
2219
2220 if(u4_valid_modes & (1 << I16x16))
2221 {
2222 isvce_evaluate_intra16x16_modes_for_least_cost_rdoptoff(ps_proc);
2223
2224 if(ENABLE_INTRA16X16_BASED_INTRA4X4_GATING &&
2225 (ps_proc->i4_slice_type != ISLICE) &&
2226 (ps_proc->ps_mb_info->u2_mb_type == I16x16))
2227 {
2228 b_enable_intra4x4_eval = false;
2229 }
2230 }
2231
2232 if(u4_valid_modes & (1 << I8x8))
2233 {
2234 isvce_evaluate_intra8x8_modes_for_least_cost_rdoptoff(ps_proc);
2235 }
2236
2237 if(ENABLE_ILP_BASED_INTRA4X4_GATING && (ps_proc->i4_slice_type != ISLICE))
2238 {
2239 b_enable_intra4x4_eval =
2240 !(ps_proc->ps_ilp_mv && (INVALID_MB_TYPE != ps_proc->ps_ilp_mv->e_mb_type));
2241 }
2242
2243 /* If we are going to force intra we need to evaluate intra irrespective
2244 * of gating */
2245 if((!i4_air_enable_inter) ||
2246 ((i4_gate_threshold + 16 * ((WORD32) ps_proc->u4_lambda)) <
2247 ps_proc->i4_mb_distortion))
2248 {
2249 if(b_enable_intra4x4_eval && (u4_valid_modes & (1 << I4x4)))
2250 {
2251 if(!FORCE_FAST_INTRA4X4 &&
2252 (ps_codec->s_cfg.u4_enc_speed_preset == IVE_SLOWEST))
2253 {
2254 isvce_evaluate_intra4x4_modes_for_least_cost_rdopton(ps_proc);
2255 }
2256 else
2257 {
2258 isvce_evaluate_intra4x4_modes_for_least_cost_rdoptoff(ps_proc);
2259 }
2260 }
2261 }
2262 }
2263 }
2264
2265 if(ps_proc->ps_mb_info->u2_mb_type == I4x4 || ps_proc->ps_mb_info->u2_mb_type == I16x16 ||
2266 ps_proc->ps_mb_info->u2_mb_type == I8x8)
2267 {
2268 luma_idx = ps_proc->ps_mb_info->u2_mb_type;
2269 chroma_idx = 0;
2270 is_intra = 1;
2271
2272 isvce_evaluate_chroma_intra8x8_modes_for_least_cost_rdoptoff(ps_proc);
2273 }
2274 else if(ps_proc->ps_mb_info->u2_mb_type == BASE_MODE)
2275 {
2276 luma_idx = 3;
2277 chroma_idx = 1;
2278 is_intra = 1;
2279 ps_proc->u4_min_sad_reached = 0;
2280 }
2281 else
2282 {
2283 luma_idx = 3;
2284 chroma_idx = 1;
2285 is_intra = 0;
2286 }
2287
2288 ps_proc->ps_mb_info->u1_is_intra = is_intra;
2289
2290 if(is_intra)
2291 {
2292 ps_proc->ps_mb_info->as_pu->as_me_info[L0].i1_ref_idx = -1;
2293 ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvx = 0;
2294 ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvy = 0;
2295
2296 ps_proc->ps_mb_info->as_pu->as_me_info[L1].i1_ref_idx = -1;
2297 ps_proc->ps_mb_info->as_pu->as_me_info[L1].s_mv.i2_mvx = 0;
2298 ps_proc->ps_mb_info->as_pu->as_me_info[L1].s_mv.i2_mvy = 0;
2299 }
2300 else
2301 {
2302 isvce_mv_pred(ps_proc, ps_proc->i4_slice_type);
2303 }
2304
2305 if(ENABLE_RESIDUAL_PREDICTION && !is_intra && (ps_proc->u1_spatial_layer_id > 0) &&
2306 (ps_proc->i4_slice_type == PSLICE) && (ps_proc->ps_mb_info->u2_mb_type != PSKIP))
2307 {
2308 svc_res_pred_ctxt_t *ps_res_pred_ctxt = ps_proc->ps_res_pred_ctxt;
2309
2310 UWORD32 u4_res_pred_sad;
2311
2312 isvce_me_ctxt_t *ps_me_ctxt = &ps_proc->s_me_ctxt;
2313 yuv_buf_props_t s_pred = ps_proc->s_src_buf_props;
2314
2315 if(!(ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvx % 4) &&
2316 !(ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvy % 4))
2317 {
2318 s_pred.as_component_bufs[Y].pv_data =
2319 ps_me_ctxt->apu1_ref_buf_luma[L0] +
2320 (ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvx >> 2) +
2321 (ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvy >> 2) *
2322 ps_me_ctxt->ai4_rec_strd[L0];
2323 s_pred.as_component_bufs[Y].i4_data_stride = ps_me_ctxt->ai4_rec_strd[L0];
2324 }
2325 else
2326 {
2327 s_pred.as_component_bufs[Y].pv_data = ps_proc->pu1_best_subpel_buf;
2328 s_pred.as_component_bufs[Y].i4_data_stride = ps_proc->u4_bst_spel_buf_strd;
2329 }
2330
2331 s_pred.as_component_bufs[U].pv_data = s_pred.as_component_bufs[V].pv_data = NULL;
2332
2333 ps_res_pred_ctxt->s_res_pred_variables.ps_svc_ilp_data = &ps_codec->s_svc_ilp_data;
2334 ps_res_pred_ctxt->s_res_pred_variables.s_mb_pos.i4_abscissa = ps_proc->i4_mb_x;
2335 ps_res_pred_ctxt->s_res_pred_variables.s_mb_pos.i4_ordinate = ps_proc->i4_mb_y;
2336 ps_res_pred_ctxt->s_res_pred_variables.u1_spatial_layer_id =
2337 ps_proc->u1_spatial_layer_id;
2338
2339 if(ps_proc->s_svc_params.d_spatial_res_ratio == 2.)
2340 {
2341 isvce_get_mb_residual_pred(ps_proc->ps_res_pred_ctxt);
2342 }
2343 else
2344 {
2345 isvce_get_mb_residual_pred_non_dyadic(ps_proc->ps_res_pred_ctxt);
2346 }
2347
2348 isvce_residual_pred_eval(ps_proc->ps_res_pred_ctxt, &ps_proc->s_src_buf_props, &s_pred,
2349 ps_proc->ps_mb_res_buf, &u4_res_pred_sad,
2350 &ps_proc->ps_mb_info->u1_residual_prediction_flag,
2351 ps_proc->i4_mb_distortion);
2352
2353 if(ps_proc->ps_mb_info->u1_residual_prediction_flag)
2354 {
2355 ps_proc->i4_mb_cost -= ps_proc->i4_mb_distortion;
2356 ps_proc->i4_mb_cost += (WORD32) u4_res_pred_sad;
2357 ps_proc->i4_mb_distortion = (WORD32) u4_res_pred_sad;
2358 }
2359 }
2360 else
2361 {
2362 ps_proc->ps_mb_info->u1_residual_prediction_flag = 0;
2363 }
2364
2365 if(isvce_is_ilp_mv_winning_mv(ps_proc->ps_mb_info, ps_proc->ps_ilp_mv))
2366 {
2367 ps_proc->ps_mb_info->as_pu->as_me_info[L0] = ps_proc->ps_ilp_mv->as_mv[0][L0];
2368 ps_proc->ps_mb_info->as_pu->as_me_info[L1] = ps_proc->ps_ilp_mv->as_mv[0][L1];
2369
2370 ps_proc->ps_mb_info->u1_base_mode_flag = 1;
2371 ps_proc->ps_mb_info->u2_mb_type = BASE_MODE;
2372 }
2373 else if(ps_proc->ps_mb_info->u2_mb_type != BASE_MODE)
2374 {
2375 ps_proc->ps_mb_info->u1_base_mode_flag = 0;
2376 }
2377
2378 isvce_mvp_idx_eval(ps_proc->ps_mb_info, ps_proc->ps_pred_mv,
2379 ps_proc->ps_ilp_mv ? ps_proc->ps_ilp_mv->as_mv[0] : NULL,
2380 ps_proc->s_me_ctxt.pu1_mv_bits);
2381
2382 /* 8x8 Tx is not supported, and I8x8 is also unsupported */
2383 ASSERT((luma_idx == 0) || (luma_idx == 1) || (luma_idx == 3));
2384 ps_proc->ps_mb_info->u1_tx_size = 4;
2385
2386 /* Perform luma mb core coding */
2387 u4_cbp_l = (ps_enc_loop_fxns->apf_luma_energy_compaction)[luma_idx](ps_proc);
2388
2389 /* Perform chroma mb core coding */
2390 u4_cbp_c = (ps_enc_loop_fxns->apf_chroma_energy_compaction)[chroma_idx](ps_proc);
2391
2392 ps_proc->u4_cbp = (u4_cbp_c << 4) | u4_cbp_l;
2393 ps_proc->ps_mb_info->u4_cbp = (u4_cbp_c << 4) | u4_cbp_l;
2394 ps_proc->ps_mb_info->u4_csbp = isvce_calculate_csbp(ps_proc);
2395
2396 if(ps_proc->ps_mb_info->u1_is_intra)
2397 {
2398 switch(ps_proc->ps_mb_info->u2_mb_type)
2399 {
2400 case I16x16:
2401 {
2402 ps_proc->ps_mb_info->s_intra_pu.s_i16x16_mode_data.u1_mode =
2403 ps_proc->u1_l_i16_mode;
2404
2405 break;
2406 }
2407 case I4x4:
2408 {
2409 WORD32 i;
2410
2411 for(i = 0; i < MAX_TU_IN_MB; i++)
2412 {
2413 ps_proc->ps_mb_info->s_intra_pu.as_i4x4_mode_data[i].u1_mode =
2414 ps_proc->au1_intra_luma_mb_4x4_modes[i];
2415 ps_proc->ps_mb_info->s_intra_pu.as_i4x4_mode_data[i].u1_predicted_mode =
2416 ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i];
2417 }
2418
2419 break;
2420 }
2421 case BASE_MODE:
2422 {
2423 break;
2424 }
2425 default:
2426 {
2427 ASSERT(false);
2428 }
2429 }
2430
2431 ps_proc->ps_mb_info->s_intra_pu.u1_chroma_intra_mode = ps_proc->u1_c_i8_mode;
2432 }
2433
2434 if(!ps_proc->ps_mb_info->u1_is_intra && !ps_proc->ps_mb_info->u1_residual_prediction_flag)
2435 {
2436 if(ps_proc->i4_slice_type == BSLICE)
2437 {
2438 if(isvce_find_bskip_params(ps_proc, L0))
2439 {
2440 ps_proc->ps_mb_info->u2_mb_type = (ps_proc->u4_cbp) ? BDIRECT : BSKIP;
2441 }
2442 }
2443 else if(!ps_proc->u4_cbp)
2444 {
2445 if(isvce_find_pskip_params(ps_proc, L0))
2446 {
2447 ps_proc->ps_mb_info->u2_mb_type = PSKIP;
2448 }
2449 }
2450 }
2451
2452 UPDATE_MB_INFO:
2453 isvce_svc_ilp_buf_update(ps_proc);
2454
2455 isvce_update_ibl_info(
2456 ps_proc->ps_intra_pred_ctxt, ps_proc->s_svc_params.u1_num_spatial_layers,
2457 ps_proc->u1_spatial_layer_id, ps_proc->ps_mb_info->u2_mb_type, ps_proc->i4_mb_x,
2458 ps_proc->i4_mb_y, ps_proc->ps_mb_info->u1_base_mode_flag);
2459
2460 isvce_update_res_pred_info(ps_proc);
2461
2462 /* Update mb sad, mb qp and intra mb cost. Will be used by rate control */
2463 isvce_update_rc_mb_info(&ps_proc->s_frame_info, ps_proc);
2464
2465 {
2466 svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt = ps_proc->ps_sub_pic_rc_ctxt;
2467 svc_sub_pic_rc_mb_variables_t *ps_sub_pic_rc_variables =
2468 &ps_sub_pic_rc_ctxt->s_sub_pic_rc_variables.s_mb_variables;
2469
2470 ps_sub_pic_rc_variables->ps_mb_info = ps_proc->ps_mb_info;
2471 ps_sub_pic_rc_variables->s_mb_pos.i4_abscissa = ps_proc->i4_mb_x;
2472 ps_sub_pic_rc_variables->s_mb_pos.i4_ordinate = ps_proc->i4_mb_y;
2473 ps_sub_pic_rc_variables->u4_cbp = ps_proc->u4_cbp;
2474 ps_sub_pic_rc_variables->aps_mvps[0] = ps_proc->ps_pred_mv;
2475 #if MAX_MVP_IDX == 1
2476 ps_sub_pic_rc_variables->aps_mvps[1] =
2477 ps_proc->ps_ilp_mv ? ps_proc->ps_ilp_mv->as_mv[0] : NULL;
2478 #endif
2479 ps_sub_pic_rc_variables->apu1_nnzs[Y] = (UWORD8 *) ps_proc->au4_nnz;
2480 ps_sub_pic_rc_variables->apu1_nnzs[UV] = ps_proc->au1_chroma_nnz;
2481
2482 /* Quant coeffs are arranged TU by TU */
2483 switch(ps_proc->ps_mb_info->u2_mb_type)
2484 {
2485 case I16x16:
2486 case I4x4:
2487 case P16x16:
2488 case B16x16:
2489 case BASE_MODE:
2490 {
2491 ps_sub_pic_rc_variables->as_quant_coeffs[Y].pv_data =
2492 ps_proc->pi2_res_buf_intra_4x4;
2493 ps_sub_pic_rc_variables->as_quant_coeffs[Y].i4_data_stride =
2494 ps_proc->i4_res_strd;
2495 ps_sub_pic_rc_variables->as_quant_coeffs[UV].pv_data = ps_proc->pi2_res_buf;
2496 ps_sub_pic_rc_variables->as_quant_coeffs[UV].i4_data_stride =
2497 ps_proc->i4_res_strd;
2498
2499 break;
2500 }
2501 case PSKIP:
2502 case BSKIP:
2503 {
2504 ps_sub_pic_rc_variables->as_quant_coeffs[Y].pv_data = NULL;
2505 ps_sub_pic_rc_variables->as_quant_coeffs[UV].pv_data = NULL;
2506
2507 break;
2508 }
2509 default:
2510 {
2511 ASSERT(false);
2512
2513 break;
2514 }
2515 }
2516
2517 isvce_sub_pic_rc_ctxt_update(ps_proc->ps_sub_pic_rc_ctxt);
2518 }
2519
2520 #if ENABLE_MODE_STAT_VISUALISER
2521 if(ps_proc->u1_spatial_layer_id == (ps_proc->s_svc_params.u1_num_spatial_layers - 1))
2522 {
2523 coordinates_t s_mb_pos = {ps_proc->i4_mb_x, ps_proc->i4_mb_y};
2524
2525 isvce_msv_set_mode(ps_codec->ps_mode_stat_visualiser, ps_proc->ps_mb_info, &s_mb_pos);
2526 }
2527 #endif
2528
2529 /**********************************************************************/
2530 /* if disable deblock level is '0' this implies enable deblocking for */
2531 /* all edges of all macroblocks with out any restrictions */
2532 /* */
2533 /* if disable deblock level is '1' this implies disable deblocking for*/
2534 /* all edges of all macroblocks with out any restrictions */
2535 /* */
2536 /* if disable deblock level is '2' this implies enable deblocking for */
2537 /* all edges of all macroblocks except edges overlapping with slice */
2538 /* boundaries. This option is not currently supported by the encoder */
2539 /* hence the slice map should be of no significance to perform debloc */
2540 /* king */
2541 /**********************************************************************/
2542
2543 if(ps_proc->u4_compute_recon)
2544 {
2545 /* compute blocking strength */
2546 if(ps_proc->u4_disable_deblock_level != 1)
2547 {
2548 isvce_compute_bs(ps_proc, 0);
2549
2550 if(ENABLE_INTRA_BASE_DEBLOCK && (ps_proc->u1_spatial_layer_id <
2551 (ps_proc->s_svc_params.u1_num_spatial_layers - 1)))
2552 {
2553 isvce_compute_bs(ps_proc, 1);
2554 }
2555 }
2556 /* nmb deblocking and hpel and padding */
2557 isvce_dblk_n_mbs(ps_proc, 0);
2558
2559 if(ENABLE_INTRA_BASE_DEBLOCK &&
2560 (ps_proc->u1_spatial_layer_id < (ps_proc->s_svc_params.u1_num_spatial_layers - 1)))
2561 {
2562 isvce_intra_base_dblk(ps_proc);
2563 }
2564
2565 if(ps_proc->i4_mb_x == (ps_proc->i4_wd_mbs - 1) &&
2566 ps_proc->i4_mb_y == (ps_proc->i4_ht_mbs - 1))
2567 {
2568 isvce_svc_pad_frame(ps_proc);
2569
2570 isvce_pad_mb_mode_buf(ps_proc->ps_intra_pred_ctxt, ps_proc->u1_spatial_layer_id,
2571 ps_proc->s_svc_params.u1_num_spatial_layers,
2572 ps_proc->s_svc_params.d_spatial_res_ratio,
2573 ps_codec->s_cfg.u4_wd, ps_codec->s_cfg.u4_ht);
2574 }
2575 }
2576
2577 /* update the context after for coding next mb */
2578 error_status = isvce_update_proc_ctxt(ps_proc);
2579
2580 if(error_status != IH264E_SUCCESS)
2581 {
2582 return error_status;
2583 }
2584
2585 {
2586 UWORD8 u1_new_mb_qp;
2587
2588 u1_new_mb_qp =
2589 isvce_sub_pic_rc_get_mb_qp(ps_proc->ps_sub_pic_rc_ctxt, ps_proc->u1_mb_qp);
2590
2591 if(u1_new_mb_qp != ps_proc->u1_mb_qp)
2592 {
2593 ps_proc->u1_mb_qp = u1_new_mb_qp;
2594 ps_proc->u4_lambda = gu1_qp0[u1_new_mb_qp];
2595
2596 isvce_init_quant_params(ps_proc, ps_proc->u1_mb_qp);
2597 }
2598 }
2599
2600 /* Once the last row is processed, mark the buffer status appropriately */
2601 if(ps_proc->i4_ht_mbs == ps_proc->i4_mb_y)
2602 {
2603 /* Pointer to current picture buffer structure */
2604 svc_au_buf_t *ps_cur_pic = ps_proc->ps_cur_pic;
2605
2606 /* Pointer to current picture's mv buffer structure */
2607 svc_au_data_t *ps_cur_mv_buf = ps_proc->ps_cur_mv_buf;
2608
2609 /**********************************************************************/
2610 /* if disable deblock level is '0' this implies enable deblocking for */
2611 /* all edges of all macroblocks with out any restrictions */
2612 /* */
2613 /* if disable deblock level is '1' this implies disable deblocking for*/
2614 /* all edges of all macroblocks with out any restrictions */
2615 /* */
2616 /* if disable deblock level is '2' this implies enable deblocking for */
2617 /* all edges of all macroblocks except edges overlapping with slice */
2618 /* boundaries. This option is not currently supported by the encoder */
2619 /* hence the slice map should be of no significance to perform debloc */
2620 /* king */
2621 /**********************************************************************/
2622 error_status = ih264_buf_mgr_release(ps_codec->pv_svc_au_data_store_mgr,
2623 ps_cur_mv_buf->i4_buf_id, BUF_MGR_CODEC);
2624 if(error_status != IH264E_SUCCESS)
2625 {
2626 return error_status;
2627 }
2628 error_status = ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr, ps_cur_pic->i4_buf_id,
2629 BUF_MGR_CODEC);
2630 if(error_status != IH264E_SUCCESS)
2631 {
2632 return error_status;
2633 }
2634 if(ps_codec->s_cfg.u4_enable_recon)
2635 {
2636 /* pic cnt */
2637 ps_codec->as_rec_buf[ctxt_sel].i4_pic_cnt = ps_proc->i4_pic_cnt;
2638
2639 /* rec buffers */
2640 ps_codec->as_rec_buf[ctxt_sel].s_pic_buf = *ps_proc->ps_cur_pic;
2641
2642 /* is last? */
2643 ps_codec->as_rec_buf[ctxt_sel].u4_is_last = ps_proc->s_entropy.u4_is_last;
2644
2645 /* frame time stamp */
2646 ps_codec->as_rec_buf[ctxt_sel].u4_timestamp_high =
2647 ps_proc->s_entropy.u4_timestamp_high;
2648 ps_codec->as_rec_buf[ctxt_sel].u4_timestamp_low =
2649 ps_proc->s_entropy.u4_timestamp_low;
2650 }
2651 }
2652 }
2653
2654 DEBUG_HISTOGRAM_DUMP(ps_codec->s_cfg.i4_ht_mbs == ps_proc->i4_mb_y);
2655
2656 return error_status;
2657 }
2658
2659 /**
2660 *******************************************************************************
2661 *
2662 * @brief
2663 * entry point of a spawned encoder thread
2664 *
2665 * @par Description:
2666 * The encoder thread dequeues a proc/entropy job from the encoder queue and
2667 * calls necessary routines.
2668 *
2669 * @param[in] pv_proc
2670 * Process context corresponding to the thread
2671 *
2672 * @returns error status
2673 *
2674 * @remarks
2675 *
2676 *******************************************************************************
2677 */
isvce_process_thread(void * pv_proc)2678 WORD32 isvce_process_thread(void *pv_proc)
2679 {
2680 job_t s_job;
2681
2682 isvce_process_ctxt_t *ps_proc = pv_proc;
2683 isvce_codec_t *ps_codec = ps_proc->ps_codec;
2684
2685 IH264_ERROR_T ret = IH264_SUCCESS;
2686
2687 WORD32 ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS;
2688 WORD32 error_status = IH264_SUCCESS;
2689 WORD32 is_blocking = 0;
2690
2691 ps_proc->i4_error_code = IH264_SUCCESS;
2692
2693 while(1)
2694 {
2695 /* dequeue a job from the entropy queue */
2696 {
2697 bool b_is_entropy_state_invalid = false;
2698 WORD32 retval = ithread_mutex_lock(ps_codec->pv_entropy_mutex);
2699 volatile ISVCE_ENTROPY_THREAD_STATES_T *pe_entropy_thread_state =
2700 &ps_codec->ae_entropy_thread_exit_state[ctxt_sel];
2701
2702 /* have the lock */
2703 if(retval == 0)
2704 {
2705 if(*pe_entropy_thread_state == INACTIVE)
2706 {
2707 /* no entropy threads are active, try dequeuing a job from the entropy
2708 * queue */
2709 ret = ih264_list_dequeue(ps_proc->pv_entropy_jobq, &s_job, is_blocking);
2710
2711 if(IH264_SUCCESS == ret)
2712 {
2713 *pe_entropy_thread_state = IN_PROCESS;
2714 ithread_mutex_unlock(ps_codec->pv_entropy_mutex);
2715 goto WORKER;
2716 }
2717 else if(is_blocking)
2718 {
2719 ithread_mutex_unlock(ps_codec->pv_entropy_mutex);
2720 break;
2721 }
2722 }
2723 else if(*pe_entropy_thread_state == ERRONEOUS_EXIT)
2724 {
2725 b_is_entropy_state_invalid = true;
2726 }
2727
2728 ithread_mutex_unlock(ps_codec->pv_entropy_mutex);
2729 }
2730
2731 if(b_is_entropy_state_invalid)
2732 {
2733 ps_proc->i4_error_code = IH264_FAIL;
2734
2735 return IH264_FAIL;
2736 }
2737 }
2738
2739 /* dequeue a job from the process queue */
2740 ret = ih264_list_dequeue(ps_proc->pv_proc_jobq, &s_job, 1);
2741 if(IH264_SUCCESS != ret)
2742 {
2743 if(ps_proc->i4_id)
2744 {
2745 break;
2746 }
2747 else
2748 {
2749 is_blocking = 1;
2750 continue;
2751 }
2752 }
2753
2754 WORKER:
2755 /* choose appropriate proc context based on proc_base_idx */
2756 switch(s_job.i4_cmd)
2757 {
2758 case CMD_PROCESS:
2759 {
2760 ps_proc->i4_mb_cnt = s_job.i2_mb_cnt;
2761 ps_proc->i4_mb_x = s_job.i2_mb_x;
2762 ps_proc->i4_mb_y = s_job.i2_mb_y;
2763
2764 isvce_init_layer_proc_ctxt(ps_proc);
2765
2766 error_status = isvce_process(ps_proc);
2767
2768 if(error_status != IH264_SUCCESS)
2769 {
2770 ps_codec->ae_entropy_thread_exit_state[ctxt_sel] = ERRONEOUS_EXIT;
2771 ps_proc->i4_error_code = error_status;
2772 return ret;
2773 }
2774
2775 break;
2776 }
2777 case CMD_ENTROPY:
2778 {
2779 ps_proc->s_entropy.i4_mb_x = s_job.i2_mb_x;
2780 ps_proc->s_entropy.i4_mb_y = s_job.i2_mb_y;
2781 ps_proc->s_entropy.i4_mb_cnt = s_job.i2_mb_cnt;
2782
2783 isvce_init_entropy_ctxt(ps_proc);
2784
2785 error_status = isvce_entropy(ps_proc);
2786
2787 if(error_status != IH264_SUCCESS)
2788 {
2789 ps_codec->ae_entropy_thread_exit_state[ctxt_sel] = ERRONEOUS_EXIT;
2790 ps_proc->i4_error_code = error_status;
2791 return ret;
2792 }
2793
2794 break;
2795 }
2796 default:
2797 {
2798 ps_proc->i4_error_code = IH264_FAIL;
2799 return ret;
2800 }
2801 }
2802 }
2803
2804 return ret;
2805 }
2806