blob: 818e192679c5297130a44f8d5a3601c89255ffdd [file] [log] [blame]
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301/******************************************************************************
2 *
3 * Copyright (C) 2015 The Android Open Source Project
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at:
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 *
17 *****************************************************************************
18 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*/
20
21/**
22*******************************************************************************
23* @file
24* ih264e_process.c
25*
26* @brief
27* Contains functions for codec thread
28*
29* @author
30* Harish
31*
32* @par List of Functions:
33* - ih264e_generate_sps_pps()
34* - ih264e_init_entropy_ctxt()
35* - ih264e_entropy()
36* - ih264e_pack_header_data()
37* - ih264e_update_proc_ctxt()
38* - ih264e_init_proc_ctxt()
39* - ih264e_pad_recon_buffer()
40* - ih264e_dblk_pad_hpel_processing_n_mbs()
41* - ih264e_process()
42* - ih264e_set_rc_pic_params()
43* - ih264e_update_rc_post_enc()
44* - ih264e_process_thread()
45*
46* @remarks
47* None
48*
49*******************************************************************************
50*/
51
52/*****************************************************************************/
53/* File Includes */
54/*****************************************************************************/
55
56/* System include files */
57#include <stdio.h>
58#include <stddef.h>
59#include <stdlib.h>
60#include <string.h>
61#include <limits.h>
62#include <assert.h>
63
64/* User include files */
65#include "ih264_typedefs.h"
66#include "iv2.h"
67#include "ive2.h"
68#include "ih264_defs.h"
69#include "ih264_debug.h"
70#include "ime_distortion_metrics.h"
Harinarayanan K K134291e2015-06-18 16:03:38 +053071#include "ime_defs.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +053072#include "ime_structs.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +053073#include "ih264_error.h"
74#include "ih264_structs.h"
75#include "ih264_trans_quant_itrans_iquant.h"
76#include "ih264_inter_pred_filters.h"
77#include "ih264_mem_fns.h"
78#include "ih264_padding.h"
79#include "ih264_intra_pred_filters.h"
80#include "ih264_deblk_edge_filters.h"
Harinarayanan K K134291e2015-06-18 16:03:38 +053081#include "ih264_cabac_tables.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +053082#include "ih264_platform_macros.h"
83#include "ih264_macros.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +053084#include "ih264_buf_mgr.h"
85#include "ih264e_error.h"
86#include "ih264e_bitstream.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +053087#include "ih264_common_tables.h"
88#include "ih264_list.h"
89#include "ih264e_defs.h"
90#include "irc_cntrl_param.h"
91#include "irc_frame_info_collector.h"
92#include "ih264e_rate_control.h"
Harinarayanan K K134291e2015-06-18 16:03:38 +053093#include "ih264e_cabac_structs.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +053094#include "ih264e_structs.h"
Harinarayanan K K134291e2015-06-18 16:03:38 +053095#include "ih264e_cabac.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +053096#include "ih264e_process.h"
97#include "ithread.h"
98#include "ih264e_intra_modes_eval.h"
99#include "ih264e_encode_header.h"
100#include "ih264e_globals.h"
101#include "ih264e_config.h"
102#include "ih264e_trace.h"
103#include "ih264e_statistics.h"
104#include "ih264_cavlc_tables.h"
105#include "ih264e_cavlc.h"
106#include "ih264e_deblk.h"
107#include "ih264e_me.h"
108#include "ih264e_debug.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530109#include "ih264e_master.h"
110#include "ih264e_utils.h"
111#include "irc_mem_req_and_acq.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530112#include "irc_rate_control_api.h"
113#include "ih264e_platform_macros.h"
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530114#include "ime_statistics.h"
115
116
117/*****************************************************************************/
118/* Function Definitions */
119/*****************************************************************************/
120
121/**
122******************************************************************************
123*
124* @brief This function generates sps, pps set on request
125*
126* @par Description
127* When the encoder is set in header generation mode, the following function
128* is called. This generates sps and pps headers and returns the control back
129* to caller.
130*
131* @param[in] ps_codec
132* pointer to codec context
133*
134* @return success or failure error code
135*
136******************************************************************************
137*/
138IH264E_ERROR_T ih264e_generate_sps_pps(codec_t *ps_codec)
139{
140 /* choose between ping-pong process buffer set */
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530141 WORD32 ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530142
143 /* entropy ctxt */
144 entropy_ctxt_t *ps_entropy = &ps_codec->as_process[ctxt_sel * MAX_PROCESS_THREADS].s_entropy;
145
146 /* Bitstream structure */
147 bitstrm_t *ps_bitstrm = ps_entropy->ps_bitstrm;
148
149 /* sps */
150 sps_t *ps_sps = NULL;
151
152 /* pps */
153 pps_t *ps_pps = NULL;
154
155 /* output buff */
156 out_buf_t *ps_out_buf = &ps_codec->as_out_buf[ctxt_sel];
157
158
159 /********************************************************************/
160 /* initialize the bit stream buffer */
161 /********************************************************************/
162 ih264e_bitstrm_init(ps_bitstrm, ps_out_buf->s_bits_buf.pv_buf, ps_out_buf->s_bits_buf.u4_bufsize);
163
164 /********************************************************************/
165 /* BEGIN HEADER GENERATION */
166 /********************************************************************/
167 /*ps_codec->i4_pps_id ++;*/
168 ps_codec->i4_pps_id %= MAX_PPS_CNT;
169
170 /*ps_codec->i4_sps_id ++;*/
171 ps_codec->i4_sps_id %= MAX_SPS_CNT;
172
173 /* populate sps header */
174 ps_sps = ps_codec->ps_sps_base + ps_codec->i4_sps_id;
175 ih264e_populate_sps(ps_codec, ps_sps);
176
177 /* populate pps header */
178 ps_pps = ps_codec->ps_pps_base + ps_codec->i4_pps_id;
179 ih264e_populate_pps(ps_codec, ps_pps);
180
181 ps_entropy->i4_error_code = IH264E_SUCCESS;
182
183 /* generate sps */
Chamarthi Kishore95a21132019-10-11 18:53:50 +0530184 ps_entropy->i4_error_code = ih264e_generate_sps(ps_bitstrm, ps_sps,
Doney Alex983e1ae2016-03-30 17:31:26 +0530185 &ps_codec->s_cfg.s_vui);
Chamarthi Kishore95a21132019-10-11 18:53:50 +0530186 if(ps_entropy->i4_error_code != IH264E_SUCCESS)
187 {
188 return ps_entropy->i4_error_code;
189 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530190 /* generate pps */
Chamarthi Kishore95a21132019-10-11 18:53:50 +0530191 ps_entropy->i4_error_code = ih264e_generate_pps(ps_bitstrm, ps_pps, ps_sps);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530192
193 /* queue output buffer */
194 ps_out_buf->s_bits_buf.u4_bytes = ps_bitstrm->u4_strm_buf_offset;
195
196 return ps_entropy->i4_error_code;
197}
198
199/**
200*******************************************************************************
201*
202* @brief initialize entropy context.
203*
204* @par Description:
205* Before invoking the call to perform to entropy coding the entropy context
206* associated with the job needs to be initialized. This involves the start
207* mb address, end mb address, slice index and the pointer to location at
208* which the mb residue info and mb header info are packed.
209*
210* @param[in] ps_proc
211* Pointer to the current process context
212*
213* @returns error status
214*
215* @remarks none
216*
217*******************************************************************************
218*/
219IH264E_ERROR_T ih264e_init_entropy_ctxt(process_ctxt_t *ps_proc)
220{
221 /* codec context */
222 codec_t *ps_codec = ps_proc->ps_codec;
223
224 /* entropy ctxt */
225 entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
226
227 /* start address */
228 ps_entropy->i4_mb_start_add = ps_entropy->i4_mb_y * ps_entropy->i4_wd_mbs + ps_entropy->i4_mb_x;
229
230 /* end address */
231 ps_entropy->i4_mb_end_add = ps_entropy->i4_mb_start_add + ps_entropy->i4_mb_cnt;
232
233 /* slice index */
234 ps_entropy->i4_cur_slice_idx = ps_proc->pu1_slice_idx[ps_entropy->i4_mb_start_add];
235
236 /* sof */
237 /* @ start of frame or start of a new slice, set sof flag */
238 if (ps_entropy->i4_mb_start_add == 0)
239 {
240 ps_entropy->i4_sof = 1;
241 }
242
243 if (ps_entropy->i4_mb_x == 0)
244 {
245 /* packed mb coeff data */
246 ps_entropy->pv_mb_coeff_data = ((UWORD8 *)ps_entropy->pv_pic_mb_coeff_data) +
247 ps_entropy->i4_mb_y * ps_codec->u4_size_coeff_data;
248
249 /* packed mb header data */
250 ps_entropy->pv_mb_header_data = ((UWORD8 *)ps_entropy->pv_pic_mb_header_data) +
251 ps_entropy->i4_mb_y * ps_codec->u4_size_header_data;
252 }
253
254 return IH264E_SUCCESS;
255}
256
257/**
258*******************************************************************************
259*
260* @brief entry point for entropy coding
261*
262* @par Description
263* This function calls lower level functions to perform entropy coding for a
264* group (n rows) of mb's. After encoding 1 row of mb's, the function takes
265* back the control, updates the ctxt and calls lower level functions again.
266* This process is repeated till all the rows or group of mb's (which ever is
267* minimum) are coded
268*
269* @param[in] ps_proc
270* process context
271*
272* @returns error status
273*
274* @remarks
275*
276*******************************************************************************
277*/
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530278
279IH264E_ERROR_T ih264e_entropy(process_ctxt_t *ps_proc)
280{
281 /* codec context */
282 codec_t *ps_codec = ps_proc->ps_codec;
283
284 /* entropy context */
285 entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
286
Harinarayanan K K134291e2015-06-18 16:03:38 +0530287 /* cabac context */
288 cabac_ctxt_t *ps_cabac_ctxt = ps_entropy->ps_cabac;
289
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530290 /* sps */
291 sps_t *ps_sps = ps_entropy->ps_sps_base + (ps_entropy->u4_sps_id % MAX_SPS_CNT);
292
293 /* pps */
294 pps_t *ps_pps = ps_entropy->ps_pps_base + (ps_entropy->u4_pps_id % MAX_PPS_CNT);
295
296 /* slice header */
297 slice_header_t *ps_slice_hdr = ps_entropy->ps_slice_hdr_base + (ps_entropy->i4_cur_slice_idx % MAX_SLICE_HDR_CNT);
298
299 /* slice type */
300 WORD32 i4_slice_type = ps_proc->i4_slice_type;
301
302 /* Bitstream structure */
303 bitstrm_t *ps_bitstrm = ps_entropy->ps_bitstrm;
304
305 /* output buff */
306 out_buf_t s_out_buf;
307
Chamarthi Kishoread2eaf82019-10-01 11:59:43 +0530308 /* sei params */
309 sei_params_t s_sei;
310
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530311 /* proc map */
312 UWORD8 *pu1_proc_map;
313
314 /* entropy map */
315 UWORD8 *pu1_entropy_map_curr;
316
317 /* proc base idx */
Harinarayanan K K6cb67722015-06-19 14:44:42 +0530318 WORD32 ctxt_sel = ps_proc->i4_encode_api_call_cnt % MAX_CTXT_SETS;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530319
320 /* temp var */
321 WORD32 i4_wd_mbs, i4_ht_mbs;
Chamarthi Kishoread2eaf82019-10-01 11:59:43 +0530322 UWORD32 u4_mb_cnt, u4_mb_idx, u4_mb_end_idx, u4_insert_per_idr;
Harinarayanan K K134291e2015-06-18 16:03:38 +0530323 WORD32 bitstream_start_offset, bitstream_end_offset;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530324 /********************************************************************/
325 /* BEGIN INIT */
326 /********************************************************************/
327
328 /* entropy encode start address */
329 u4_mb_idx = ps_entropy->i4_mb_start_add;
330
331 /* entropy encode end address */
332 u4_mb_end_idx = ps_entropy->i4_mb_end_add;
333
334 /* width in mbs */
335 i4_wd_mbs = ps_entropy->i4_wd_mbs;
336
337 /* height in mbs */
338 i4_ht_mbs = ps_entropy->i4_ht_mbs;
339
340 /* total mb cnt */
341 u4_mb_cnt = i4_wd_mbs * i4_ht_mbs;
342
343 /* proc map */
344 pu1_proc_map = ps_proc->pu1_proc_map + ps_entropy->i4_mb_y * i4_wd_mbs;
345
346 /* entropy map */
347 pu1_entropy_map_curr = ps_entropy->pu1_entropy_map + ps_entropy->i4_mb_y * i4_wd_mbs;
348
349 /********************************************************************/
350 /* @ start of frame / slice, */
351 /* initialize the output buffer, */
352 /* initialize the bit stream buffer, */
353 /* check if sps and pps headers have to be generated, */
354 /* populate and generate slice header */
355 /********************************************************************/
356 if (ps_entropy->i4_sof)
357 {
358 /********************************************************************/
359 /* initialize the output buffer */
360 /********************************************************************/
361 s_out_buf = ps_codec->as_out_buf[ctxt_sel];
362
363 /* is last frame to encode */
364 s_out_buf.u4_is_last = ps_entropy->u4_is_last;
365
366 /* frame idx */
367 s_out_buf.u4_timestamp_high = ps_entropy->u4_timestamp_high;
368 s_out_buf.u4_timestamp_low = ps_entropy->u4_timestamp_low;
369
370 /********************************************************************/
371 /* initialize the bit stream buffer */
372 /********************************************************************/
373 ih264e_bitstrm_init(ps_bitstrm, s_out_buf.s_bits_buf.pv_buf, s_out_buf.s_bits_buf.u4_bufsize);
374
375 /********************************************************************/
376 /* BEGIN HEADER GENERATION */
377 /********************************************************************/
378 if (1 == ps_entropy->i4_gen_header)
379 {
380 /* generate sps */
Chamarthi Kishore95a21132019-10-11 18:53:50 +0530381 ps_entropy->i4_error_code = ih264e_generate_sps(ps_bitstrm, ps_sps,
Doney Alex983e1ae2016-03-30 17:31:26 +0530382 &ps_codec->s_cfg.s_vui);
Chamarthi Kishore4bc3e632019-11-27 13:52:47 +0530383 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530384 /* generate pps */
Chamarthi Kishore95a21132019-10-11 18:53:50 +0530385 ps_entropy->i4_error_code = ih264e_generate_pps(ps_bitstrm, ps_pps, ps_sps);
Chamarthi Kishore4bc3e632019-11-27 13:52:47 +0530386 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
387
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530388 /* reset i4_gen_header */
389 ps_entropy->i4_gen_header = 0;
390 }
391
392 /* populate slice header */
393 ih264e_populate_slice_header(ps_proc, ps_slice_hdr, ps_pps, ps_sps);
394
Chamarthi Kishoread2eaf82019-10-01 11:59:43 +0530395 /* generate sei */
396 u4_insert_per_idr = (NAL_SLICE_IDR == ps_slice_hdr->i1_nal_unit_type);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530397
Chamarthi Kishoread2eaf82019-10-01 11:59:43 +0530398 memset(&s_sei, 0, sizeof(sei_params_t));
399 s_sei.u1_sei_mdcv_params_present_flag =
400 ps_codec->s_cfg.s_sei.u1_sei_mdcv_params_present_flag;
401 s_sei.s_sei_mdcv_params = ps_codec->s_cfg.s_sei.s_sei_mdcv_params;
402 s_sei.u1_sei_cll_params_present_flag =
403 ps_codec->s_cfg.s_sei.u1_sei_cll_params_present_flag;
404 s_sei.s_sei_cll_params = ps_codec->s_cfg.s_sei.s_sei_cll_params;
405 s_sei.u1_sei_ave_params_present_flag =
406 ps_codec->s_cfg.s_sei.u1_sei_ave_params_present_flag;
407 s_sei.s_sei_ave_params = ps_codec->s_cfg.s_sei.s_sei_ave_params;
408 s_sei.u1_sei_ccv_params_present_flag = 0;
409 s_sei.s_sei_ccv_params =
410 ps_codec->as_inp_list[ps_codec->i4_poc % MAX_NUM_BFRAMES].s_sei_ccv;
411
412 if((1 == ps_sps->i1_vui_parameters_present_flag) &&
413 (1 == ps_codec->s_cfg.s_vui.u1_video_signal_type_present_flag) &&
414 (1 == ps_codec->s_cfg.s_vui.u1_colour_description_present_flag) &&
415 (2 != ps_codec->s_cfg.s_vui.u1_colour_primaries) &&
416 (2 != ps_codec->s_cfg.s_vui.u1_matrix_coefficients) &&
417 (2 != ps_codec->s_cfg.s_vui.u1_transfer_characteristics) &&
418 (4 != ps_codec->s_cfg.s_vui.u1_transfer_characteristics) &&
419 (5 != ps_codec->s_cfg.s_vui.u1_transfer_characteristics))
420 {
421 s_sei.u1_sei_ccv_params_present_flag =
422 ps_codec->as_inp_list[ps_codec->i4_poc % MAX_NUM_BFRAMES].u1_sei_ccv_params_present_flag;
423 }
424
425 if((1 == s_sei.u1_sei_mdcv_params_present_flag && u4_insert_per_idr) ||
426 (1 == s_sei.u1_sei_cll_params_present_flag && u4_insert_per_idr) ||
427 (1 == s_sei.u1_sei_ave_params_present_flag && u4_insert_per_idr) ||
428 (1 == s_sei.u1_sei_ccv_params_present_flag))
429 {
Chamarthi Kishore95a21132019-10-11 18:53:50 +0530430 ps_entropy->i4_error_code =
Chamarthi Kishoread2eaf82019-10-01 11:59:43 +0530431 ih264e_generate_sei(ps_bitstrm, &s_sei, u4_insert_per_idr);
Chamarthi Kishore4bc3e632019-11-27 13:52:47 +0530432 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
Chamarthi Kishoread2eaf82019-10-01 11:59:43 +0530433 }
434 ps_codec->as_inp_list[ps_codec->i4_poc % MAX_NUM_BFRAMES].u1_sei_ccv_params_present_flag = 0;
435
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530436 /* generate slice header */
Chamarthi Kishore95a21132019-10-11 18:53:50 +0530437 ps_entropy->i4_error_code = ih264e_generate_slice_header(ps_bitstrm, ps_slice_hdr,
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530438 ps_pps, ps_sps);
Chamarthi Kishore4bc3e632019-11-27 13:52:47 +0530439 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530440 /* once start of frame / slice is done, you can reset it */
441 /* it is the responsibility of the caller to set this flag */
442 ps_entropy->i4_sof = 0;
Harinarayanan K K134291e2015-06-18 16:03:38 +0530443
444 if (CABAC == ps_entropy->u1_entropy_coding_mode_flag)
445 {
446 BITSTREAM_BYTE_ALIGN(ps_bitstrm);
Neelkamal Semwal3de25bf2021-03-10 10:03:39 +0530447 BITSTREAM_FLUSH(ps_bitstrm, ps_entropy->i4_error_code);
Harinarayanan K K134291e2015-06-18 16:03:38 +0530448 ih264e_init_cabac_ctxt(ps_entropy);
449 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530450 }
451
452 /* begin entropy coding for the mb set */
453 while (u4_mb_idx < u4_mb_end_idx)
454 {
455 /* init ptrs/indices */
456 if (ps_entropy->i4_mb_x == i4_wd_mbs)
457 {
Harinarayanan K K134291e2015-06-18 16:03:38 +0530458 ps_entropy->i4_mb_y++;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530459 ps_entropy->i4_mb_x = 0;
460
461 /* packed mb coeff data */
462 ps_entropy->pv_mb_coeff_data = ((UWORD8 *)ps_entropy->pv_pic_mb_coeff_data) +
463 ps_entropy->i4_mb_y * ps_codec->u4_size_coeff_data;
464
465 /* packed mb header data */
466 ps_entropy->pv_mb_header_data = ((UWORD8 *)ps_entropy->pv_pic_mb_header_data) +
467 ps_entropy->i4_mb_y * ps_codec->u4_size_header_data;
468
469 /* proc map */
Harinarayanan K K134291e2015-06-18 16:03:38 +0530470 pu1_proc_map = ps_proc->pu1_proc_map + ps_entropy->i4_mb_y * i4_wd_mbs;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530471
472 /* entropy map */
473 pu1_entropy_map_curr = ps_entropy->pu1_entropy_map + ps_entropy->i4_mb_y * i4_wd_mbs;
474 }
475
476 DEBUG("\nmb indices x, y %d, %d", ps_entropy->i4_mb_x, ps_entropy->i4_mb_y);
477 ENTROPY_TRACE("mb index x %d", ps_entropy->i4_mb_x);
478 ENTROPY_TRACE("mb index y %d", ps_entropy->i4_mb_y);
479
480 /* wait until the curr mb is core coded */
481 /* The wait for curr mb to be core coded is essential when entropy is launched
482 * as a separate job
483 */
484 while (1)
485 {
486 volatile UWORD8 *pu1_buf1;
487 WORD32 idx = ps_entropy->i4_mb_x;
488
Harinarayanan K K134291e2015-06-18 16:03:38 +0530489 pu1_buf1 = pu1_proc_map + idx;
490 if (*pu1_buf1)
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530491 break;
492 ithread_yield();
493 }
494
Harinarayanan K K134291e2015-06-18 16:03:38 +0530495
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530496 /* write mb layer */
Chamarthi Kishore95a21132019-10-11 18:53:50 +0530497 ps_entropy->i4_error_code = ps_codec->pf_write_mb_syntax_layer
498 [ps_entropy->u1_entropy_coding_mode_flag][i4_slice_type](ps_entropy);
Chamarthi Kishore4bc3e632019-11-27 13:52:47 +0530499 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
Chamarthi Kishore95a21132019-10-11 18:53:50 +0530500
Harinarayanan K K134291e2015-06-18 16:03:38 +0530501 /* Starting bitstream offset for header in bits */
502 bitstream_start_offset = GET_NUM_BITS(ps_bitstrm);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530503
504 /* set entropy map */
505 pu1_entropy_map_curr[ps_entropy->i4_mb_x] = 1;
506
Harinarayanan K K134291e2015-06-18 16:03:38 +0530507 u4_mb_idx++;
508 ps_entropy->i4_mb_x++;
509 /* check for eof */
510 if (CABAC == ps_entropy->u1_entropy_coding_mode_flag)
511 {
512 if (ps_entropy->i4_mb_x < i4_wd_mbs)
513 {
514 ih264e_cabac_encode_terminate(ps_cabac_ctxt, 0);
515 }
516 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530517
518 if (ps_entropy->i4_mb_x == i4_wd_mbs)
519 {
520 /* if slices are enabled */
521 if (ps_codec->s_cfg.e_slice_mode == IVE_SLICE_MODE_BLOCKS)
522 {
523 /* current slice index */
524 WORD32 i4_curr_slice_idx = ps_entropy->i4_cur_slice_idx;
525
526 /* slice map */
527 UWORD8 *pu1_slice_idx = ps_entropy->pu1_slice_idx;
528
529 /* No need to open a slice at end of frame. The current slice can be closed at the time
530 * of signaling eof flag.
531 */
Harinarayanan K K134291e2015-06-18 16:03:38 +0530532 if ((u4_mb_idx != u4_mb_cnt) && (i4_curr_slice_idx
533 != pu1_slice_idx[u4_mb_idx]))
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530534 {
Harinarayanan K K134291e2015-06-18 16:03:38 +0530535 if (CAVLC == ps_entropy->u1_entropy_coding_mode_flag)
536 { /* mb skip run */
537 if ((i4_slice_type != ISLICE)
538 && *ps_entropy->pi4_mb_skip_run)
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530539 {
Harinarayanan K K134291e2015-06-18 16:03:38 +0530540 if (*ps_entropy->pi4_mb_skip_run)
541 {
Chamarthi Kishore4bc3e632019-11-27 13:52:47 +0530542 PUT_BITS_UEV(ps_bitstrm, *ps_entropy->pi4_mb_skip_run,
543 ps_entropy->i4_error_code, "mb skip run");
Harinarayanan K K134291e2015-06-18 16:03:38 +0530544 *ps_entropy->pi4_mb_skip_run = 0;
Chamarthi Kishore4bc3e632019-11-27 13:52:47 +0530545 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
Harinarayanan K K134291e2015-06-18 16:03:38 +0530546 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530547 }
Harinarayanan K K134291e2015-06-18 16:03:38 +0530548 /* put rbsp trailing bits for the previous slice */
Chamarthi Kishore4bc3e632019-11-27 13:52:47 +0530549 ps_entropy->i4_error_code = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
550 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530551 }
Harinarayanan K K134291e2015-06-18 16:03:38 +0530552 else
553 {
554 ih264e_cabac_encode_terminate(ps_cabac_ctxt, 1);
555 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530556
557 /* update slice header pointer */
558 i4_curr_slice_idx = pu1_slice_idx[u4_mb_idx];
559 ps_entropy->i4_cur_slice_idx = i4_curr_slice_idx;
Harinarayanan K K134291e2015-06-18 16:03:38 +0530560 ps_slice_hdr = ps_entropy->ps_slice_hdr_base+ (i4_curr_slice_idx % MAX_SLICE_HDR_CNT);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530561
562 /* populate slice header */
563 ps_entropy->i4_mb_start_add = u4_mb_idx;
Harinarayanan K K134291e2015-06-18 16:03:38 +0530564 ih264e_populate_slice_header(ps_proc, ps_slice_hdr, ps_pps,
565 ps_sps);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530566
567 /* generate slice header */
Chamarthi Kishore95a21132019-10-11 18:53:50 +0530568 ps_entropy->i4_error_code = ih264e_generate_slice_header(
Harinarayanan K K134291e2015-06-18 16:03:38 +0530569 ps_bitstrm, ps_slice_hdr, ps_pps, ps_sps);
Chamarthi Kishore4bc3e632019-11-27 13:52:47 +0530570 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
Harinarayanan K K134291e2015-06-18 16:03:38 +0530571 if (CABAC == ps_entropy->u1_entropy_coding_mode_flag)
572 {
573 BITSTREAM_BYTE_ALIGN(ps_bitstrm);
Neelkamal Semwal3de25bf2021-03-10 10:03:39 +0530574 BITSTREAM_FLUSH(ps_bitstrm, ps_entropy->i4_error_code);
Harinarayanan K K134291e2015-06-18 16:03:38 +0530575 ih264e_init_cabac_ctxt(ps_entropy);
576 }
577 }
578 else
579 {
580 if (CABAC == ps_entropy->u1_entropy_coding_mode_flag
581 && u4_mb_idx != u4_mb_cnt)
582 {
583 ih264e_cabac_encode_terminate(ps_cabac_ctxt, 0);
584 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530585 }
586 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530587 }
Harinarayanan K K134291e2015-06-18 16:03:38 +0530588
589 /* Ending bitstream offset for header in bits */
590 bitstream_end_offset = GET_NUM_BITS(ps_bitstrm);
591 ps_entropy->u4_header_bits[i4_slice_type == PSLICE] +=
592 bitstream_end_offset - bitstream_start_offset;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530593 }
594
595 /* check for eof */
596 if (u4_mb_idx == u4_mb_cnt)
597 {
598 /* set end of frame flag */
599 ps_entropy->i4_eof = 1;
600 }
Harinarayanan K K134291e2015-06-18 16:03:38 +0530601 else
602 {
603 if (CABAC == ps_entropy->u1_entropy_coding_mode_flag
604 && ps_codec->s_cfg.e_slice_mode
605 != IVE_SLICE_MODE_BLOCKS)
606 {
607 ih264e_cabac_encode_terminate(ps_cabac_ctxt, 0);
608 }
609 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530610
611 if (ps_entropy->i4_eof)
612 {
Harinarayanan K K134291e2015-06-18 16:03:38 +0530613 if (CAVLC == ps_entropy->u1_entropy_coding_mode_flag)
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530614 {
Harinarayanan K K134291e2015-06-18 16:03:38 +0530615 /* mb skip run */
616 if ((i4_slice_type != ISLICE) && *ps_entropy->pi4_mb_skip_run)
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530617 {
Harinarayanan K K134291e2015-06-18 16:03:38 +0530618 if (*ps_entropy->pi4_mb_skip_run)
619 {
620 PUT_BITS_UEV(ps_bitstrm, *ps_entropy->pi4_mb_skip_run,
621 ps_entropy->i4_error_code, "mb skip run");
622 *ps_entropy->pi4_mb_skip_run = 0;
Chamarthi Kishore4bc3e632019-11-27 13:52:47 +0530623 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
Harinarayanan K K134291e2015-06-18 16:03:38 +0530624 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530625 }
Harinarayanan K K134291e2015-06-18 16:03:38 +0530626 /* put rbsp trailing bits */
Chamarthi Kishore95a21132019-10-11 18:53:50 +0530627 ps_entropy->i4_error_code = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
Chamarthi Kishore4bc3e632019-11-27 13:52:47 +0530628 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
Harinarayanan K K134291e2015-06-18 16:03:38 +0530629 }
630 else
631 {
632 ih264e_cabac_encode_terminate(ps_cabac_ctxt, 1);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530633 }
634
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530635 /* update current frame stats to rc library */
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530636 {
637 /* number of bytes to stuff */
638 WORD32 i4_stuff_bytes;
639
640 /* update */
Harinarayanan K K134291e2015-06-18 16:03:38 +0530641 i4_stuff_bytes = ih264e_update_rc_post_enc(
642 ps_codec, ctxt_sel,
643 (ps_proc->ps_codec->i4_poc == 0));
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530644
645 /* cbr rc - house keeping */
646 if (ps_codec->s_rate_control.post_encode_skip[ctxt_sel])
647 {
Chamarthi Kishore95a21132019-10-11 18:53:50 +0530648 ps_entropy->ps_bitstrm->u4_strm_buf_offset = 0;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530649 }
650 else if (i4_stuff_bytes)
651 {
652 /* add filler nal units */
Chamarthi Kishore95a21132019-10-11 18:53:50 +0530653 ps_entropy->i4_error_code = ih264e_add_filler_nal_unit(ps_bitstrm, i4_stuff_bytes);
Chamarthi Kishore4bc3e632019-11-27 13:52:47 +0530654 RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530655 }
656 }
657
Harinarayanan K K134291e2015-06-18 16:03:38 +0530658 /*
659 *Frame number is to be incremented only if the current frame is a
660 * reference frame. After each successful frame encode, we increment
661 * frame number by 1
662 */
663 if (!ps_codec->s_rate_control.post_encode_skip[ctxt_sel]
664 && ps_codec->u4_is_curr_frm_ref)
665 {
666 ps_codec->i4_frame_num++;
667 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530668 /********************************************************************/
669 /* signal the output */
670 /********************************************************************/
Harinarayanan K K134291e2015-06-18 16:03:38 +0530671 ps_codec->as_out_buf[ctxt_sel].s_bits_buf.u4_bytes =
672 ps_entropy->ps_bitstrm->u4_strm_buf_offset;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530673
674 DEBUG("entropy status %x", ps_entropy->i4_error_code);
675 }
676
Ram Mohan5df81832019-05-10 19:55:26 +0530677 /* Dont execute any further instructions until store synchronization took place */
678 DATA_SYNC();
679
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530680 /* allow threads to dequeue entropy jobs */
681 ps_codec->au4_entropy_thread_active[ctxt_sel] = 0;
682
683 return ps_entropy->i4_error_code;
684}
685
686/**
687*******************************************************************************
688*
689* @brief Packs header information of a mb in to a buffer
690*
691* @par Description:
692* After the deciding the mode info of a macroblock, the syntax elements
693* associated with the mb are packed and stored. The entropy thread unpacks
694* this buffer and generates the end bit stream.
695*
696* @param[in] ps_proc
697* Pointer to the current process context
698*
699* @returns error status
700*
701* @remarks none
702*
703*******************************************************************************
704*/
705IH264E_ERROR_T ih264e_pack_header_data(process_ctxt_t *ps_proc)
706{
707 /* curr mb type */
708 UWORD32 u4_mb_type = ps_proc->u4_mb_type;
709
710 /* pack mb syntax layer of curr mb (used for entropy coding) */
711 if (u4_mb_type == I4x4)
712 {
713 /* pointer to mb header storage space */
714 UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530715 mb_hdr_i4x4_t *ps_mb_hdr = (mb_hdr_i4x4_t *)ps_proc->pv_mb_header_data;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530716
717 /* temp var */
718 WORD32 i4, byte;
719
720 /* mb type plus mode */
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530721 ps_mb_hdr->common.u1_mb_type_mode = (ps_proc->u1_c_i8_mode << 6) + u4_mb_type;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530722
723 /* cbp */
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530724 ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530725
726 /* mb qp delta */
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530727 ps_mb_hdr->common.u1_mb_qp_delta = ps_proc->u4_mb_qp - ps_proc->u4_mb_qp_prev;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530728
729 /* sub mb modes */
730 for (i4 = 0; i4 < 16; i4 ++)
731 {
732 byte = 0;
733
734 if (ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i4] ==
735 ps_proc->au1_intra_luma_mb_4x4_modes[i4])
736 {
737 byte |= 1;
738 }
739 else
740 {
741
742 if (ps_proc->au1_intra_luma_mb_4x4_modes[i4] <
743 ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i4])
744 {
745 byte |= (ps_proc->au1_intra_luma_mb_4x4_modes[i4] << 1);
746 }
747 else
748 {
749 byte |= (ps_proc->au1_intra_luma_mb_4x4_modes[i4] - 1) << 1;
750 }
751 }
752
753 i4++;
754
755 if (ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i4] ==
756 ps_proc->au1_intra_luma_mb_4x4_modes[i4])
757 {
758 byte |= 16;
759 }
760 else
761 {
762
763 if (ps_proc->au1_intra_luma_mb_4x4_modes[i4] <
764 ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i4])
765 {
766 byte |= (ps_proc->au1_intra_luma_mb_4x4_modes[i4] << 5);
767 }
768 else
769 {
770 byte |= (ps_proc->au1_intra_luma_mb_4x4_modes[i4] - 1) << 5;
771 }
772 }
773
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530774 ps_mb_hdr->au1_sub_blk_modes[i4 >> 1] = byte;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530775 }
776
777 /* end of mb layer */
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530778 pu1_ptr += sizeof(mb_hdr_i4x4_t);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530779 ps_proc->pv_mb_header_data = pu1_ptr;
780 }
781 else if (u4_mb_type == I16x16)
782 {
783 /* pointer to mb header storage space */
784 UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530785 mb_hdr_i16x16_t *ps_mb_hdr = (mb_hdr_i16x16_t *)ps_proc->pv_mb_header_data;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530786
787 /* mb type plus mode */
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530788 ps_mb_hdr->common.u1_mb_type_mode = (ps_proc->u1_c_i8_mode << 6) + (ps_proc->u1_l_i16_mode << 4) + u4_mb_type;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530789
790 /* cbp */
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530791 ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530792
793 /* mb qp delta */
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530794 ps_mb_hdr->common.u1_mb_qp_delta = ps_proc->u4_mb_qp - ps_proc->u4_mb_qp_prev;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530795
796 /* end of mb layer */
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530797 pu1_ptr += sizeof(mb_hdr_i16x16_t);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530798 ps_proc->pv_mb_header_data = pu1_ptr;
799 }
800 else if (u4_mb_type == P16x16)
801 {
802 /* pointer to mb header storage space */
803 UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530804 mb_hdr_p16x16_t *ps_mb_hdr = (mb_hdr_p16x16_t *)ps_proc->pv_mb_header_data;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530805
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530806 /* mb type */
807 ps_mb_hdr->common.u1_mb_type_mode = u4_mb_type;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530808
809 /* cbp */
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530810 ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530811
812 /* mb qp delta */
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530813 ps_mb_hdr->common.u1_mb_qp_delta = ps_proc->u4_mb_qp - ps_proc->u4_mb_qp_prev;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530814
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530815 ps_mb_hdr->ai2_mv[0] = ps_proc->ps_pu->s_me_info[0].s_mv.i2_mvx - ps_proc->ps_pred_mv[0].s_mv.i2_mvx;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530816
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530817 ps_mb_hdr->ai2_mv[1] = ps_proc->ps_pu->s_me_info[0].s_mv.i2_mvy - ps_proc->ps_pred_mv[0].s_mv.i2_mvy;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530818
819 /* end of mb layer */
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530820 pu1_ptr += sizeof(mb_hdr_p16x16_t);
821 ps_proc->pv_mb_header_data = pu1_ptr;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530822 }
823 else if (u4_mb_type == PSKIP)
824 {
825 /* pointer to mb header storage space */
826 UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530827 mb_hdr_pskip_t *ps_mb_hdr = (mb_hdr_pskip_t *)ps_proc->pv_mb_header_data;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530828
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530829 /* mb type */
830 ps_mb_hdr->common.u1_mb_type_mode = u4_mb_type;
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530831
832 /* end of mb layer */
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530833 pu1_ptr += sizeof(mb_hdr_pskip_t);
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530834 ps_proc->pv_mb_header_data = pu1_ptr;
835 }
Harinarayanan K K134291e2015-06-18 16:03:38 +0530836 else if(u4_mb_type == B16x16)
837 {
838
839 /* pointer to mb header storage space */
840 UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530841 mb_hdr_b16x16_t *ps_mb_hdr = (mb_hdr_b16x16_t *)ps_proc->pv_mb_header_data;
Harinarayanan K K134291e2015-06-18 16:03:38 +0530842
843 UWORD32 u4_pred_mode = ps_proc->ps_pu->b2_pred_mode;
844
845 /* mb type plus mode */
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530846 ps_mb_hdr->common.u1_mb_type_mode = (u4_pred_mode << 4) + u4_mb_type;
Harinarayanan K K134291e2015-06-18 16:03:38 +0530847
848 /* cbp */
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530849 ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
Harinarayanan K K134291e2015-06-18 16:03:38 +0530850
851 /* mb qp delta */
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530852 ps_mb_hdr->common.u1_mb_qp_delta = ps_proc->u4_mb_qp - ps_proc->u4_mb_qp_prev;
Harinarayanan K K134291e2015-06-18 16:03:38 +0530853
854 /* l0 & l1 me data */
Harinarayanan K K134291e2015-06-18 16:03:38 +0530855 if (u4_pred_mode != PRED_L1)
856 {
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530857 ps_mb_hdr->ai2_mv[0][0] = ps_proc->ps_pu->s_me_info[0].s_mv.i2_mvx
Harinarayanan K K134291e2015-06-18 16:03:38 +0530858 - ps_proc->ps_pred_mv[0].s_mv.i2_mvx;
859
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530860 ps_mb_hdr->ai2_mv[0][1] = ps_proc->ps_pu->s_me_info[0].s_mv.i2_mvy
Harinarayanan K K134291e2015-06-18 16:03:38 +0530861 - ps_proc->ps_pred_mv[0].s_mv.i2_mvy;
862 }
863 if (u4_pred_mode != PRED_L0)
864 {
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530865 ps_mb_hdr->ai2_mv[1][0] = ps_proc->ps_pu->s_me_info[1].s_mv.i2_mvx
Harinarayanan K K134291e2015-06-18 16:03:38 +0530866 - ps_proc->ps_pred_mv[1].s_mv.i2_mvx;
867
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530868 ps_mb_hdr->ai2_mv[1][1] = ps_proc->ps_pu->s_me_info[1].s_mv.i2_mvy
Harinarayanan K K134291e2015-06-18 16:03:38 +0530869 - ps_proc->ps_pred_mv[1].s_mv.i2_mvy;
870 }
871
872 /* end of mb layer */
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530873 pu1_ptr += sizeof(mb_hdr_b16x16_t);
874 ps_proc->pv_mb_header_data = pu1_ptr;
Harinarayanan K K134291e2015-06-18 16:03:38 +0530875
876 }
877 else if(u4_mb_type == BDIRECT)
878 {
879 /* pointer to mb header storage space */
880 UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530881 mb_hdr_bdirect_t *ps_mb_hdr = (mb_hdr_bdirect_t *)ps_proc->pv_mb_header_data;
Harinarayanan K K134291e2015-06-18 16:03:38 +0530882
883 /* mb type plus mode */
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530884 ps_mb_hdr->common.u1_mb_type_mode = u4_mb_type;
Harinarayanan K K134291e2015-06-18 16:03:38 +0530885
886 /* cbp */
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530887 ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
Harinarayanan K K134291e2015-06-18 16:03:38 +0530888
889 /* mb qp delta */
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530890 ps_mb_hdr->common.u1_mb_qp_delta = ps_proc->u4_mb_qp - ps_proc->u4_mb_qp_prev;
Harinarayanan K K134291e2015-06-18 16:03:38 +0530891
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530892 /* end of mb layer */
893 pu1_ptr += sizeof(mb_hdr_bdirect_t);
Harinarayanan K K134291e2015-06-18 16:03:38 +0530894 ps_proc->pv_mb_header_data = pu1_ptr;
895
896 }
897 else if(u4_mb_type == BSKIP)
898 {
899 UWORD32 u4_pred_mode = ps_proc->ps_pu->b2_pred_mode;
900
901 /* pointer to mb header storage space */
902 UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530903 mb_hdr_bskip_t *ps_mb_hdr = (mb_hdr_bskip_t *)ps_proc->pv_mb_header_data;
Harinarayanan K K134291e2015-06-18 16:03:38 +0530904
905 /* mb type plus mode */
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530906 ps_mb_hdr->common.u1_mb_type_mode = (u4_pred_mode << 4) + u4_mb_type;
Harinarayanan K K134291e2015-06-18 16:03:38 +0530907
908 /* end of mb layer */
Harish Mahendrakarc7d9c912016-11-23 13:30:39 +0530909 pu1_ptr += sizeof(mb_hdr_bskip_t);
Harinarayanan K K134291e2015-06-18 16:03:38 +0530910 ps_proc->pv_mb_header_data = pu1_ptr;
911 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530912
913 return IH264E_SUCCESS;
914}
915
916/**
917*******************************************************************************
918*
919* @brief update process context after encoding an mb. This involves preserving
920* the current mb information for later use, initialize the proc ctxt elements to
921* encode next mb.
922*
923* @par Description:
924* This function performs house keeping tasks after encoding an mb.
925* After encoding an mb, various elements of the process context needs to be
926* updated to encode the next mb. For instance, the source, recon and reference
927* pointers, mb indices have to be adjusted to the next mb. The slice index of
928* the current mb needs to be updated. If mb qp modulation is enabled, then if
929* the qp changes the quant param structure needs to be updated. Also to encoding
930* the next mb, the current mb info is used as part of mode prediction or mv
931* prediction. Hence the current mb info has to preserved at top/top left/left
932* locations.
933*
934* @param[in] ps_proc
935* Pointer to the current process context
936*
937* @returns none
938*
939* @remarks none
940*
941*******************************************************************************
942*/
943WORD32 ih264e_update_proc_ctxt(process_ctxt_t *ps_proc)
944{
945 /* error status */
946 WORD32 error_status = IH264_SUCCESS;
947
948 /* codec context */
949 codec_t *ps_codec = ps_proc->ps_codec;
950
951 /* curr mb indices */
952 WORD32 i4_mb_x = ps_proc->i4_mb_x;
953 WORD32 i4_mb_y = ps_proc->i4_mb_y;
954
955 /* mb syntax elements of neighbors */
956 mb_info_t *ps_left_syn = &ps_proc->s_left_mb_syntax_ele;
957 mb_info_t *ps_top_syn = ps_proc->ps_top_row_mb_syntax_ele + i4_mb_x;
958 mb_info_t *ps_top_left_syn = &ps_proc->s_top_left_mb_syntax_ele;
959
960 /* curr mb type */
961 UWORD32 u4_mb_type = ps_proc->u4_mb_type;
962
963 /* curr mb type */
964 UWORD32 u4_is_intra = ps_proc->u4_is_intra;
965
966 /* width in mbs */
967 WORD32 i4_wd_mbs = ps_proc->i4_wd_mbs;
968
969 /*height in mbs*/
970 WORD32 i4_ht_mbs = ps_proc->i4_ht_mbs;
971
972 /* proc map */
973 UWORD8 *pu1_proc_map = ps_proc->pu1_proc_map + (i4_mb_y * i4_wd_mbs);
974
975 /* deblk context */
976 deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
977
978 /* deblk bs context */
979 bs_ctxt_t *ps_bs = &(ps_deblk->s_bs_ctxt);
980
981 /* top row motion vector info */
982 enc_pu_t *ps_top_row_pu = ps_proc->ps_top_row_pu + i4_mb_x;
983
984 /* top left mb motion vector */
985 enc_pu_t *ps_top_left_mb_pu = &ps_proc->s_top_left_mb_pu;
986
987 /* left mb motion vector */
988 enc_pu_t *ps_left_mb_pu = &ps_proc->s_left_mb_pu;
989
990 /* sub mb modes */
991 UWORD8 *pu1_top_mb_intra_modes = ps_proc->pu1_top_mb_intra_modes + (i4_mb_x << 4);
992
Hamsalekha S8d3d3032015-03-13 21:24:58 +0530993 /*************************************************************/
994 /* During MV prediction, when top right mb is not available, */
995 /* top left mb info. is used for prediction. Hence the curr */
996 /* top, which will be top left for the next mb needs to be */
997 /* preserved before updating it with curr mb info. */
998 /*************************************************************/
999
1000 /* mb type, mb class, csbp */
1001 *ps_top_left_syn = *ps_top_syn;
1002
Harinarayanan K K134291e2015-06-18 16:03:38 +05301003 if (ps_proc->i4_slice_type != ISLICE)
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301004 {
1005 /*****************************************/
1006 /* update top left with top info results */
1007 /*****************************************/
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301008 /* mv */
1009 *ps_top_left_mb_pu = *ps_top_row_pu;
1010 }
1011
1012 /*************************************************/
1013 /* update top and left with curr mb info results */
1014 /*************************************************/
1015
1016 /* mb type */
1017 ps_left_syn->u2_mb_type = ps_top_syn->u2_mb_type = u4_mb_type;
1018
1019 /* mb class */
1020 ps_left_syn->u2_is_intra = ps_top_syn->u2_is_intra = u4_is_intra;
1021
1022 /* csbp */
1023 ps_left_syn->u4_csbp = ps_top_syn->u4_csbp = ps_proc->u4_csbp;
1024
1025 /* distortion */
1026 ps_left_syn->i4_mb_distortion = ps_top_syn->i4_mb_distortion = ps_proc->i4_mb_distortion;
1027
1028 if (u4_is_intra)
1029 {
1030 /* mb / sub mb modes */
1031 if (I16x16 == u4_mb_type)
1032 {
1033 pu1_top_mb_intra_modes[0] = ps_proc->au1_left_mb_intra_modes[0] = ps_proc->u1_l_i16_mode;
1034 }
1035 else if (I4x4 == u4_mb_type)
1036 {
1037 ps_codec->pf_mem_cpy_mul8(ps_proc->au1_left_mb_intra_modes, ps_proc->au1_intra_luma_mb_4x4_modes, 16);
1038 ps_codec->pf_mem_cpy_mul8(pu1_top_mb_intra_modes, ps_proc->au1_intra_luma_mb_4x4_modes, 16);
1039 }
1040 else if (I8x8 == u4_mb_type)
1041 {
1042 memcpy(ps_proc->au1_left_mb_intra_modes, ps_proc->au1_intra_luma_mb_8x8_modes, 4);
1043 memcpy(pu1_top_mb_intra_modes, ps_proc->au1_intra_luma_mb_8x8_modes, 4);
1044 }
1045
Harinarayanan K K134291e2015-06-18 16:03:38 +05301046 if ((ps_proc->i4_slice_type == PSLICE) ||(ps_proc->i4_slice_type == BSLICE))
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301047 {
1048 /* mv */
1049 *ps_left_mb_pu = *ps_top_row_pu = *(ps_proc->ps_pu);
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301050 }
Harinarayanan K K134291e2015-06-18 16:03:38 +05301051
1052 *ps_proc->pu4_mb_pu_cnt = 1;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301053 }
1054 else
1055 {
1056 /* mv */
1057 *ps_left_mb_pu = *ps_top_row_pu = *(ps_proc->ps_pu);
1058 }
1059
1060 /*
1061 * Mark that the MB has been coded intra
1062 * So that future AIRs can skip it
1063 */
1064 ps_proc->pu1_is_intra_coded[i4_mb_x + (i4_mb_y * i4_wd_mbs)] = u4_is_intra;
1065
1066 /**************************************************/
1067 /* pack mb header info. for entropy coding */
1068 /**************************************************/
1069 ih264e_pack_header_data(ps_proc);
1070
1071 /* update previous mb qp */
1072 ps_proc->u4_mb_qp_prev = ps_proc->u4_mb_qp;
1073
1074 /* store qp */
1075 ps_proc->s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp[(i4_mb_y * i4_wd_mbs) + i4_mb_x] = ps_proc->u4_mb_qp;
1076
1077 /*
1078 * We need to sync the cache to make sure that the nmv content of proc
1079 * is updated to cache properly
1080 */
1081 DATA_SYNC();
1082
1083 /* Just before finishing the row, enqueue the job in to entropy queue.
1084 * The master thread depending on its convenience shall dequeue it and
1085 * performs entropy.
1086 *
1087 * WARN !! Placing this block post proc map update can cause queuing of
1088 * entropy jobs in out of order.
1089 */
1090 if (i4_mb_x == i4_wd_mbs - 1)
1091 {
1092 /* job structures */
1093 job_t s_job;
1094
1095 /* job class */
1096 s_job.i4_cmd = CMD_ENTROPY;
1097
1098 /* number of mbs to be processed in the current job */
1099 s_job.i2_mb_cnt = ps_codec->s_cfg.i4_wd_mbs;
1100
1101 /* job start index x */
1102 s_job.i2_mb_x = 0;
1103
1104 /* job start index y */
1105 s_job.i2_mb_y = ps_proc->i4_mb_y;
1106
1107 /* proc base idx */
Harinarayanan K K6cb67722015-06-19 14:44:42 +05301108 s_job.i2_proc_base_idx = (ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS) ? (MAX_PROCESS_CTXT / 2) : 0;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301109
1110 /* queue the job */
Chamarthi Kishore95a21132019-10-11 18:53:50 +05301111 error_status = ih264_list_queue(ps_proc->pv_entropy_jobq, &s_job, 1);
1112 if(error_status != IH264_SUCCESS)
1113 {
1114 return error_status;
1115 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301116 if(ps_proc->i4_mb_y == (i4_ht_mbs - 1))
1117 ih264_list_terminate(ps_codec->pv_entropy_jobq);
1118 }
1119
1120 /* update proc map */
1121 pu1_proc_map[i4_mb_x] = 1;
1122
1123 /**************************************************/
1124 /* update proc ctxt elements for encoding next mb */
1125 /**************************************************/
1126 /* update indices */
1127 i4_mb_x ++;
1128 ps_proc->i4_mb_x = i4_mb_x;
1129
1130 if (ps_proc->i4_mb_x == i4_wd_mbs)
1131 {
1132 ps_proc->i4_mb_y++;
1133 ps_proc->i4_mb_x = 0;
1134 }
1135
1136 /* update slice index */
1137 ps_proc->i4_cur_slice_idx = ps_proc->pu1_slice_idx[ps_proc->i4_mb_y * i4_wd_mbs + ps_proc->i4_mb_x];
1138
1139 /* update buffers pointers */
1140 ps_proc->pu1_src_buf_luma += MB_SIZE;
1141 ps_proc->pu1_rec_buf_luma += MB_SIZE;
Harinarayanan K K134291e2015-06-18 16:03:38 +05301142 ps_proc->apu1_ref_buf_luma[0] += MB_SIZE;
1143 ps_proc->apu1_ref_buf_luma[1] += MB_SIZE;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301144
1145 /*
1146 * Note: Although chroma mb size is 8, as the chroma buffers are interleaved,
1147 * the stride per MB is MB_SIZE
1148 */
1149 ps_proc->pu1_src_buf_chroma += MB_SIZE;
1150 ps_proc->pu1_rec_buf_chroma += MB_SIZE;
Harinarayanan K K134291e2015-06-18 16:03:38 +05301151 ps_proc->apu1_ref_buf_chroma[0] += MB_SIZE;
1152 ps_proc->apu1_ref_buf_chroma[1] += MB_SIZE;
1153
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301154
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301155
1156 /* Reset cost, distortion params */
1157 ps_proc->i4_mb_cost = INT_MAX;
1158 ps_proc->i4_mb_distortion = SHRT_MAX;
1159
1160 ps_proc->ps_pu += *ps_proc->pu4_mb_pu_cnt;
1161
1162 ps_proc->pu4_mb_pu_cnt += 1;
1163
Harinarayanan K K134291e2015-06-18 16:03:38 +05301164 /* Update colocated pu */
1165 if (ps_proc->i4_slice_type == BSLICE)
1166 ps_proc->ps_colpu += *(ps_proc->aps_mv_buf[1]->pu4_mb_pu_cnt + (i4_mb_y * ps_proc->i4_wd_mbs) + i4_mb_x);
1167
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301168 /* deblk ctxts */
1169 if (ps_proc->u4_disable_deblock_level != 1)
1170 {
1171 /* indices */
1172 ps_bs->i4_mb_x = ps_proc->i4_mb_x;
1173 ps_bs->i4_mb_y = ps_proc->i4_mb_y;
1174
1175#ifndef N_MB_ENABLE /* For N MB processing update take place inside deblocking function */
1176 ps_deblk->i4_mb_x ++;
1177
1178 ps_deblk->pu1_cur_pic_luma += MB_SIZE;
1179 /*
1180 * Note: Although chroma mb size is 8, as the chroma buffers are interleaved,
1181 * the stride per MB is MB_SIZE
1182 */
1183 ps_deblk->pu1_cur_pic_chroma += MB_SIZE;
1184#endif
1185 }
1186
1187 return error_status;
1188}
1189
1190/**
1191*******************************************************************************
1192*
1193* @brief initialize process context.
1194*
1195* @par Description:
1196* Before dispatching the current job to process thread, the process context
1197* associated with the job is initialized. Usually every job aims to encode one
1198* row of mb's. Basing on the row indices provided by the job, the process
1199* context's buffer ptrs, slice indices and other elements that are necessary
1200* during core-coding are initialized.
1201*
1202* @param[in] ps_proc
1203* Pointer to the current process context
1204*
1205* @returns error status
1206*
1207* @remarks none
1208*
1209*******************************************************************************
1210*/
1211IH264E_ERROR_T ih264e_init_proc_ctxt(process_ctxt_t *ps_proc)
1212{
1213 /* codec context */
1214 codec_t *ps_codec = ps_proc->ps_codec;
1215
1216 /* nmb processing context*/
1217 n_mb_process_ctxt_t *ps_n_mb_ctxt = &ps_proc->s_n_mb_ctxt;
1218
1219 /* indices */
1220 WORD32 i4_mb_x, i4_mb_y;
1221
1222 /* strides */
1223 WORD32 i4_src_strd = ps_proc->i4_src_strd;
Martin Storsjo53c68782015-06-09 16:25:51 +03001224 WORD32 i4_src_chroma_strd = ps_proc->i4_src_chroma_strd;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301225 WORD32 i4_rec_strd = ps_proc->i4_rec_strd;
1226
1227 /* quant params */
1228 quant_params_t *ps_qp_params = ps_proc->ps_qp_params[0];
1229
1230 /* deblk ctxt */
1231 deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
1232
1233 /* deblk bs context */
1234 bs_ctxt_t *ps_bs = &(ps_deblk->s_bs_ctxt);
1235
1236 /* Pointer to mv_buffer of current frame */
1237 mv_buf_t *ps_cur_mv_buf = ps_proc->ps_cur_mv_buf;
1238
1239 /* Pointers for color space conversion */
1240 UWORD8 *pu1_y_buf_base, *pu1_u_buf_base, *pu1_v_buf_base;
1241
1242 /* Pad the MB to support non standard sizes */
Harish Mahendrakarc72323e2015-04-28 19:07:40 +05301243 UWORD32 u4_pad_right_sz = ps_codec->s_cfg.u4_wd - ps_codec->s_cfg.u4_disp_wd;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301244 UWORD32 u4_pad_bottom_sz = ps_codec->s_cfg.u4_ht - ps_codec->s_cfg.u4_disp_ht;
Harish Mahendrakarc72323e2015-04-28 19:07:40 +05301245 UWORD16 u2_num_rows = MB_SIZE;
1246 WORD32 convert_uv_only;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301247
1248 /********************************************************************/
1249 /* BEGIN INIT */
1250 /********************************************************************/
1251
1252 i4_mb_x = ps_proc->i4_mb_x;
1253 i4_mb_y = ps_proc->i4_mb_y;
1254
1255 /* Number of mbs processed in one loop of process function */
Harinarayanan K K6cb67722015-06-19 14:44:42 +05301256 ps_proc->i4_nmb_ntrpy = ps_proc->i4_wd_mbs;
1257 ps_proc->u4_nmb_me = ps_proc->i4_wd_mbs;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301258
Harinarayanan K K134291e2015-06-18 16:03:38 +05301259 /* init buffer pointers */
Harish Mahendrakarc72323e2015-04-28 19:07:40 +05301260 convert_uv_only = 1;
Martin Storsjof7682972015-06-16 21:30:36 +02001261 if (u4_pad_bottom_sz || u4_pad_right_sz ||
Neelkamal Semwal646a58c2021-04-01 12:52:14 +05301262 ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_422ILE ||
1263 ps_proc->i4_mb_y == (ps_proc->i4_ht_mbs - 1))
Harish Mahendrakarc72323e2015-04-28 19:07:40 +05301264 {
Martin Storsjo90a39042015-06-09 16:38:50 +03001265 if (ps_proc->i4_mb_y == ps_proc->i4_ht_mbs - 1)
1266 u2_num_rows = (UWORD16) MB_SIZE - u4_pad_bottom_sz;
Harish Mahendrakarc72323e2015-04-28 19:07:40 +05301267 ps_proc->pu1_src_buf_luma_base = ps_codec->pu1_y_csc_buf_base;
Martin Storsjo90a39042015-06-09 16:38:50 +03001268 i4_src_strd = ps_proc->i4_src_strd = ps_codec->s_cfg.u4_max_wd;
Harish Mahendrakarc72323e2015-04-28 19:07:40 +05301269 ps_proc->pu1_src_buf_luma = ps_proc->pu1_src_buf_luma_base + (i4_mb_x * MB_SIZE) + ps_codec->s_cfg.u4_max_wd * (i4_mb_y * MB_SIZE);
1270 convert_uv_only = 0;
Harish Mahendrakarc72323e2015-04-28 19:07:40 +05301271 }
1272 else
Martin Storsjo90a39042015-06-09 16:38:50 +03001273 {
1274 i4_src_strd = ps_proc->i4_src_strd = ps_proc->s_inp_buf.s_raw_buf.au4_strd[0];
Harish Mahendrakarc72323e2015-04-28 19:07:40 +05301275 ps_proc->pu1_src_buf_luma = ps_proc->pu1_src_buf_luma_base + (i4_mb_x * MB_SIZE) + i4_src_strd * (i4_mb_y * MB_SIZE);
Martin Storsjo90a39042015-06-09 16:38:50 +03001276 }
Harish Mahendrakarc72323e2015-04-28 19:07:40 +05301277
Harish Mahendrakarc72323e2015-04-28 19:07:40 +05301278
Harish Mahendrakar5cdb8882015-06-09 17:48:53 +05301279 if (ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_422ILE ||
1280 ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_420P ||
Martin Storsjof7682972015-06-16 21:30:36 +02001281 ps_proc->i4_mb_y == (ps_proc->i4_ht_mbs - 1) ||
1282 u4_pad_bottom_sz || u4_pad_right_sz)
Harish Mahendrakar5cdb8882015-06-09 17:48:53 +05301283 {
1284 if ((ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_420SP_UV) ||
1285 (ps_codec->s_cfg.e_inp_color_fmt == IV_YUV_420SP_VU))
1286 ps_proc->pu1_src_buf_chroma_base = ps_codec->pu1_uv_csc_buf_base;
1287
1288 ps_proc->pu1_src_buf_chroma = ps_proc->pu1_src_buf_chroma_base + (i4_mb_x * MB_SIZE) + ps_codec->s_cfg.u4_max_wd * (i4_mb_y * BLK8x8SIZE);
Martin Storsjo90a39042015-06-09 16:38:50 +03001289 i4_src_chroma_strd = ps_proc->i4_src_chroma_strd = ps_codec->s_cfg.u4_max_wd;
Harish Mahendrakar5cdb8882015-06-09 17:48:53 +05301290 }
1291 else
1292 {
Martin Storsjo90a39042015-06-09 16:38:50 +03001293 i4_src_chroma_strd = ps_proc->i4_src_chroma_strd = ps_proc->s_inp_buf.s_raw_buf.au4_strd[1];
Martin Storsjo53c68782015-06-09 16:25:51 +03001294 ps_proc->pu1_src_buf_chroma = ps_proc->pu1_src_buf_chroma_base + (i4_mb_x * MB_SIZE) + i4_src_chroma_strd * (i4_mb_y * BLK8x8SIZE);
Harish Mahendrakar5cdb8882015-06-09 17:48:53 +05301295 }
1296
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301297 ps_proc->pu1_rec_buf_luma = ps_proc->pu1_rec_buf_luma_base + (i4_mb_x * MB_SIZE) + i4_rec_strd * (i4_mb_y * MB_SIZE);
1298 ps_proc->pu1_rec_buf_chroma = ps_proc->pu1_rec_buf_chroma_base + (i4_mb_x * MB_SIZE) + i4_rec_strd * (i4_mb_y * BLK8x8SIZE);
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301299
Harinarayanan K K134291e2015-06-18 16:03:38 +05301300 /* Tempral back and forward reference buffer */
1301 ps_proc->apu1_ref_buf_luma[0] = ps_proc->apu1_ref_buf_luma_base[0] + (i4_mb_x * MB_SIZE) + i4_rec_strd * (i4_mb_y * MB_SIZE);
1302 ps_proc->apu1_ref_buf_chroma[0] = ps_proc->apu1_ref_buf_chroma_base[0] + (i4_mb_x * MB_SIZE) + i4_rec_strd * (i4_mb_y * BLK8x8SIZE);
1303 ps_proc->apu1_ref_buf_luma[1] = ps_proc->apu1_ref_buf_luma_base[1] + (i4_mb_x * MB_SIZE) + i4_rec_strd * (i4_mb_y * MB_SIZE);
1304 ps_proc->apu1_ref_buf_chroma[1] = ps_proc->apu1_ref_buf_chroma_base[1] + (i4_mb_x * MB_SIZE) + i4_rec_strd * (i4_mb_y * BLK8x8SIZE);
Harish Mahendrakarc72323e2015-04-28 19:07:40 +05301305
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301306 /*
1307 * Do color space conversion
1308 * NOTE : We assume there that the number of MB's to process will not span multiple rows
1309 */
1310 switch (ps_codec->s_cfg.e_inp_color_fmt)
1311 {
1312 case IV_YUV_420SP_UV:
1313 case IV_YUV_420SP_VU:
Harish Mahendrakar5cdb8882015-06-09 17:48:53 +05301314 /* In case of 420 semi-planar input, copy last few rows to intermediate
Neelkamal Semwal646a58c2021-04-01 12:52:14 +05301315 buffer as few SIMD functions access upto 16 more bytes.
Harish Mahendrakar5cdb8882015-06-09 17:48:53 +05301316 This data will be padded if required */
Martin Storsjof7682972015-06-16 21:30:36 +02001317 if (ps_proc->i4_mb_y == (ps_proc->i4_ht_mbs - 1) || u4_pad_bottom_sz || u4_pad_right_sz)
Harish Mahendrakar5cdb8882015-06-09 17:48:53 +05301318 {
Martin Storsjof7682972015-06-16 21:30:36 +02001319 WORD32 num_rows = MB_SIZE;
Harish Mahendrakar5cdb8882015-06-09 17:48:53 +05301320 UWORD8 *pu1_src;
1321 UWORD8 *pu1_dst;
1322 WORD32 i;
1323 pu1_src = (UWORD8 *)ps_proc->s_inp_buf.s_raw_buf.apv_bufs[0] + (i4_mb_x * MB_SIZE) +
1324 ps_proc->s_inp_buf.s_raw_buf.au4_strd[0] * (i4_mb_y * MB_SIZE);
1325
1326 pu1_dst = ps_proc->pu1_src_buf_luma;
1327
Neelkamal Semwal646a58c2021-04-01 12:52:14 +05301328 if (ps_proc->i4_mb_y == (ps_proc->i4_ht_mbs - 1))
1329 num_rows = MB_SIZE - u4_pad_bottom_sz;
1330 for (i = 0; i < num_rows; i++)
1331 {
Suyog Pawarb483f222022-10-07 17:42:45 +05301332 memcpy(pu1_dst, pu1_src, ps_codec->s_cfg.u4_disp_wd);
Neelkamal Semwal646a58c2021-04-01 12:52:14 +05301333 pu1_src += ps_proc->s_inp_buf.s_raw_buf.au4_strd[0];
1334 pu1_dst += ps_proc->i4_src_strd;
Harish Mahendrakar5cdb8882015-06-09 17:48:53 +05301335 }
1336 pu1_src = (UWORD8 *)ps_proc->s_inp_buf.s_raw_buf.apv_bufs[1] + (i4_mb_x * BLK8x8SIZE) +
1337 ps_proc->s_inp_buf.s_raw_buf.au4_strd[1] * (i4_mb_y * BLK8x8SIZE);
1338 pu1_dst = ps_proc->pu1_src_buf_chroma;
1339
1340 /* Last MB row of chroma is copied unconditionally, since trans functions access an extra byte
1341 * due to interleaved input
1342 */
Martin Storsjof7682972015-06-16 21:30:36 +02001343 if (ps_proc->i4_mb_y == (ps_proc->i4_ht_mbs - 1))
1344 num_rows = (ps_codec->s_cfg.u4_disp_ht >> 1) - (ps_proc->i4_mb_y * BLK8x8SIZE);
1345 else
1346 num_rows = BLK8x8SIZE;
Harish Mahendrakar5cdb8882015-06-09 17:48:53 +05301347 for (i = 0; i < num_rows; i++)
1348 {
Suyog Pawarb483f222022-10-07 17:42:45 +05301349 memcpy(pu1_dst, pu1_src, ps_codec->s_cfg.u4_disp_wd);
Harish Mahendrakar5cdb8882015-06-09 17:48:53 +05301350 pu1_src += ps_proc->s_inp_buf.s_raw_buf.au4_strd[1];
Martin Storsjo53c68782015-06-09 16:25:51 +03001351 pu1_dst += ps_proc->i4_src_chroma_strd;
Harish Mahendrakar5cdb8882015-06-09 17:48:53 +05301352 }
1353
1354 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301355 break;
1356
1357 case IV_YUV_420P :
1358 pu1_y_buf_base = (UWORD8 *)ps_proc->s_inp_buf.s_raw_buf.apv_bufs[0] + (i4_mb_x * MB_SIZE) +
1359 ps_proc->s_inp_buf.s_raw_buf.au4_strd[0] * (i4_mb_y * MB_SIZE);
1360
1361 pu1_u_buf_base = (UWORD8 *)ps_proc->s_inp_buf.s_raw_buf.apv_bufs[1] + (i4_mb_x * BLK8x8SIZE) +
1362 ps_proc->s_inp_buf.s_raw_buf.au4_strd[1] * (i4_mb_y * BLK8x8SIZE);
1363
1364 pu1_v_buf_base = (UWORD8 *)ps_proc->s_inp_buf.s_raw_buf.apv_bufs[2] + (i4_mb_x * BLK8x8SIZE) +
1365 ps_proc->s_inp_buf.s_raw_buf.au4_strd[2] * (i4_mb_y * BLK8x8SIZE);
1366
1367 ps_codec->pf_ih264e_conv_420p_to_420sp(
1368 pu1_y_buf_base, pu1_u_buf_base, pu1_v_buf_base,
1369 ps_proc->pu1_src_buf_luma,
Harish Mahendrakarc72323e2015-04-28 19:07:40 +05301370 ps_proc->pu1_src_buf_chroma, u2_num_rows,
1371 ps_codec->s_cfg.u4_disp_wd,
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301372 ps_proc->s_inp_buf.s_raw_buf.au4_strd[0],
1373 ps_proc->s_inp_buf.s_raw_buf.au4_strd[1],
1374 ps_proc->s_inp_buf.s_raw_buf.au4_strd[2],
Martin Storsjo53c68782015-06-09 16:25:51 +03001375 ps_proc->i4_src_strd, ps_proc->i4_src_chroma_strd,
Harish Mahendrakarc72323e2015-04-28 19:07:40 +05301376 convert_uv_only);
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301377 break;
1378
1379 case IV_YUV_422ILE :
1380 pu1_y_buf_base = (UWORD8 *)ps_proc->s_inp_buf.s_raw_buf.apv_bufs[0] + (i4_mb_x * MB_SIZE * 2)
1381 + ps_proc->s_inp_buf.s_raw_buf.au4_strd[0] * (i4_mb_y * MB_SIZE);
1382
1383 ps_codec->pf_ih264e_fmt_conv_422i_to_420sp(
1384 ps_proc->pu1_src_buf_luma,
1385 ps_proc->pu1_src_buf_chroma,
1386 ps_proc->pu1_src_buf_chroma + 1, pu1_y_buf_base,
Harish Mahendrakarc72323e2015-04-28 19:07:40 +05301387 ps_codec->s_cfg.u4_disp_wd, u2_num_rows,
Martin Storsjo53c68782015-06-09 16:25:51 +03001388 ps_proc->i4_src_strd, ps_proc->i4_src_chroma_strd,
1389 ps_proc->i4_src_chroma_strd,
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301390 ps_proc->s_inp_buf.s_raw_buf.au4_strd[0] >> 1);
1391 break;
1392
1393 default:
1394 break;
1395 }
1396
Martin Storsjof7682972015-06-16 21:30:36 +02001397 if (u4_pad_right_sz && (ps_proc->i4_mb_x == 0))
Harish Mahendrakarc72323e2015-04-28 19:07:40 +05301398 {
1399 UWORD32 u4_pad_wd, u4_pad_ht;
1400 u4_pad_wd = (UWORD32)(ps_proc->i4_src_strd - ps_codec->s_cfg.u4_disp_wd);
1401 u4_pad_wd = MIN(u4_pad_right_sz, u4_pad_wd);
1402 u4_pad_ht = MB_SIZE;
1403 if(ps_proc->i4_mb_y == ps_proc->i4_ht_mbs - 1)
1404 u4_pad_ht = MIN(MB_SIZE, (MB_SIZE - u4_pad_bottom_sz));
1405
1406 ih264_pad_right_luma(
1407 ps_proc->pu1_src_buf_luma + ps_codec->s_cfg.u4_disp_wd,
1408 ps_proc->i4_src_strd, u4_pad_ht, u4_pad_wd);
1409
1410 ih264_pad_right_chroma(
1411 ps_proc->pu1_src_buf_chroma + ps_codec->s_cfg.u4_disp_wd,
Martin Storsjo53c68782015-06-09 16:25:51 +03001412 ps_proc->i4_src_chroma_strd, u4_pad_ht / 2, u4_pad_wd);
Harish Mahendrakarc72323e2015-04-28 19:07:40 +05301413 }
1414
Neelkamal Semwal646a58c2021-04-01 12:52:14 +05301415 if (ps_proc->i4_mb_y && ps_proc->i4_mb_y == ps_proc->i4_ht_mbs - 1) {
1416 UWORD8 *pu1_src = (UWORD8 *)ps_proc->s_inp_buf.s_raw_buf.apv_bufs[0] +
1417 ps_proc->s_inp_buf.s_raw_buf.au4_strd[0] * (i4_mb_y * MB_SIZE) -
1418 ps_proc->s_inp_buf.s_raw_buf.au4_strd[0];
1419 UWORD8 *pu1_dst = ps_proc->pu1_src_buf_luma - ps_proc->i4_src_strd;
Suyog Pawarb483f222022-10-07 17:42:45 +05301420 memcpy(pu1_dst, pu1_src, ps_codec->s_cfg.u4_disp_wd);
Neelkamal Semwal646a58c2021-04-01 12:52:14 +05301421 if (u4_pad_right_sz && (ps_proc->i4_mb_x == 0)) {
1422 pu1_dst += ps_codec->s_cfg.u4_disp_wd;
1423 memset(pu1_dst, pu1_dst[-1], u4_pad_right_sz);
1424 }
1425 }
1426
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301427 /* pad bottom edge */
1428 if (u4_pad_bottom_sz && (ps_proc->i4_mb_y == ps_proc->i4_ht_mbs - 1) && ps_proc->i4_mb_x == 0)
1429 {
1430 ih264_pad_bottom(ps_proc->pu1_src_buf_luma + (MB_SIZE - u4_pad_bottom_sz) * ps_proc->i4_src_strd,
Harish Mahendrakarc72323e2015-04-28 19:07:40 +05301431 ps_proc->i4_src_strd, ps_proc->i4_src_strd, u4_pad_bottom_sz);
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301432
Martin Storsjo53c68782015-06-09 16:25:51 +03001433 ih264_pad_bottom(ps_proc->pu1_src_buf_chroma + (MB_SIZE - u4_pad_bottom_sz) * ps_proc->i4_src_chroma_strd / 2,
1434 ps_proc->i4_src_chroma_strd, ps_proc->i4_src_chroma_strd, (u4_pad_bottom_sz / 2));
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301435 }
1436
Harish Mahendrakarc72323e2015-04-28 19:07:40 +05301437
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301438 /* packed mb coeff data */
1439 ps_proc->pv_mb_coeff_data = ((UWORD8 *)ps_proc->pv_pic_mb_coeff_data) + i4_mb_y * ps_codec->u4_size_coeff_data;
1440
1441 /* packed mb header data */
1442 ps_proc->pv_mb_header_data = ((UWORD8 *)ps_proc->pv_pic_mb_header_data) + i4_mb_y * ps_codec->u4_size_header_data;
1443
1444 /* slice index */
1445 ps_proc->i4_cur_slice_idx = ps_proc->pu1_slice_idx[i4_mb_y * ps_proc->i4_wd_mbs + i4_mb_x];
1446
1447 /*********************************************************************/
1448 /* ih264e_init_quant_params() routine is called at the pic init level*/
1449 /* this would have initialized the qp. */
1450 /* TODO_LATER: currently it is assumed that quant params donot change*/
1451 /* across mb's. When they do calculate update ps_qp_params accordingly*/
1452 /*********************************************************************/
1453
1454 /* init mv buffer ptr */
Harinarayanan K K6cb67722015-06-19 14:44:42 +05301455 ps_proc->ps_pu = ps_cur_mv_buf->ps_pic_pu + (i4_mb_y * ps_proc->i4_wd_mbs *
1456 ((MB_SIZE * MB_SIZE) / (ENC_MIN_PU_SIZE * ENC_MIN_PU_SIZE)));
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301457
Harinarayanan K K134291e2015-06-18 16:03:38 +05301458 /* Init co-located mv buffer */
Harinarayanan K K6cb67722015-06-19 14:44:42 +05301459 ps_proc->ps_colpu = ps_proc->aps_mv_buf[1]->ps_pic_pu + (i4_mb_y * ps_proc->i4_wd_mbs *
1460 ((MB_SIZE * MB_SIZE) / (ENC_MIN_PU_SIZE * ENC_MIN_PU_SIZE)));
Harinarayanan K K134291e2015-06-18 16:03:38 +05301461
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301462 if (i4_mb_y == 0)
1463 {
1464 ps_proc->ps_top_row_pu_ME = ps_cur_mv_buf->ps_pic_pu;
1465 }
1466 else
1467 {
Harinarayanan K K6cb67722015-06-19 14:44:42 +05301468 ps_proc->ps_top_row_pu_ME = ps_cur_mv_buf->ps_pic_pu + ((i4_mb_y - 1) * ps_proc->i4_wd_mbs *
1469 ((MB_SIZE * MB_SIZE) / (ENC_MIN_PU_SIZE * ENC_MIN_PU_SIZE)));
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301470 }
1471
1472 ps_proc->pu4_mb_pu_cnt = ps_cur_mv_buf->pu4_mb_pu_cnt + (i4_mb_y * ps_proc->i4_wd_mbs);
1473
1474 /* mb type */
1475 ps_proc->u4_mb_type = I16x16;
1476
1477 /* lambda */
1478 ps_proc->u4_lambda = gu1_qp0[ps_qp_params->u1_mb_qp];
1479
1480 /* mb distortion */
1481 ps_proc->i4_mb_distortion = SHRT_MAX;
1482
1483 if (i4_mb_x == 0)
1484 {
1485 ps_proc->s_left_mb_syntax_ele.i4_mb_distortion = 0;
1486
1487 ps_proc->s_top_left_mb_syntax_ele.i4_mb_distortion = 0;
1488
1489 ps_proc->s_top_left_mb_syntax_ME.i4_mb_distortion = 0;
1490
1491 if (i4_mb_y == 0)
1492 {
1493 memset(ps_proc->ps_top_row_mb_syntax_ele, 0, (ps_proc->i4_wd_mbs + 1)*sizeof(mb_info_t));
1494 }
1495 }
1496
1497 /* mb cost */
1498 ps_proc->i4_mb_cost = INT_MAX;
1499
1500 /**********************/
1501 /* init deblk context */
1502 /**********************/
1503 ps_deblk->i4_mb_x = ps_proc->i4_mb_x;
1504 /* deblk lags the current mb proc by 1 row */
1505 /* NOTE: Intra prediction has to happen with non deblocked samples used as reference */
1506 /* Hence to deblk MB 0 of row 0, you have wait till MB 0 of row 1 is encoded. */
1507 /* For simplicity, we chose to lag deblking by 1 Row wrt to proc */
1508 ps_deblk->i4_mb_y = ps_proc->i4_mb_y - 1;
1509
1510 /* buffer ptrs */
1511 ps_deblk->pu1_cur_pic_luma = ps_proc->pu1_rec_buf_luma_base + i4_rec_strd * (ps_deblk->i4_mb_y * MB_SIZE);
1512 ps_deblk->pu1_cur_pic_chroma = ps_proc->pu1_rec_buf_chroma_base + i4_rec_strd * (ps_deblk->i4_mb_y * BLK8x8SIZE);
1513
1514 /* init deblk bs context */
1515 /* mb indices */
1516 ps_bs->i4_mb_x = ps_proc->i4_mb_x;
1517 ps_bs->i4_mb_y = ps_proc->i4_mb_y;
1518
1519 /* init n_mb_process context */
1520 ps_n_mb_ctxt->i4_mb_x = 0;
1521 ps_n_mb_ctxt->i4_mb_y = ps_deblk->i4_mb_y;
1522 ps_n_mb_ctxt->i4_n_mbs = ps_proc->i4_nmb_ntrpy;
1523
1524 return IH264E_SUCCESS;
1525}
1526
1527/**
1528*******************************************************************************
1529*
1530* @brief This function performs luma & chroma padding
1531*
1532* @par Description:
1533*
1534* @param[in] ps_proc
1535* Process context corresponding to the job
1536*
1537* @param[in] pu1_curr_pic_luma
1538* Pointer to luma buffer
1539*
1540* @param[in] pu1_curr_pic_chroma
1541* Pointer to chroma buffer
1542*
1543* @param[in] i4_mb_x
1544* mb index x
1545*
1546* @param[in] i4_mb_y
1547* mb index y
1548*
1549* @param[in] i4_pad_ht
1550* number of rows to be padded
1551*
1552* @returns error status
1553*
1554* @remarks none
1555*
1556*******************************************************************************
1557*/
1558IH264E_ERROR_T ih264e_pad_recon_buffer(process_ctxt_t *ps_proc,
1559 UWORD8 *pu1_curr_pic_luma,
1560 UWORD8 *pu1_curr_pic_chroma,
1561 WORD32 i4_mb_x,
1562 WORD32 i4_mb_y,
1563 WORD32 i4_pad_ht)
1564{
1565 /* codec context */
1566 codec_t *ps_codec = ps_proc->ps_codec;
1567
1568 /* strides */
1569 WORD32 i4_rec_strd = ps_proc->i4_rec_strd;
1570
1571 if (i4_mb_x == 0)
1572 {
1573 /* padding left luma */
1574 ps_codec->pf_pad_left_luma(pu1_curr_pic_luma, i4_rec_strd, i4_pad_ht, PAD_LEFT);
1575
1576 /* padding left chroma */
1577 ps_codec->pf_pad_left_chroma(pu1_curr_pic_chroma, i4_rec_strd, i4_pad_ht >> 1, PAD_LEFT);
1578 }
Harish Mahendrakarc72323e2015-04-28 19:07:40 +05301579 if (i4_mb_x == ps_proc->i4_wd_mbs - 1)
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301580 {
1581 /* padding right luma */
1582 ps_codec->pf_pad_right_luma(pu1_curr_pic_luma + MB_SIZE, i4_rec_strd, i4_pad_ht, PAD_RIGHT);
1583
1584 /* padding right chroma */
1585 ps_codec->pf_pad_right_chroma(pu1_curr_pic_chroma + MB_SIZE, i4_rec_strd, i4_pad_ht >> 1, PAD_RIGHT);
1586
1587 if (i4_mb_y == ps_proc->i4_ht_mbs - 1)
1588 {
1589 UWORD8 *pu1_rec_luma = pu1_curr_pic_luma + MB_SIZE + PAD_RIGHT + ((i4_pad_ht - 1) * i4_rec_strd);
1590 UWORD8 *pu1_rec_chroma = pu1_curr_pic_chroma + MB_SIZE + PAD_RIGHT + (((i4_pad_ht >> 1) - 1) * i4_rec_strd);
1591
1592 /* padding bottom luma */
1593 ps_codec->pf_pad_bottom(pu1_rec_luma, i4_rec_strd, i4_rec_strd, PAD_BOT);
1594
1595 /* padding bottom chroma */
1596 ps_codec->pf_pad_bottom(pu1_rec_chroma, i4_rec_strd, i4_rec_strd, (PAD_BOT >> 1));
1597 }
1598 }
1599
1600 if (i4_mb_y == 0)
1601 {
1602 UWORD8 *pu1_rec_luma = pu1_curr_pic_luma;
1603 UWORD8 *pu1_rec_chroma = pu1_curr_pic_chroma;
1604 WORD32 wd = MB_SIZE;
1605
1606 if (i4_mb_x == 0)
1607 {
1608 pu1_rec_luma -= PAD_LEFT;
1609 pu1_rec_chroma -= PAD_LEFT;
1610
1611 wd += PAD_LEFT;
1612 }
Harish Mahendrakarc72323e2015-04-28 19:07:40 +05301613 if (i4_mb_x == ps_proc->i4_wd_mbs - 1)
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301614 {
1615 wd += PAD_RIGHT;
1616 }
1617
1618 /* padding top luma */
1619 ps_codec->pf_pad_top(pu1_rec_luma, i4_rec_strd, wd, PAD_TOP);
1620
1621 /* padding top chroma */
1622 ps_codec->pf_pad_top(pu1_rec_chroma, i4_rec_strd, wd, (PAD_TOP >> 1));
1623 }
1624
1625 return IH264E_SUCCESS;
1626}
1627
1628
1629
1630
1631/**
1632*******************************************************************************
1633*
1634* @brief This function performs deblocking, padding and halfpel generation for
1635* 'n' MBs
1636*
1637* @par Description:
1638*
1639* @param[in] ps_proc
1640* Process context corresponding to the job
1641*
1642* @param[in] pu1_curr_pic_luma
1643* Current MB being processed(Luma)
1644*
1645* @param[in] pu1_curr_pic_chroma
1646* Current MB being processed(Chroma)
1647*
1648* @param[in] i4_mb_x
1649* Column value of current MB processed
1650*
1651* @param[in] i4_mb_y
1652* Curent row processed
1653*
1654* @returns error status
1655*
1656* @remarks none
1657*
1658*******************************************************************************
1659*/
1660IH264E_ERROR_T ih264e_dblk_pad_hpel_processing_n_mbs(process_ctxt_t *ps_proc,
1661 UWORD8 *pu1_curr_pic_luma,
1662 UWORD8 *pu1_curr_pic_chroma,
1663 WORD32 i4_mb_x,
1664 WORD32 i4_mb_y)
1665{
1666 /* codec context */
1667 codec_t *ps_codec = ps_proc->ps_codec;
1668
1669 /* n_mb processing context */
1670 n_mb_process_ctxt_t *ps_n_mb_ctxt = &ps_proc->s_n_mb_ctxt;
1671
1672 /* deblk context */
1673 deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
1674
1675 /* strides */
1676 WORD32 i4_rec_strd = ps_proc->i4_rec_strd;
1677
1678 /* loop variables */
1679 WORD32 row, i, j, col;
1680
1681 /* Padding Width */
1682 UWORD32 u4_pad_wd;
1683
1684 /* deblk_map of the row being deblocked */
1685 UWORD8 *pu1_deblk_map = ps_proc->pu1_deblk_map + ps_deblk->i4_mb_y * ps_proc->i4_wd_mbs;
1686
1687 /* deblk_map_previous row */
1688 UWORD8 *pu1_deblk_map_prev_row = pu1_deblk_map - ps_proc->i4_wd_mbs;
1689
1690 WORD32 u4_pad_top = 0;
1691
1692 WORD32 u4_deblk_prev_row = 0;
1693
1694 /* Number of mbs to be processed */
1695 WORD32 i4_n_mbs = ps_n_mb_ctxt->i4_n_mbs;
1696
1697 /* Number of mbs actually processed
1698 * (at the end of a row, when remaining number of MBs are less than i4_n_mbs) */
1699 WORD32 i4_n_mb_process_count = 0;
1700
1701 UWORD8 *pu1_pad_bottom_src = NULL;
1702
1703 UWORD8 *pu1_pad_src_luma = NULL;
1704 UWORD8 *pu1_pad_src_chroma = NULL;
1705
1706 if (ps_proc->u4_disable_deblock_level == 1)
1707 {
1708 /* If left most MB is processed, then pad left */
1709 if (i4_mb_x == 0)
1710 {
1711 /* padding left luma */
1712 ps_codec->pf_pad_left_luma(pu1_curr_pic_luma, i4_rec_strd, MB_SIZE, PAD_LEFT);
1713
1714 /* padding left chroma */
1715 ps_codec->pf_pad_left_chroma(pu1_curr_pic_chroma, i4_rec_strd, MB_SIZE >> 1, PAD_LEFT);
1716 }
1717 /*last col*/
1718 if (i4_mb_x == (ps_proc->i4_wd_mbs - 1))
1719 {
1720 /* padding right luma */
1721 ps_codec->pf_pad_right_luma(pu1_curr_pic_luma + MB_SIZE, i4_rec_strd, MB_SIZE, PAD_RIGHT);
1722
1723 /* padding right chroma */
1724 ps_codec->pf_pad_right_chroma(pu1_curr_pic_chroma + MB_SIZE, i4_rec_strd, MB_SIZE >> 1, PAD_RIGHT);
1725 }
1726 }
1727
Harish Mahendrakarc72323e2015-04-28 19:07:40 +05301728 if ((i4_mb_y > 0) || (i4_mb_y == (ps_proc->i4_ht_mbs - 1)))
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301729 {
1730 /* if number of mb's to be processed are less than 'N', go back.
1731 * exception to the above clause is end of row */
1732 if ( ((i4_mb_x - (ps_n_mb_ctxt->i4_mb_x - 1)) < i4_n_mbs) && (i4_mb_x < (ps_proc->i4_wd_mbs - 1)) )
1733 {
1734 return IH264E_SUCCESS;
1735 }
1736 else
1737 {
1738 i4_n_mb_process_count = MIN(i4_mb_x - (ps_n_mb_ctxt->i4_mb_x - 1), i4_n_mbs);
1739
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301740 /* performing deblocking for required number of MBs */
Harish Mahendrakarc72323e2015-04-28 19:07:40 +05301741 if ((i4_mb_y > 0) && (ps_proc->u4_disable_deblock_level != 1))
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301742 {
Martin Storsjo1bc67422015-05-25 15:31:26 +03001743 u4_deblk_prev_row = 1;
1744
1745 /* checking whether the top rows are deblocked */
1746 for (col = 0; col < i4_n_mb_process_count; col++)
1747 {
1748 u4_deblk_prev_row &= pu1_deblk_map_prev_row[ps_deblk->i4_mb_x + col];
1749 }
1750
1751 /* checking whether the top right MB is deblocked */
1752 if ((ps_deblk->i4_mb_x + i4_n_mb_process_count) != ps_proc->i4_wd_mbs)
1753 {
1754 u4_deblk_prev_row &= pu1_deblk_map_prev_row[ps_deblk->i4_mb_x + i4_n_mb_process_count];
1755 }
1756
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301757 /* Top or Top right MBs not deblocked */
Harish Mahendrakarc72323e2015-04-28 19:07:40 +05301758 if ((u4_deblk_prev_row != 1) && (i4_mb_y > 0))
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301759 {
1760 return IH264E_SUCCESS;
1761 }
1762
1763 for (row = 0; row < i4_n_mb_process_count; row++)
1764 {
1765 ih264e_deblock_mb(ps_proc, ps_deblk);
1766
1767 pu1_deblk_map[ps_deblk->i4_mb_x] = 1;
1768
1769 if (ps_deblk->i4_mb_y > 0)
1770 {
1771 if (ps_deblk->i4_mb_x == 0)/* If left most MB is processed, then pad left*/
1772 {
1773 /* padding left luma */
1774 ps_codec->pf_pad_left_luma(ps_deblk->pu1_cur_pic_luma - i4_rec_strd * MB_SIZE, i4_rec_strd, MB_SIZE, PAD_LEFT);
1775
1776 /* padding left chroma */
1777 ps_codec->pf_pad_left_chroma(ps_deblk->pu1_cur_pic_chroma - i4_rec_strd * BLK8x8SIZE, i4_rec_strd, MB_SIZE >> 1, PAD_LEFT);
1778 }
1779
1780 if (ps_deblk->i4_mb_x == (ps_proc->i4_wd_mbs - 1))/*last column*/
1781 {
1782 /* padding right luma */
1783 ps_codec->pf_pad_right_luma(ps_deblk->pu1_cur_pic_luma - i4_rec_strd * MB_SIZE + MB_SIZE, i4_rec_strd, MB_SIZE, PAD_RIGHT);
1784
1785 /* padding right chroma */
1786 ps_codec->pf_pad_right_chroma(ps_deblk->pu1_cur_pic_chroma - i4_rec_strd * BLK8x8SIZE + MB_SIZE, i4_rec_strd, MB_SIZE >> 1, PAD_RIGHT);
1787 }
1788 }
1789 ps_deblk->i4_mb_x++;
1790
1791 ps_deblk->pu1_cur_pic_luma += MB_SIZE;
1792 ps_deblk->pu1_cur_pic_chroma += MB_SIZE;
1793
1794 }
1795 }
Harish Mahendrakarc72323e2015-04-28 19:07:40 +05301796 else if(i4_mb_y > 0)
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301797 {
1798 ps_deblk->i4_mb_x += i4_n_mb_process_count;
1799
1800 ps_deblk->pu1_cur_pic_luma += i4_n_mb_process_count * MB_SIZE;
1801 ps_deblk->pu1_cur_pic_chroma += i4_n_mb_process_count * MB_SIZE;
1802 }
1803
1804 if (i4_mb_y == 2)
1805 {
1806 u4_pad_wd = i4_n_mb_process_count * MB_SIZE;
1807 u4_pad_top = ps_n_mb_ctxt->i4_mb_x * MB_SIZE;
1808
1809 if (ps_n_mb_ctxt->i4_mb_x == 0)
1810 {
1811 u4_pad_wd += PAD_LEFT;
1812 u4_pad_top = -PAD_LEFT;
1813 }
1814
1815 if (i4_mb_x == ps_proc->i4_wd_mbs - 1)
1816 {
1817 u4_pad_wd += PAD_RIGHT;
1818 }
1819
1820 /* padding top luma */
1821 ps_codec->pf_pad_top(ps_proc->pu1_rec_buf_luma_base + u4_pad_top, i4_rec_strd, u4_pad_wd, PAD_TOP);
1822
1823 /* padding top chroma */
1824 ps_codec->pf_pad_top(ps_proc->pu1_rec_buf_chroma_base + u4_pad_top, i4_rec_strd, u4_pad_wd, (PAD_TOP >> 1));
1825 }
1826
1827 ps_n_mb_ctxt->i4_mb_x += i4_n_mb_process_count;
1828
1829 if (i4_mb_x == ps_proc->i4_wd_mbs - 1)
1830 {
1831 if (ps_proc->i4_mb_y == ps_proc->i4_ht_mbs - 1)
1832 {
1833 /* Bottom Padding is done in one stretch for the entire width */
1834 if (ps_proc->u4_disable_deblock_level != 1)
1835 {
1836 ps_deblk->pu1_cur_pic_luma = ps_proc->pu1_rec_buf_luma_base + (ps_proc->i4_ht_mbs - 1) * i4_rec_strd * MB_SIZE;
1837
1838 ps_deblk->pu1_cur_pic_chroma = ps_proc->pu1_rec_buf_chroma_base + (ps_proc->i4_ht_mbs - 1) * i4_rec_strd * BLK8x8SIZE;
1839
1840 ps_n_mb_ctxt->i4_mb_x = 0;
1841 ps_n_mb_ctxt->i4_mb_y = ps_proc->i4_mb_y;
1842 ps_deblk->i4_mb_x = 0;
1843 ps_deblk->i4_mb_y = ps_proc->i4_mb_y;
1844
1845 /* update pic qp map (as update_proc_ctxt is still not called for the last MB) */
1846 ps_proc->s_deblk_ctxt.s_bs_ctxt.pu1_pic_qp[(i4_mb_y * ps_proc->i4_wd_mbs) + i4_mb_x] = ps_proc->u4_mb_qp;
1847
1848 i4_n_mb_process_count = (ps_proc->i4_wd_mbs) % i4_n_mbs;
1849
1850 j = (ps_proc->i4_wd_mbs) / i4_n_mbs;
1851
1852 for (i = 0; i < j; i++)
1853 {
1854 for (col = 0; col < i4_n_mbs; col++)
1855 {
1856 ih264e_deblock_mb(ps_proc, ps_deblk);
1857
1858 pu1_deblk_map[ps_deblk->i4_mb_x] = 1;
1859
1860 ps_deblk->i4_mb_x++;
1861 ps_deblk->pu1_cur_pic_luma += MB_SIZE;
1862 ps_deblk->pu1_cur_pic_chroma += MB_SIZE;
1863 ps_n_mb_ctxt->i4_mb_x++;
1864 }
1865 }
1866
1867 for (col = 0; col < i4_n_mb_process_count; col++)
1868 {
1869 ih264e_deblock_mb(ps_proc, ps_deblk);
1870
1871 pu1_deblk_map[ps_deblk->i4_mb_x] = 1;
1872
1873 ps_deblk->i4_mb_x++;
1874 ps_deblk->pu1_cur_pic_luma += MB_SIZE;
1875 ps_deblk->pu1_cur_pic_chroma += MB_SIZE;
1876 ps_n_mb_ctxt->i4_mb_x++;
1877 }
1878
1879 pu1_pad_src_luma = ps_proc->pu1_rec_buf_luma_base + (ps_proc->i4_ht_mbs - 2) * MB_SIZE * i4_rec_strd;
1880
1881 pu1_pad_src_chroma = ps_proc->pu1_rec_buf_chroma_base + (ps_proc->i4_ht_mbs - 2) * BLK8x8SIZE * i4_rec_strd;
1882
1883 /* padding left luma */
1884 ps_codec->pf_pad_left_luma(pu1_pad_src_luma, i4_rec_strd, MB_SIZE, PAD_LEFT);
1885
1886 /* padding left chroma */
1887 ps_codec->pf_pad_left_chroma(pu1_pad_src_chroma, i4_rec_strd, BLK8x8SIZE, PAD_LEFT);
1888
1889 pu1_pad_src_luma += i4_rec_strd * MB_SIZE;
1890 pu1_pad_src_chroma += i4_rec_strd * BLK8x8SIZE;
1891
1892 /* padding left luma */
1893 ps_codec->pf_pad_left_luma(pu1_pad_src_luma, i4_rec_strd, MB_SIZE, PAD_LEFT);
1894
1895 /* padding left chroma */
1896 ps_codec->pf_pad_left_chroma(pu1_pad_src_chroma, i4_rec_strd, BLK8x8SIZE, PAD_LEFT);
1897
1898 pu1_pad_src_luma = ps_proc->pu1_rec_buf_luma_base + (ps_proc->i4_ht_mbs - 2) * MB_SIZE * i4_rec_strd + (ps_proc->i4_wd_mbs) * MB_SIZE;
1899
1900 pu1_pad_src_chroma = ps_proc->pu1_rec_buf_chroma_base + (ps_proc->i4_ht_mbs - 2) * BLK8x8SIZE * i4_rec_strd + (ps_proc->i4_wd_mbs) * MB_SIZE;
1901
1902 /* padding right luma */
1903 ps_codec->pf_pad_right_luma(pu1_pad_src_luma, i4_rec_strd, MB_SIZE, PAD_RIGHT);
1904
1905 /* padding right chroma */
1906 ps_codec->pf_pad_right_chroma(pu1_pad_src_chroma, i4_rec_strd, BLK8x8SIZE, PAD_RIGHT);
1907
1908 pu1_pad_src_luma += i4_rec_strd * MB_SIZE;
1909 pu1_pad_src_chroma += i4_rec_strd * BLK8x8SIZE;
1910
1911 /* padding right luma */
1912 ps_codec->pf_pad_right_luma(pu1_pad_src_luma, i4_rec_strd, MB_SIZE, PAD_RIGHT);
1913
1914 /* padding right chroma */
1915 ps_codec->pf_pad_right_chroma(pu1_pad_src_chroma, i4_rec_strd, BLK8x8SIZE, PAD_RIGHT);
1916
1917 }
1918
Harish Mahendrakarc72323e2015-04-28 19:07:40 +05301919 /* In case height is less than 2 MBs pad top */
1920 if (ps_proc->i4_ht_mbs <= 2)
1921 {
1922 UWORD8 *pu1_pad_top_src;
1923 /* padding top luma */
1924 pu1_pad_top_src = ps_proc->pu1_rec_buf_luma_base - PAD_LEFT;
1925 ps_codec->pf_pad_top(pu1_pad_top_src, i4_rec_strd, i4_rec_strd, PAD_TOP);
1926
1927 /* padding top chroma */
1928 pu1_pad_top_src = ps_proc->pu1_rec_buf_chroma_base - PAD_LEFT;
1929 ps_codec->pf_pad_top(pu1_pad_top_src, i4_rec_strd, i4_rec_strd, (PAD_TOP >> 1));
1930 }
1931
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301932 /* padding bottom luma */
1933 pu1_pad_bottom_src = ps_proc->pu1_rec_buf_luma_base + ps_proc->i4_ht_mbs * MB_SIZE * i4_rec_strd - PAD_LEFT;
1934 ps_codec->pf_pad_bottom(pu1_pad_bottom_src, i4_rec_strd, i4_rec_strd, PAD_BOT);
1935
1936 /* padding bottom chroma */
1937 pu1_pad_bottom_src = ps_proc->pu1_rec_buf_chroma_base + ps_proc->i4_ht_mbs * (MB_SIZE >> 1) * i4_rec_strd - PAD_LEFT;
1938 ps_codec->pf_pad_bottom(pu1_pad_bottom_src, i4_rec_strd, i4_rec_strd, (PAD_BOT >> 1));
1939 }
1940 }
1941 }
1942 }
1943
1944 return IH264E_SUCCESS;
1945}
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 cost
1956* is selected and using intra/inter prediction filters, prediction is carried out.
1957* The deviation between src and pred signal constitutes error signal. This error
1958* signal is transformed (hierarchical transform if necessary) and quantized. The
1959* quantized residue is packed in to entropy buffer for entropy coding. This is
1960* 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*/
1971WORD32 ih264e_process(process_ctxt_t *ps_proc)
1972{
1973 /* error status */
1974 WORD32 error_status = IH264_SUCCESS;
1975
1976 /* codec context */
1977 codec_t *ps_codec = ps_proc->ps_codec;
1978
1979 /* cbp luma, chroma */
1980 UWORD32 u4_cbp_l, u4_cbp_c;
1981
1982 /* width in mbs */
1983 WORD32 i4_wd_mbs = ps_proc->i4_wd_mbs;
1984
1985 /* loop var */
1986 WORD32 i4_mb_idx, i4_mb_cnt = ps_proc->i4_mb_cnt;
1987
1988 /* valid modes */
1989 UWORD32 u4_valid_modes = 0;
1990
1991 /* gate threshold */
1992 WORD32 i4_gate_threshold = 0;
1993
1994 /* is intra */
1995 WORD32 luma_idx, chroma_idx, is_intra;
1996
1997 /* temp variables */
Harinarayanan K K6cb67722015-06-19 14:44:42 +05301998 WORD32 ctxt_sel = ps_proc->i4_encode_api_call_cnt % MAX_CTXT_SETS;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05301999
Harinarayanan K K85883032015-06-19 11:39:42 +05302000 /*
2001 * list of modes for evaluation
2002 * -------------------------------------------------------------------------
2003 * Note on enabling I4x4 and I16x16
2004 * At very low QP's the hadamard transform in I16x16 will push up the maximum
2005 * coeff value very high. CAVLC may not be able to represent the value and
2006 * hence the stream may not be decodable in some clips.
2007 * Hence at low QPs, we will enable I4x4 and disable I16x16 irrespective of preset.
2008 */
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302009 if (ps_proc->i4_slice_type == ISLICE)
2010 {
Harinarayanan K K85883032015-06-19 11:39:42 +05302011 if (ps_proc->u4_frame_qp > 10)
2012 {
2013 /* enable intra 16x16 */
2014 u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_16x16 ? (1 << I16x16) : 0;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302015
Harinarayanan K K85883032015-06-19 11:39:42 +05302016 /* enable intra 8x8 */
2017 u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_8x8 ? (1 << I8x8) : 0;
2018 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302019
2020 /* enable intra 4x4 */
2021 u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_4x4 ? (1 << I4x4) : 0;
Harinarayanan K K85883032015-06-19 11:39:42 +05302022 u4_valid_modes |= (ps_proc->u4_frame_qp <= 10) << I4x4;
2023
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302024 }
2025 else if (ps_proc->i4_slice_type == PSLICE)
2026 {
Harinarayanan K K85883032015-06-19 11:39:42 +05302027 if (ps_proc->u4_frame_qp > 10)
2028 {
2029 /* enable intra 16x16 */
2030 u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_16x16 ? (1 << I16x16) : 0;
2031 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302032
2033 /* enable intra 4x4 */
2034 if (ps_codec->s_cfg.u4_enc_speed_preset == IVE_SLOWEST)
2035 {
2036 u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_4x4 ? (1 << I4x4) : 0;
2037 }
Harinarayanan K K85883032015-06-19 11:39:42 +05302038 u4_valid_modes |= (ps_proc->u4_frame_qp <= 10) << I4x4;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302039
Harinarayanan K K134291e2015-06-18 16:03:38 +05302040 /* enable inter P16x16 */
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302041 u4_valid_modes |= (1 << P16x16);
2042 }
Harinarayanan K K134291e2015-06-18 16:03:38 +05302043 else if (ps_proc->i4_slice_type == BSLICE)
2044 {
Harinarayanan K K85883032015-06-19 11:39:42 +05302045 if (ps_proc->u4_frame_qp > 10)
2046 {
2047 /* enable intra 16x16 */
2048 u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_16x16 ? (1 << I16x16) : 0;
2049 }
Harinarayanan K K134291e2015-06-18 16:03:38 +05302050
2051 /* enable intra 4x4 */
2052 if (ps_codec->s_cfg.u4_enc_speed_preset == IVE_SLOWEST)
2053 {
2054 u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_4x4 ? (1 << I4x4) : 0;
2055 }
Harinarayanan K K85883032015-06-19 11:39:42 +05302056 u4_valid_modes |= (ps_proc->u4_frame_qp <= 10) << I4x4;
Harinarayanan K K134291e2015-06-18 16:03:38 +05302057
2058 /* enable inter B16x16 */
2059 u4_valid_modes |= (1 << B16x16);
2060 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302061
2062
2063 /* init entropy */
2064 ps_proc->s_entropy.i4_mb_x = ps_proc->i4_mb_x;
2065 ps_proc->s_entropy.i4_mb_y = ps_proc->i4_mb_y;
2066 ps_proc->s_entropy.i4_mb_cnt = MIN(ps_proc->i4_nmb_ntrpy, i4_wd_mbs - ps_proc->i4_mb_x);
2067
2068 /* compute recon when :
2069 * 1. current frame is to be used as a reference
2070 * 2. dump recon for bit stream sanity check
2071 */
2072 ps_proc->u4_compute_recon = ps_codec->u4_is_curr_frm_ref ||
2073 ps_codec->s_cfg.u4_enable_recon;
2074
2075 /* Encode 'n' macroblocks,
2076 * 'n' being the number of mbs dictated by current proc ctxt */
2077 for (i4_mb_idx = 0; i4_mb_idx < i4_mb_cnt; i4_mb_idx ++)
2078 {
2079 /* since we have not yet found sad, we have not yet got min sad */
2080 /* we need to initialize these variables for each MB */
2081 /* TODO how to get the min sad into the codec */
2082 ps_proc->u4_min_sad = ps_codec->s_cfg.i4_min_sad;
2083 ps_proc->u4_min_sad_reached = 0;
2084
2085 /* mb analysis */
2086 {
2087 /* temp var */
2088 WORD32 i4_mb_id = ps_proc->i4_mb_x + ps_proc->i4_mb_y * i4_wd_mbs;
2089
2090 /* force intra refresh ? */
2091 WORD32 i4_air_enable_inter = (ps_codec->s_cfg.e_air_mode == IVE_AIR_MODE_NONE) ||
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302092 (ps_codec->pu2_intr_rfrsh_map[i4_mb_id] != ps_codec->i4_air_pic_cnt);
2093
2094 /* evaluate inter 16x16 modes */
Harinarayanan K K134291e2015-06-18 16:03:38 +05302095 if ((u4_valid_modes & (1 << P16x16)) || (u4_valid_modes & (1 << B16x16)))
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302096 {
2097 /* compute nmb me */
2098 if (ps_proc->i4_mb_x % ps_proc->u4_nmb_me == 0)
2099 {
2100 ih264e_compute_me_nmb(ps_proc, MIN((WORD32)ps_proc->u4_nmb_me,
2101 i4_wd_mbs - ps_proc->i4_mb_x));
2102 }
2103
2104 /* set pointers to ME data appropriately for other modules to use */
2105 {
2106 UWORD32 u4_mb_index = ps_proc->i4_mb_x % ps_proc->u4_nmb_me ;
2107
2108 /* get the min sad condition for current mb */
2109 ps_proc->u4_min_sad_reached = ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad_reached;
2110 ps_proc->u4_min_sad = ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad;
2111
Harinarayanan K K134291e2015-06-18 16:03:38 +05302112 ps_proc->ps_skip_mv = &(ps_proc->ps_nmb_info[u4_mb_index].as_skip_mv[0]);
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302113 ps_proc->ps_ngbr_avbl = &(ps_proc->ps_nmb_info[u4_mb_index].s_ngbr_avbl);
Harinarayanan K K134291e2015-06-18 16:03:38 +05302114 ps_proc->ps_pred_mv = &(ps_proc->ps_nmb_info[u4_mb_index].as_pred_mv[0]);
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302115
2116 ps_proc->i4_mb_distortion = ps_proc->ps_nmb_info[u4_mb_index].i4_mb_distortion;
2117 ps_proc->i4_mb_cost = ps_proc->ps_nmb_info[u4_mb_index].i4_mb_cost;
2118 ps_proc->u4_min_sad = ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad;
2119 ps_proc->u4_min_sad_reached = ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad_reached;
2120 ps_proc->u4_mb_type = ps_proc->ps_nmb_info[u4_mb_index].u4_mb_type;
2121
2122 /* get the best sub pel buffer */
2123 ps_proc->pu1_best_subpel_buf = ps_proc->ps_nmb_info[u4_mb_index].pu1_best_sub_pel_buf;
2124 ps_proc->u4_bst_spel_buf_strd = ps_proc->ps_nmb_info[u4_mb_index].u4_bst_spel_buf_strd;
2125 }
2126 ih264e_derive_nghbr_avbl_of_mbs(ps_proc);
2127 }
2128 else
2129 {
2130 /* Derive neighbor availability for the current macroblock */
2131 ps_proc->ps_ngbr_avbl = &ps_proc->s_ngbr_avbl;
2132
2133 ih264e_derive_nghbr_avbl_of_mbs(ps_proc);
2134 }
2135
2136 /*
2137 * If air says intra, we need to force the following code path to evaluate intra
2138 * The easy way is just to say that the inter cost is too much
2139 */
2140 if (!i4_air_enable_inter)
2141 {
2142 ps_proc->u4_min_sad_reached = 0;
2143 ps_proc->i4_mb_cost = INT_MAX;
2144 ps_proc->i4_mb_distortion = INT_MAX;
2145 }
2146 else if (ps_proc->u4_mb_type == PSKIP)
2147 {
2148 goto UPDATE_MB_INFO;
2149 }
2150
2151 /* wait until the proc of [top + 1] mb is computed.
2152 * We wait till the proc dependencies are satisfied */
2153 if(ps_proc->i4_mb_y > 0)
2154 {
2155 /* proc map */
2156 UWORD8 *pu1_proc_map_top;
2157
2158 pu1_proc_map_top = ps_proc->pu1_proc_map + ((ps_proc->i4_mb_y - 1) * i4_wd_mbs);
2159
2160 while (1)
2161 {
2162 volatile UWORD8 *pu1_buf;
2163 WORD32 idx = i4_mb_idx + 1;
2164
2165 idx = MIN(idx, ((WORD32)ps_codec->s_cfg.i4_wd_mbs - 1));
2166 pu1_buf = pu1_proc_map_top + idx;
2167 if(*pu1_buf)
2168 break;
2169 ithread_yield();
2170 }
2171 }
2172
2173 /* If we already have the minimum sad, there is no point in searching for sad again */
Ram Mohan82fb2d32017-11-27 17:56:29 +05302174 if (ps_proc->u4_min_sad_reached == 0 || ps_codec->s_cfg.u4_enc_speed_preset != IVE_FASTEST)
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302175 {
2176 /* intra gating in inter slices */
2177 /* No need of gating if we want to force intra, we need to find the threshold only if inter is enabled by AIR*/
Harinarayanan K K134291e2015-06-18 16:03:38 +05302178 if (i4_air_enable_inter && ps_proc->i4_slice_type != ISLICE && ps_codec->u4_inter_gate)
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302179 {
2180 /* distortion of neighboring blocks */
2181 WORD32 i4_distortion[4];
2182
2183 i4_distortion[0] = ps_proc->s_left_mb_syntax_ele.i4_mb_distortion;
2184
2185 i4_distortion[1] = ps_proc->ps_top_row_mb_syntax_ele[ps_proc->i4_mb_x].i4_mb_distortion;
2186
2187 i4_distortion[2] = ps_proc->ps_top_row_mb_syntax_ele[ps_proc->i4_mb_x + 1].i4_mb_distortion;
2188
2189 i4_distortion[3] = ps_proc->s_top_left_mb_syntax_ele.i4_mb_distortion;
2190
2191 i4_gate_threshold = (i4_distortion[0] + i4_distortion[1] + i4_distortion[2] + i4_distortion[3]) >> 2;
2192
2193 }
2194
Harinarayanan K K134291e2015-06-18 16:03:38 +05302195
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302196 /* If we are going to force intra we need to evaluate intra irrespective of gating */
2197 if ( (!i4_air_enable_inter) || ((i4_gate_threshold + 16 *((WORD32) ps_proc->u4_lambda)) < ps_proc->i4_mb_distortion))
2198 {
2199 /* evaluate intra 4x4 modes */
2200 if (u4_valid_modes & (1 << I4x4))
2201 {
2202 if (ps_codec->s_cfg.u4_enc_speed_preset == IVE_SLOWEST)
2203 {
2204 ih264e_evaluate_intra4x4_modes_for_least_cost_rdopton(ps_proc);
2205 }
2206 else
2207 {
2208 ih264e_evaluate_intra4x4_modes_for_least_cost_rdoptoff(ps_proc);
2209 }
2210 }
2211
2212 /* evaluate intra 16x16 modes */
2213 if (u4_valid_modes & (1 << I16x16))
2214 {
2215 ih264e_evaluate_intra16x16_modes_for_least_cost_rdoptoff(ps_proc);
2216 }
2217
2218 /* evaluate intra 8x8 modes */
2219 if (u4_valid_modes & (1 << I8x8))
2220 {
2221 ih264e_evaluate_intra8x8_modes_for_least_cost_rdoptoff(ps_proc);
2222 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302223
Harinarayanan K K134291e2015-06-18 16:03:38 +05302224 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302225 }
Harinarayanan K K134291e2015-06-18 16:03:38 +05302226 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302227
2228 /* is intra */
2229 if (ps_proc->u4_mb_type == I4x4 || ps_proc->u4_mb_type == I16x16 || ps_proc->u4_mb_type == I8x8)
2230 {
2231 luma_idx = ps_proc->u4_mb_type;
2232 chroma_idx = 0;
2233 is_intra = 1;
2234
2235 /* evaluate chroma blocks for intra */
2236 ih264e_evaluate_chroma_intra8x8_modes_for_least_cost_rdoptoff(ps_proc);
2237 }
2238 else
2239 {
2240 luma_idx = 3;
2241 chroma_idx = 1;
2242 is_intra = 0;
2243 }
2244 ps_proc->u4_is_intra = is_intra;
Harinarayanan K K134291e2015-06-18 16:03:38 +05302245 ps_proc->ps_pu->b1_intra_flag = is_intra;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302246
2247 /* redo MV pred of neighbors in the case intra mb */
2248 /* TODO : currently called unconditionally, needs to be called only in the case of intra
2249 * to modify neighbors */
2250 if (ps_proc->i4_slice_type != ISLICE)
2251 {
Harinarayanan K K134291e2015-06-18 16:03:38 +05302252 ih264e_mv_pred(ps_proc, ps_proc->i4_slice_type);
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302253 }
2254
2255 /* Perform luma mb core coding */
2256 u4_cbp_l = (ps_codec->luma_energy_compaction)[luma_idx](ps_proc);
2257
2258 /* Perform luma mb core coding */
2259 u4_cbp_c = (ps_codec->chroma_energy_compaction)[chroma_idx](ps_proc);
2260
2261 /* coded block pattern */
2262 ps_proc->u4_cbp = (u4_cbp_c << 4) | u4_cbp_l;
2263
Harinarayanan K K134291e2015-06-18 16:03:38 +05302264 if (!ps_proc->u4_is_intra)
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302265 {
Harinarayanan K K134291e2015-06-18 16:03:38 +05302266 if (ps_proc->i4_slice_type == BSLICE)
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302267 {
Harinarayanan K K134291e2015-06-18 16:03:38 +05302268 if (ih264e_find_bskip_params(ps_proc, PRED_L0))
2269 {
2270 ps_proc->u4_mb_type = (ps_proc->u4_cbp) ? BDIRECT : BSKIP;
2271 }
2272 }
2273 else if(!ps_proc->u4_cbp)
2274 {
2275 if (ih264e_find_pskip_params(ps_proc, PRED_L0))
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302276 {
2277 ps_proc->u4_mb_type = PSKIP;
2278 }
2279 }
2280 }
2281
2282UPDATE_MB_INFO:
2283
2284 /* Update mb sad, mb qp and intra mb cost. Will be used by rate control */
2285 ih264e_update_rc_mb_info(&ps_proc->s_frame_info, ps_proc);
2286
2287 /**********************************************************************/
2288 /* if disable deblock level is '0' this implies enable deblocking for */
2289 /* all edges of all macroblocks with out any restrictions */
2290 /* */
2291 /* if disable deblock level is '1' this implies disable deblocking for*/
2292 /* all edges of all macroblocks with out any restrictions */
2293 /* */
2294 /* if disable deblock level is '2' this implies enable deblocking for */
2295 /* all edges of all macroblocks except edges overlapping with slice */
2296 /* boundaries. This option is not currently supported by the encoder */
2297 /* hence the slice map should be of no significance to perform debloc */
2298 /* king */
2299 /**********************************************************************/
2300
2301 if (ps_proc->u4_compute_recon)
2302 {
2303 /* deblk context */
2304 /* src pointers */
2305 UWORD8 *pu1_cur_pic_luma = ps_proc->pu1_rec_buf_luma;
2306 UWORD8 *pu1_cur_pic_chroma = ps_proc->pu1_rec_buf_chroma;
2307
2308 /* src indices */
2309 UWORD32 i4_mb_x = ps_proc->i4_mb_x;
2310 UWORD32 i4_mb_y = ps_proc->i4_mb_y;
2311
2312 /* compute blocking strength */
2313 if (ps_proc->u4_disable_deblock_level != 1)
2314 {
2315 ih264e_compute_bs(ps_proc);
2316 }
2317
2318 /* nmb deblocking and hpel and padding */
2319 ih264e_dblk_pad_hpel_processing_n_mbs(ps_proc, pu1_cur_pic_luma,
2320 pu1_cur_pic_chroma, i4_mb_x,
2321 i4_mb_y);
2322 }
2323
2324 /* update the context after for coding next mb */
Chamarthi Kishore95a21132019-10-11 18:53:50 +05302325 error_status = ih264e_update_proc_ctxt(ps_proc);
2326 if(error_status != IH264E_SUCCESS)
2327 {
2328 return error_status;
2329 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302330 /* Once the last row is processed, mark the buffer status appropriately */
2331 if (ps_proc->i4_ht_mbs == ps_proc->i4_mb_y)
2332 {
2333 /* Pointer to current picture buffer structure */
2334 pic_buf_t *ps_cur_pic = ps_proc->ps_cur_pic;
2335
2336 /* Pointer to current picture's mv buffer structure */
2337 mv_buf_t *ps_cur_mv_buf = ps_proc->ps_cur_mv_buf;
2338
2339 /**********************************************************************/
2340 /* if disable deblock level is '0' this implies enable deblocking for */
2341 /* all edges of all macroblocks with out any restrictions */
2342 /* */
2343 /* if disable deblock level is '1' this implies disable deblocking for*/
2344 /* all edges of all macroblocks with out any restrictions */
2345 /* */
2346 /* if disable deblock level is '2' this implies enable deblocking for */
2347 /* all edges of all macroblocks except edges overlapping with slice */
2348 /* boundaries. This option is not currently supported by the encoder */
2349 /* hence the slice map should be of no significance to perform debloc */
2350 /* king */
2351 /**********************************************************************/
Chamarthi Kishore95a21132019-10-11 18:53:50 +05302352 error_status = ih264_buf_mgr_release(ps_codec->pv_mv_buf_mgr,
2353 ps_cur_mv_buf->i4_buf_id , BUF_MGR_CODEC);
2354 if(error_status != IH264E_SUCCESS)
2355 {
2356 return error_status;
2357 }
2358 error_status = ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr,
2359 ps_cur_pic->i4_buf_id , BUF_MGR_CODEC);
2360 if(error_status != IH264E_SUCCESS)
2361 {
2362 return error_status;
2363 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302364 if (ps_codec->s_cfg.u4_enable_recon)
2365 {
2366 /* pic cnt */
2367 ps_codec->as_rec_buf[ctxt_sel].i4_pic_cnt = ps_proc->i4_pic_cnt;
2368
2369 /* rec buffers */
2370 ps_codec->as_rec_buf[ctxt_sel].s_pic_buf = *ps_proc->ps_cur_pic;
2371
2372 /* is last? */
2373 ps_codec->as_rec_buf[ctxt_sel].u4_is_last = ps_proc->s_entropy.u4_is_last;
2374
2375 /* frame time stamp */
2376 ps_codec->as_rec_buf[ctxt_sel].u4_timestamp_high = ps_proc->s_entropy.u4_timestamp_high;
2377 ps_codec->as_rec_buf[ctxt_sel].u4_timestamp_low = ps_proc->s_entropy.u4_timestamp_low;
2378 }
2379
2380 }
2381 }
2382
2383 DEBUG_HISTOGRAM_DUMP(ps_codec->s_cfg.i4_ht_mbs == ps_proc->i4_mb_y);
2384
2385 return error_status;
2386}
2387
2388/**
2389*******************************************************************************
2390*
2391* @brief
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302392* Function to update rc context after encoding
2393*
2394* @par Description
2395* This function updates the rate control context after the frame is encoded.
2396* Number of bits consumed by the current frame, frame distortion, frame cost,
2397* number of intra/inter mb's, ... are passed on to rate control context for
2398* updating the rc model.
2399*
2400* @param[in] ps_codec
2401* Handle to codec context
2402*
2403* @param[in] ctxt_sel
2404* frame context selector
2405*
2406* @param[in] pic_cnt
2407* pic count
2408*
2409* @returns i4_stuffing_byte
2410* number of stuffing bytes (if necessary)
2411*
2412* @remarks
2413*
2414*******************************************************************************
2415*/
Harinarayanan K K134291e2015-06-18 16:03:38 +05302416WORD32 ih264e_update_rc_post_enc(codec_t *ps_codec, WORD32 ctxt_sel, WORD32 i4_is_first_frm)
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302417{
2418 /* proc set base idx */
2419 WORD32 i4_proc_ctxt_sel_base = ctxt_sel ? (MAX_PROCESS_CTXT / 2) : 0;
2420
2421 /* proc ctxt */
2422 process_ctxt_t *ps_proc = &ps_codec->as_process[i4_proc_ctxt_sel_base];
2423
2424 /* frame qp */
2425 UWORD8 u1_frame_qp = ps_codec->u4_frame_qp;
2426
2427 /* cbr rc return status */
2428 WORD32 i4_stuffing_byte = 0;
2429
2430 /* current frame stats */
2431 frame_info_t s_frame_info;
2432 picture_type_e rc_pic_type;
2433
2434 /* temp var */
2435 WORD32 i, j;
2436
2437 /********************************************************************/
2438 /* BEGIN INIT */
2439 /********************************************************************/
2440
2441 /* init frame info */
2442 irc_init_frame_info(&s_frame_info);
2443
2444 /* get frame info */
2445 for (i = 0; i < (WORD32)ps_codec->s_cfg.u4_num_cores; i++)
2446 {
2447 /*****************************************************************/
2448 /* One frame can be encoded by max of u4_num_cores threads */
2449 /* Accumulating the num mbs, sad, qp and intra_mb_cost from */
2450 /* u4_num_cores threads */
2451 /*****************************************************************/
2452 for (j = 0; j< MAX_MB_TYPE; j++)
2453 {
2454 s_frame_info.num_mbs[j] += ps_proc[i].s_frame_info.num_mbs[j];
2455
2456 s_frame_info.tot_mb_sad[j] += ps_proc[i].s_frame_info.tot_mb_sad[j];
2457
2458 s_frame_info.qp_sum[j] += ps_proc[i].s_frame_info.qp_sum[j];
2459 }
2460
2461 s_frame_info.intra_mb_cost_sum += ps_proc[i].s_frame_info.intra_mb_cost_sum;
2462
2463 s_frame_info.activity_sum += ps_proc[i].s_frame_info.activity_sum;
2464
2465 /*****************************************************************/
2466 /* gather number of residue and header bits consumed by the frame*/
2467 /*****************************************************************/
2468 ih264e_update_rc_bits_info(&s_frame_info, &ps_proc[i].s_entropy);
2469 }
2470
2471 /* get pic type */
2472 switch (ps_codec->pic_type)
2473 {
2474 case PIC_I:
2475 case PIC_IDR:
2476 rc_pic_type = I_PIC;
2477 break;
2478 case PIC_P:
2479 rc_pic_type = P_PIC;
2480 break;
2481 case PIC_B:
2482 rc_pic_type = B_PIC;
2483 break;
2484 default:
2485 assert(0);
2486 break;
2487 }
2488
2489 /* update rc lib with current frame stats */
2490 i4_stuffing_byte = ih264e_rc_post_enc(ps_codec->s_rate_control.pps_rate_control_api,
2491 &(s_frame_info),
2492 ps_codec->s_rate_control.pps_pd_frm_rate,
2493 ps_codec->s_rate_control.pps_time_stamp,
2494 ps_codec->s_rate_control.pps_frame_time,
2495 (ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs),
2496 &rc_pic_type,
Harinarayanan K K134291e2015-06-18 16:03:38 +05302497 i4_is_first_frm,
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302498 &ps_codec->s_rate_control.post_encode_skip[ctxt_sel],
2499 u1_frame_qp,
2500 &ps_codec->s_rate_control.num_intra_in_prev_frame,
2501 &ps_codec->s_rate_control.i4_avg_activity);
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302502 return i4_stuffing_byte;
2503}
2504
2505/**
2506*******************************************************************************
2507*
2508* @brief
2509* entry point of a spawned encoder thread
2510*
2511* @par Description:
2512* The encoder thread dequeues a proc/entropy job from the encoder queue and
2513* calls necessary routines.
2514*
2515* @param[in] pv_proc
2516* Process context corresponding to the thread
2517*
2518* @returns error status
2519*
2520* @remarks
2521*
2522*******************************************************************************
2523*/
2524WORD32 ih264e_process_thread(void *pv_proc)
2525{
2526 /* error status */
2527 IH264_ERROR_T ret = IH264_SUCCESS;
2528 WORD32 error_status = IH264_SUCCESS;
2529
2530 /* proc ctxt */
2531 process_ctxt_t *ps_proc = pv_proc;
2532
2533 /* codec ctxt */
2534 codec_t *ps_codec = ps_proc->ps_codec;
2535
2536 /* structure to represent a processing job entry */
2537 job_t s_job;
2538
2539 /* blocking call : entropy dequeue is non-blocking till all
2540 * the proc jobs are processed */
2541 WORD32 is_blocking = 0;
2542
2543 /* set affinity */
2544 ithread_set_affinity(ps_proc->i4_id);
2545
Chamarthi Kishore95a21132019-10-11 18:53:50 +05302546 ps_proc->i4_error_code = IH264_SUCCESS;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302547 while(1)
2548 {
2549 /* dequeue a job from the entropy queue */
2550 {
2551 int error = ithread_mutex_lock(ps_codec->pv_entropy_mutex);
2552
2553 /* codec context selector */
Harinarayanan K K6cb67722015-06-19 14:44:42 +05302554 WORD32 ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302555
2556 volatile UWORD32 *pu4_buf = &ps_codec->au4_entropy_thread_active[ctxt_sel];
2557
2558 /* have the lock */
2559 if (error == 0)
2560 {
2561 if (*pu4_buf == 0)
2562 {
2563 /* no entropy threads are active, try dequeuing a job from the entropy queue */
2564 ret = ih264_list_dequeue(ps_proc->pv_entropy_jobq, &s_job, is_blocking);
2565 if (IH264_SUCCESS == ret)
2566 {
2567 *pu4_buf = 1;
2568 ithread_mutex_unlock(ps_codec->pv_entropy_mutex);
2569 goto WORKER;
2570 }
2571 else if(is_blocking)
2572 {
2573 ithread_mutex_unlock(ps_codec->pv_entropy_mutex);
2574 break;
2575 }
2576 }
2577 ithread_mutex_unlock(ps_codec->pv_entropy_mutex);
2578 }
2579 }
2580
2581 /* dequeue a job from the process queue */
2582 ret = ih264_list_dequeue(ps_proc->pv_proc_jobq, &s_job, 1);
2583 if (IH264_SUCCESS != ret)
2584 {
2585 if(ps_proc->i4_id)
2586 break;
2587 else
2588 {
2589 is_blocking = 1;
2590 continue;
2591 }
2592 }
2593
2594WORKER:
2595 /* choose appropriate proc context based on proc_base_idx */
2596 ps_proc = &ps_codec->as_process[ps_proc->i4_id + s_job.i2_proc_base_idx];
2597
2598 switch (s_job.i4_cmd)
2599 {
2600 case CMD_PROCESS:
2601 ps_proc->i4_mb_cnt = s_job.i2_mb_cnt;
2602 ps_proc->i4_mb_x = s_job.i2_mb_x;
2603 ps_proc->i4_mb_y = s_job.i2_mb_y;
2604
2605 /* init process context */
2606 ih264e_init_proc_ctxt(ps_proc);
2607
2608 /* core code all mbs enlisted under the current job */
Chamarthi Kishore95a21132019-10-11 18:53:50 +05302609 error_status = ih264e_process(ps_proc);
2610 if(error_status !=IH264_SUCCESS)
2611 {
2612 ps_proc->i4_error_code = error_status;
2613 return ret;
2614 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302615 break;
2616
2617 case CMD_ENTROPY:
2618 ps_proc->s_entropy.i4_mb_x = s_job.i2_mb_x;
2619 ps_proc->s_entropy.i4_mb_y = s_job.i2_mb_y;
2620 ps_proc->s_entropy.i4_mb_cnt = s_job.i2_mb_cnt;
2621
2622 /* init entropy */
2623 ih264e_init_entropy_ctxt(ps_proc);
2624
2625 /* entropy code all mbs enlisted under the current job */
Chamarthi Kishore95a21132019-10-11 18:53:50 +05302626 error_status = ih264e_entropy(ps_proc);
2627 if(error_status !=IH264_SUCCESS)
2628 {
2629 ps_proc->i4_error_code = error_status;
2630 return ret;
2631 }
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302632 break;
2633
2634 default:
Chamarthi Kishore95a21132019-10-11 18:53:50 +05302635 ps_proc->i4_error_code = IH264_FAIL;
2636 return ret;
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302637 }
2638 }
2639
Hamsalekha S8d3d3032015-03-13 21:24:58 +05302640 return ret;
2641}