xref: /aosp_15_r20/external/libavc/encoder/svc/isvce_encode.c (revision 495ae853bb871d1e5a258cb02c2cc13cde8ddb9a)
1*495ae853SAndroid Build Coastguard Worker /******************************************************************************
2*495ae853SAndroid Build Coastguard Worker  *
3*495ae853SAndroid Build Coastguard Worker  * Copyright (C) 2022 The Android Open Source Project
4*495ae853SAndroid Build Coastguard Worker  *
5*495ae853SAndroid Build Coastguard Worker  * Licensed under the Apache License, Version 2.0 (the "License");
6*495ae853SAndroid Build Coastguard Worker  * you may not use this file except in compliance with the License.
7*495ae853SAndroid Build Coastguard Worker  * You may obtain a copy of the License at:
8*495ae853SAndroid Build Coastguard Worker  *
9*495ae853SAndroid Build Coastguard Worker  * http://www.apache.org/licenses/LICENSE-2.0
10*495ae853SAndroid Build Coastguard Worker  *
11*495ae853SAndroid Build Coastguard Worker  * Unless required by applicable law or agreed to in writing, software
12*495ae853SAndroid Build Coastguard Worker  * distributed under the License is distributed on an "AS IS" BASIS,
13*495ae853SAndroid Build Coastguard Worker  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*495ae853SAndroid Build Coastguard Worker  * See the License for the specific language governing permissions and
15*495ae853SAndroid Build Coastguard Worker  * limitations under the License.
16*495ae853SAndroid Build Coastguard Worker  *
17*495ae853SAndroid Build Coastguard Worker  *****************************************************************************
18*495ae853SAndroid Build Coastguard Worker  * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19*495ae853SAndroid Build Coastguard Worker  */
20*495ae853SAndroid Build Coastguard Worker 
21*495ae853SAndroid Build Coastguard Worker /**
22*495ae853SAndroid Build Coastguard Worker ******************************************************************************
23*495ae853SAndroid Build Coastguard Worker * @file
24*495ae853SAndroid Build Coastguard Worker *  isvce_encode.c
25*495ae853SAndroid Build Coastguard Worker *
26*495ae853SAndroid Build Coastguard Worker * @brief
27*495ae853SAndroid Build Coastguard Worker *  This file contains functions for encoding the input yuv frame in synchronous
28*495ae853SAndroid Build Coastguard Worker *  api mode
29*495ae853SAndroid Build Coastguard Worker *
30*495ae853SAndroid Build Coastguard Worker * @author
31*495ae853SAndroid Build Coastguard Worker *  ittiam
32*495ae853SAndroid Build Coastguard Worker *
33*495ae853SAndroid Build Coastguard Worker * List of Functions
34*495ae853SAndroid Build Coastguard Worker *  - isvce_join_threads()
35*495ae853SAndroid Build Coastguard Worker *  - isvce_wait_for_thread()
36*495ae853SAndroid Build Coastguard Worker *  - isvce_encode()
37*495ae853SAndroid Build Coastguard Worker *
38*495ae853SAndroid Build Coastguard Worker ******************************************************************************
39*495ae853SAndroid Build Coastguard Worker */
40*495ae853SAndroid Build Coastguard Worker #include <stdio.h>
41*495ae853SAndroid Build Coastguard Worker #include <stddef.h>
42*495ae853SAndroid Build Coastguard Worker #include <stdlib.h>
43*495ae853SAndroid Build Coastguard Worker #include <string.h>
44*495ae853SAndroid Build Coastguard Worker #include <limits.h>
45*495ae853SAndroid Build Coastguard Worker #include <assert.h>
46*495ae853SAndroid Build Coastguard Worker #include <math.h>
47*495ae853SAndroid Build Coastguard Worker #include <stdbool.h>
48*495ae853SAndroid Build Coastguard Worker 
49*495ae853SAndroid Build Coastguard Worker #include "ih264_typedefs.h"
50*495ae853SAndroid Build Coastguard Worker /* Dependencies of ih264_buf_mgr.h */
51*495ae853SAndroid Build Coastguard Worker /* Dependencies of ih264_list.h */
52*495ae853SAndroid Build Coastguard Worker #include "ih264_error.h"
53*495ae853SAndroid Build Coastguard Worker /* Dependencies of ih264_common_tables.h */
54*495ae853SAndroid Build Coastguard Worker #include "ih264_defs.h"
55*495ae853SAndroid Build Coastguard Worker #include "ih264_structs.h"
56*495ae853SAndroid Build Coastguard Worker #include "ih264_buf_mgr.h"
57*495ae853SAndroid Build Coastguard Worker #include "ih264_common_tables.h"
58*495ae853SAndroid Build Coastguard Worker #include "ih264_list.h"
59*495ae853SAndroid Build Coastguard Worker #include "ih264_platform_macros.h"
60*495ae853SAndroid Build Coastguard Worker #include "ih264_trans_data.h"
61*495ae853SAndroid Build Coastguard Worker #include "ih264_size_defs.h"
62*495ae853SAndroid Build Coastguard Worker /* Dependencies of ih264e_cabac_structs.h */
63*495ae853SAndroid Build Coastguard Worker #include "ih264_cabac_tables.h"
64*495ae853SAndroid Build Coastguard Worker /* Dependencies of ime_structs.h */
65*495ae853SAndroid Build Coastguard Worker #include "ime_defs.h"
66*495ae853SAndroid Build Coastguard Worker #include "ime_distortion_metrics.h"
67*495ae853SAndroid Build Coastguard Worker /* Dependencies of ih264e_structs.h */
68*495ae853SAndroid Build Coastguard Worker #include "iv2.h"
69*495ae853SAndroid Build Coastguard Worker #include "ive2.h"
70*495ae853SAndroid Build Coastguard Worker #include "ih264_defs.h"
71*495ae853SAndroid Build Coastguard Worker #include "ih264_deblk_edge_filters.h"
72*495ae853SAndroid Build Coastguard Worker #include "ih264_inter_pred_filters.h"
73*495ae853SAndroid Build Coastguard Worker #include "ih264_structs.h"
74*495ae853SAndroid Build Coastguard Worker #include "ih264_trans_quant_itrans_iquant.h"
75*495ae853SAndroid Build Coastguard Worker /* Dependencies of ih264e_bitstream.h */
76*495ae853SAndroid Build Coastguard Worker #include "ih264e_error.h"
77*495ae853SAndroid Build Coastguard Worker #include "ih264e_bitstream.h"
78*495ae853SAndroid Build Coastguard Worker #include "ih264e_cabac_structs.h"
79*495ae853SAndroid Build Coastguard Worker #include "irc_cntrl_param.h"
80*495ae853SAndroid Build Coastguard Worker #include "irc_frame_info_collector.h"
81*495ae853SAndroid Build Coastguard Worker #include "ime_statistics.h"
82*495ae853SAndroid Build Coastguard Worker #include "ime_structs.h"
83*495ae853SAndroid Build Coastguard Worker /* Dependencies of 'ih264e_utils.h' */
84*495ae853SAndroid Build Coastguard Worker #include "ih264e_defs.h"
85*495ae853SAndroid Build Coastguard Worker #include "ih264e_structs.h"
86*495ae853SAndroid Build Coastguard Worker #include "ih264e_utils.h"
87*495ae853SAndroid Build Coastguard Worker #include "ime.h"
88*495ae853SAndroid Build Coastguard Worker #include "isvce.h"
89*495ae853SAndroid Build Coastguard Worker #include "isvce_cabac.h"
90*495ae853SAndroid Build Coastguard Worker #include "isvce_deblk.h"
91*495ae853SAndroid Build Coastguard Worker #include "isvce_defs.h"
92*495ae853SAndroid Build Coastguard Worker #include "isvce_downscaler.h"
93*495ae853SAndroid Build Coastguard Worker #include "isvce_encode_header.h"
94*495ae853SAndroid Build Coastguard Worker #include "isvce_fmt_conv.h"
95*495ae853SAndroid Build Coastguard Worker #include "isvce_ibl_eval.h"
96*495ae853SAndroid Build Coastguard Worker #include "isvce_ilp_mv.h"
97*495ae853SAndroid Build Coastguard Worker #include "isvce_intra_modes_eval.h"
98*495ae853SAndroid Build Coastguard Worker #include "isvce_me.h"
99*495ae853SAndroid Build Coastguard Worker #include "isvce_process.h"
100*495ae853SAndroid Build Coastguard Worker #include "isvce_rate_control.h"
101*495ae853SAndroid Build Coastguard Worker #include "isvce_residual_pred.h"
102*495ae853SAndroid Build Coastguard Worker #include "isvce_sub_pic_rc.h"
103*495ae853SAndroid Build Coastguard Worker #include "isvce_utils.h"
104*495ae853SAndroid Build Coastguard Worker 
105*495ae853SAndroid Build Coastguard Worker #define SEI_BASED_FORCE_IDR 1
106*495ae853SAndroid Build Coastguard Worker 
107*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
108*495ae853SAndroid Build Coastguard Worker /* Function Definitions                                                      */
109*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
110*495ae853SAndroid Build Coastguard Worker 
111*495ae853SAndroid Build Coastguard Worker /**
112*495ae853SAndroid Build Coastguard Worker ******************************************************************************
113*495ae853SAndroid Build Coastguard Worker *
114*495ae853SAndroid Build Coastguard Worker * @brief
115*495ae853SAndroid Build Coastguard Worker *  Encodes in synchronous api mode
116*495ae853SAndroid Build Coastguard Worker *
117*495ae853SAndroid Build Coastguard Worker * @par Description
118*495ae853SAndroid Build Coastguard Worker *  This routine processes input yuv, encodes it and outputs bitstream and recon
119*495ae853SAndroid Build Coastguard Worker *
120*495ae853SAndroid Build Coastguard Worker * @param[in] ps_codec_obj
121*495ae853SAndroid Build Coastguard Worker *  Pointer to codec object at API level
122*495ae853SAndroid Build Coastguard Worker *
123*495ae853SAndroid Build Coastguard Worker * @param[in] pv_api_ip
124*495ae853SAndroid Build Coastguard Worker *  Pointer to input argument structure
125*495ae853SAndroid Build Coastguard Worker *
126*495ae853SAndroid Build Coastguard Worker * @param[out] pv_api_op
127*495ae853SAndroid Build Coastguard Worker *  Pointer to output argument structure
128*495ae853SAndroid Build Coastguard Worker *
129*495ae853SAndroid Build Coastguard Worker * @returns  Status
130*495ae853SAndroid Build Coastguard Worker *
131*495ae853SAndroid Build Coastguard Worker ******************************************************************************
132*495ae853SAndroid Build Coastguard Worker */
isvce_encode(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)133*495ae853SAndroid Build Coastguard Worker WORD32 isvce_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
134*495ae853SAndroid Build Coastguard Worker {
135*495ae853SAndroid Build Coastguard Worker     /* error status */
136*495ae853SAndroid Build Coastguard Worker     IH264E_ERROR_T error_status = IH264E_SUCCESS;
137*495ae853SAndroid Build Coastguard Worker 
138*495ae853SAndroid Build Coastguard Worker     /* codec ctxt */
139*495ae853SAndroid Build Coastguard Worker     isvce_codec_t *ps_codec = (isvce_codec_t *) ps_codec_obj->pv_codec_handle;
140*495ae853SAndroid Build Coastguard Worker 
141*495ae853SAndroid Build Coastguard Worker     /* input frame to encode */
142*495ae853SAndroid Build Coastguard Worker     isvce_video_encode_ip_t *ps_video_encode_ip = pv_api_ip;
143*495ae853SAndroid Build Coastguard Worker 
144*495ae853SAndroid Build Coastguard Worker     /* output buffer to write stream */
145*495ae853SAndroid Build Coastguard Worker     isvce_video_encode_op_t *ps_video_encode_op = pv_api_op;
146*495ae853SAndroid Build Coastguard Worker 
147*495ae853SAndroid Build Coastguard Worker     /* i/o structures */
148*495ae853SAndroid Build Coastguard Worker     isvce_inp_buf_t s_inp_buf;
149*495ae853SAndroid Build Coastguard Worker     isvce_out_buf_t s_out_buf;
150*495ae853SAndroid Build Coastguard Worker 
151*495ae853SAndroid Build Coastguard Worker     WORD32 ctxt_sel = 0, i4_rc_pre_enc_skip;
152*495ae853SAndroid Build Coastguard Worker     WORD32 i, j;
153*495ae853SAndroid Build Coastguard Worker 
154*495ae853SAndroid Build Coastguard Worker     ASSERT(MAX_CTXT_SETS == 1);
155*495ae853SAndroid Build Coastguard Worker 
156*495ae853SAndroid Build Coastguard Worker     /********************************************************************/
157*495ae853SAndroid Build Coastguard Worker     /*                            BEGIN INIT                            */
158*495ae853SAndroid Build Coastguard Worker     /********************************************************************/
159*495ae853SAndroid Build Coastguard Worker     /* reset output structure */
160*495ae853SAndroid Build Coastguard Worker     ps_video_encode_op->s_ive_op.u4_error_code = IV_SUCCESS;
161*495ae853SAndroid Build Coastguard Worker     ps_video_encode_op->s_ive_op.output_present = 0;
162*495ae853SAndroid Build Coastguard Worker     ps_video_encode_op->s_ive_op.dump_recon = 0;
163*495ae853SAndroid Build Coastguard Worker     ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_NA_FRAME;
164*495ae853SAndroid Build Coastguard Worker 
165*495ae853SAndroid Build Coastguard Worker     /* Check for output memory allocation size */
166*495ae853SAndroid Build Coastguard Worker     {
167*495ae853SAndroid Build Coastguard Worker         UWORD32 u4_min_bufsize =
168*495ae853SAndroid Build Coastguard Worker             isvce_get_min_outbuf_size(ps_codec->s_cfg.u4_wd, ps_codec->s_cfg.u4_ht,
169*495ae853SAndroid Build Coastguard Worker                                       ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers);
170*495ae853SAndroid Build Coastguard Worker         UWORD32 u4_bufsize_per_layer = ps_video_encode_ip->s_ive_ip.s_out_buf.u4_bufsize /
171*495ae853SAndroid Build Coastguard Worker                                        ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers;
172*495ae853SAndroid Build Coastguard Worker 
173*495ae853SAndroid Build Coastguard Worker         if(ps_video_encode_ip->s_ive_ip.s_out_buf.u4_bufsize < u4_min_bufsize)
174*495ae853SAndroid Build Coastguard Worker         {
175*495ae853SAndroid Build Coastguard Worker             error_status = IH264E_INSUFFICIENT_OUTPUT_BUFFER;
176*495ae853SAndroid Build Coastguard Worker 
177*495ae853SAndroid Build Coastguard Worker             SET_ERROR_ON_RETURN(error_status, IVE_UNSUPPORTEDPARAM,
178*495ae853SAndroid Build Coastguard Worker                                 ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL);
179*495ae853SAndroid Build Coastguard Worker         }
180*495ae853SAndroid Build Coastguard Worker 
181*495ae853SAndroid Build Coastguard Worker         for(i = 0; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers; i++)
182*495ae853SAndroid Build Coastguard Worker         {
183*495ae853SAndroid Build Coastguard Worker             s_out_buf.as_bits_buf[i] = ps_video_encode_ip->s_ive_ip.s_out_buf;
184*495ae853SAndroid Build Coastguard Worker 
185*495ae853SAndroid Build Coastguard Worker             s_out_buf.as_bits_buf[i].u4_bufsize = u4_bufsize_per_layer;
186*495ae853SAndroid Build Coastguard Worker             s_out_buf.as_bits_buf[i].pv_buf =
187*495ae853SAndroid Build Coastguard Worker                 ((UWORD8 *) ps_video_encode_ip->s_ive_ip.s_out_buf.pv_buf) +
188*495ae853SAndroid Build Coastguard Worker                 u4_bufsize_per_layer * i;
189*495ae853SAndroid Build Coastguard Worker         }
190*495ae853SAndroid Build Coastguard Worker     }
191*495ae853SAndroid Build Coastguard Worker 
192*495ae853SAndroid Build Coastguard Worker     s_out_buf.u4_is_last = 0;
193*495ae853SAndroid Build Coastguard Worker     s_out_buf.u4_timestamp_low = ps_video_encode_ip->s_ive_ip.u4_timestamp_low;
194*495ae853SAndroid Build Coastguard Worker     s_out_buf.u4_timestamp_high = ps_video_encode_ip->s_ive_ip.u4_timestamp_high;
195*495ae853SAndroid Build Coastguard Worker 
196*495ae853SAndroid Build Coastguard Worker     /* api call cnt */
197*495ae853SAndroid Build Coastguard Worker     ps_codec->i4_encode_api_call_cnt += 1;
198*495ae853SAndroid Build Coastguard Worker 
199*495ae853SAndroid Build Coastguard Worker     /* codec context selector */
200*495ae853SAndroid Build Coastguard Worker     ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS;
201*495ae853SAndroid Build Coastguard Worker 
202*495ae853SAndroid Build Coastguard Worker     /* reset status flags */
203*495ae853SAndroid Build Coastguard Worker     ps_codec->ai4_pic_cnt[ctxt_sel] = -1;
204*495ae853SAndroid Build Coastguard Worker     ps_codec->s_rate_control.post_encode_skip[ctxt_sel] = 0;
205*495ae853SAndroid Build Coastguard Worker     ps_codec->s_rate_control.pre_encode_skip[ctxt_sel] = 0;
206*495ae853SAndroid Build Coastguard Worker 
207*495ae853SAndroid Build Coastguard Worker     /* pass output buffer to codec */
208*495ae853SAndroid Build Coastguard Worker     ps_codec->as_out_buf[ctxt_sel] = s_out_buf;
209*495ae853SAndroid Build Coastguard Worker 
210*495ae853SAndroid Build Coastguard Worker     /* initialize codec ctxt with default params for the first encode api call */
211*495ae853SAndroid Build Coastguard Worker     if(ps_codec->i4_encode_api_call_cnt == 0)
212*495ae853SAndroid Build Coastguard Worker     {
213*495ae853SAndroid Build Coastguard Worker         error_status = isvce_codec_init(ps_codec);
214*495ae853SAndroid Build Coastguard Worker 
215*495ae853SAndroid Build Coastguard Worker         SET_ERROR_ON_RETURN(error_status, IVE_FATALERROR,
216*495ae853SAndroid Build Coastguard Worker                             ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL);
217*495ae853SAndroid Build Coastguard Worker     }
218*495ae853SAndroid Build Coastguard Worker 
219*495ae853SAndroid Build Coastguard Worker     error_status =
220*495ae853SAndroid Build Coastguard Worker         isvce_svc_frame_params_validate(ps_codec->s_rate_control.apps_rate_control_api,
221*495ae853SAndroid Build Coastguard Worker                                         ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers);
222*495ae853SAndroid Build Coastguard Worker     SET_ERROR_ON_RETURN(error_status, IVE_FATALERROR, ps_video_encode_op->s_ive_op.u4_error_code,
223*495ae853SAndroid Build Coastguard Worker                         IV_FAIL);
224*495ae853SAndroid Build Coastguard Worker 
225*495ae853SAndroid Build Coastguard Worker     /* parse configuration params */
226*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < MAX_ACTIVE_CONFIG_PARAMS; i++)
227*495ae853SAndroid Build Coastguard Worker     {
228*495ae853SAndroid Build Coastguard Worker         isvce_cfg_params_t *ps_cfg = &ps_codec->as_cfg[i];
229*495ae853SAndroid Build Coastguard Worker 
230*495ae853SAndroid Build Coastguard Worker         if(1 == ps_cfg->u4_is_valid)
231*495ae853SAndroid Build Coastguard Worker         {
232*495ae853SAndroid Build Coastguard Worker             if(((ps_cfg->u4_timestamp_high == ps_video_encode_ip->s_ive_ip.u4_timestamp_high) &&
233*495ae853SAndroid Build Coastguard Worker                 (ps_cfg->u4_timestamp_low == ps_video_encode_ip->s_ive_ip.u4_timestamp_low)) ||
234*495ae853SAndroid Build Coastguard Worker                ((WORD32) ps_cfg->u4_timestamp_high == -1) ||
235*495ae853SAndroid Build Coastguard Worker                ((WORD32) ps_cfg->u4_timestamp_low == -1))
236*495ae853SAndroid Build Coastguard Worker             {
237*495ae853SAndroid Build Coastguard Worker                 error_status = isvce_codec_update_config(ps_codec, ps_cfg);
238*495ae853SAndroid Build Coastguard Worker                 SET_ERROR_ON_RETURN(error_status, IVE_UNSUPPORTEDPARAM,
239*495ae853SAndroid Build Coastguard Worker                                     ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL);
240*495ae853SAndroid Build Coastguard Worker 
241*495ae853SAndroid Build Coastguard Worker                 ps_cfg->u4_is_valid = 0;
242*495ae853SAndroid Build Coastguard Worker             }
243*495ae853SAndroid Build Coastguard Worker         }
244*495ae853SAndroid Build Coastguard Worker     }
245*495ae853SAndroid Build Coastguard Worker     /* Force IDR based on SEI params */
246*495ae853SAndroid Build Coastguard Worker #if SEI_BASED_FORCE_IDR
247*495ae853SAndroid Build Coastguard Worker     {
248*495ae853SAndroid Build Coastguard Worker         sei_mdcv_params_t *ps_sei_mdcv_params = &ps_codec->s_sei.s_sei_mdcv_params;
249*495ae853SAndroid Build Coastguard Worker         sei_mdcv_params_t *ps_cfg_sei_mdcv_params = &ps_codec->s_cfg.s_sei.s_sei_mdcv_params;
250*495ae853SAndroid Build Coastguard Worker         sei_cll_params_t *ps_sei_cll_params = &ps_codec->s_sei.s_sei_cll_params;
251*495ae853SAndroid Build Coastguard Worker         sei_cll_params_t *ps_cfg_sei_cll_params = &ps_codec->s_cfg.s_sei.s_sei_cll_params;
252*495ae853SAndroid Build Coastguard Worker         sei_ave_params_t *ps_sei_ave_params = &ps_codec->s_sei.s_sei_ave_params;
253*495ae853SAndroid Build Coastguard Worker         sei_ave_params_t *ps_cfg_sei_ave_params = &ps_codec->s_cfg.s_sei.s_sei_ave_params;
254*495ae853SAndroid Build Coastguard Worker 
255*495ae853SAndroid Build Coastguard Worker         if((ps_sei_mdcv_params->au2_display_primaries_x[0] !=
256*495ae853SAndroid Build Coastguard Worker             ps_cfg_sei_mdcv_params->au2_display_primaries_x[0]) ||
257*495ae853SAndroid Build Coastguard Worker            (ps_sei_mdcv_params->au2_display_primaries_x[1] !=
258*495ae853SAndroid Build Coastguard Worker             ps_cfg_sei_mdcv_params->au2_display_primaries_x[1]) ||
259*495ae853SAndroid Build Coastguard Worker            (ps_sei_mdcv_params->au2_display_primaries_x[2] !=
260*495ae853SAndroid Build Coastguard Worker             ps_cfg_sei_mdcv_params->au2_display_primaries_x[2]) ||
261*495ae853SAndroid Build Coastguard Worker            (ps_sei_mdcv_params->au2_display_primaries_y[0] !=
262*495ae853SAndroid Build Coastguard Worker             ps_cfg_sei_mdcv_params->au2_display_primaries_y[0]) ||
263*495ae853SAndroid Build Coastguard Worker            (ps_sei_mdcv_params->au2_display_primaries_y[1] !=
264*495ae853SAndroid Build Coastguard Worker             ps_cfg_sei_mdcv_params->au2_display_primaries_y[1]) ||
265*495ae853SAndroid Build Coastguard Worker            (ps_sei_mdcv_params->au2_display_primaries_y[2] !=
266*495ae853SAndroid Build Coastguard Worker             ps_cfg_sei_mdcv_params->au2_display_primaries_y[2]) ||
267*495ae853SAndroid Build Coastguard Worker            (ps_sei_mdcv_params->u2_white_point_x != ps_cfg_sei_mdcv_params->u2_white_point_x) ||
268*495ae853SAndroid Build Coastguard Worker            (ps_sei_mdcv_params->u2_white_point_y != ps_cfg_sei_mdcv_params->u2_white_point_y) ||
269*495ae853SAndroid Build Coastguard Worker            (ps_sei_mdcv_params->u4_max_display_mastering_luminance !=
270*495ae853SAndroid Build Coastguard Worker             ps_cfg_sei_mdcv_params->u4_max_display_mastering_luminance) ||
271*495ae853SAndroid Build Coastguard Worker            (ps_sei_mdcv_params->u4_min_display_mastering_luminance !=
272*495ae853SAndroid Build Coastguard Worker             ps_cfg_sei_mdcv_params->u4_min_display_mastering_luminance))
273*495ae853SAndroid Build Coastguard Worker         {
274*495ae853SAndroid Build Coastguard Worker             ps_codec->s_sei.s_sei_mdcv_params = ps_codec->s_cfg.s_sei.s_sei_mdcv_params;
275*495ae853SAndroid Build Coastguard Worker             ps_codec->s_sei.u1_sei_mdcv_params_present_flag = 1;
276*495ae853SAndroid Build Coastguard Worker         }
277*495ae853SAndroid Build Coastguard Worker         else
278*495ae853SAndroid Build Coastguard Worker         {
279*495ae853SAndroid Build Coastguard Worker             ps_codec->s_sei.u1_sei_mdcv_params_present_flag = 0;
280*495ae853SAndroid Build Coastguard Worker         }
281*495ae853SAndroid Build Coastguard Worker 
282*495ae853SAndroid Build Coastguard Worker         if((ps_sei_cll_params->u2_max_content_light_level !=
283*495ae853SAndroid Build Coastguard Worker             ps_cfg_sei_cll_params->u2_max_content_light_level) ||
284*495ae853SAndroid Build Coastguard Worker            (ps_sei_cll_params->u2_max_pic_average_light_level !=
285*495ae853SAndroid Build Coastguard Worker             ps_cfg_sei_cll_params->u2_max_pic_average_light_level))
286*495ae853SAndroid Build Coastguard Worker         {
287*495ae853SAndroid Build Coastguard Worker             ps_codec->s_sei.s_sei_cll_params = ps_codec->s_cfg.s_sei.s_sei_cll_params;
288*495ae853SAndroid Build Coastguard Worker             ps_codec->s_sei.u1_sei_cll_params_present_flag = 1;
289*495ae853SAndroid Build Coastguard Worker         }
290*495ae853SAndroid Build Coastguard Worker         else
291*495ae853SAndroid Build Coastguard Worker         {
292*495ae853SAndroid Build Coastguard Worker             ps_codec->s_sei.u1_sei_cll_params_present_flag = 0;
293*495ae853SAndroid Build Coastguard Worker         }
294*495ae853SAndroid Build Coastguard Worker 
295*495ae853SAndroid Build Coastguard Worker         if((ps_sei_ave_params->u4_ambient_illuminance !=
296*495ae853SAndroid Build Coastguard Worker             ps_cfg_sei_ave_params->u4_ambient_illuminance) ||
297*495ae853SAndroid Build Coastguard Worker            (ps_sei_ave_params->u2_ambient_light_x != ps_cfg_sei_ave_params->u2_ambient_light_x) ||
298*495ae853SAndroid Build Coastguard Worker            (ps_sei_ave_params->u2_ambient_light_y != ps_cfg_sei_ave_params->u2_ambient_light_y))
299*495ae853SAndroid Build Coastguard Worker         {
300*495ae853SAndroid Build Coastguard Worker             ps_codec->s_sei.s_sei_ave_params = ps_codec->s_cfg.s_sei.s_sei_ave_params;
301*495ae853SAndroid Build Coastguard Worker             ps_codec->s_sei.u1_sei_ave_params_present_flag = 1;
302*495ae853SAndroid Build Coastguard Worker         }
303*495ae853SAndroid Build Coastguard Worker         else
304*495ae853SAndroid Build Coastguard Worker         {
305*495ae853SAndroid Build Coastguard Worker             ps_codec->s_sei.u1_sei_ave_params_present_flag = 0;
306*495ae853SAndroid Build Coastguard Worker         }
307*495ae853SAndroid Build Coastguard Worker 
308*495ae853SAndroid Build Coastguard Worker         if((1 == ps_codec->s_sei.u1_sei_mdcv_params_present_flag) ||
309*495ae853SAndroid Build Coastguard Worker            (1 == ps_codec->s_sei.u1_sei_cll_params_present_flag) ||
310*495ae853SAndroid Build Coastguard Worker            (1 == ps_codec->s_sei.u1_sei_ave_params_present_flag))
311*495ae853SAndroid Build Coastguard Worker         {
312*495ae853SAndroid Build Coastguard Worker             ps_codec->force_curr_frame_type = IV_IDR_FRAME;
313*495ae853SAndroid Build Coastguard Worker         }
314*495ae853SAndroid Build Coastguard Worker     }
315*495ae853SAndroid Build Coastguard Worker #endif
316*495ae853SAndroid Build Coastguard Worker 
317*495ae853SAndroid Build Coastguard Worker     /* In case of alt ref and B pics we will have non reference frame in stream */
318*495ae853SAndroid Build Coastguard Worker     if(ps_codec->s_cfg.u4_enable_alt_ref || ps_codec->s_cfg.u4_num_bframes)
319*495ae853SAndroid Build Coastguard Worker     {
320*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_non_ref_frames_in_stream = 1;
321*495ae853SAndroid Build Coastguard Worker     }
322*495ae853SAndroid Build Coastguard Worker 
323*495ae853SAndroid Build Coastguard Worker     if(ps_codec->i4_encode_api_call_cnt == 0)
324*495ae853SAndroid Build Coastguard Worker     {
325*495ae853SAndroid Build Coastguard Worker         /********************************************************************/
326*495ae853SAndroid Build Coastguard Worker         /*   number of mv/ref bank buffers used by the codec,               */
327*495ae853SAndroid Build Coastguard Worker         /*      1 to handle curr frame                                      */
328*495ae853SAndroid Build Coastguard Worker         /*      1 to store information of ref frame                         */
329*495ae853SAndroid Build Coastguard Worker         /*      1 more additional because of the codec employs 2 ctxt sets  */
330*495ae853SAndroid Build Coastguard Worker         /*        to assist asynchronous API                                */
331*495ae853SAndroid Build Coastguard Worker         /********************************************************************/
332*495ae853SAndroid Build Coastguard Worker 
333*495ae853SAndroid Build Coastguard Worker         /* initialize mv bank buffer manager */
334*495ae853SAndroid Build Coastguard Worker         error_status = isvce_svc_au_data_mgr_add_bufs(ps_codec);
335*495ae853SAndroid Build Coastguard Worker 
336*495ae853SAndroid Build Coastguard Worker         SET_ERROR_ON_RETURN(error_status, IVE_FATALERROR,
337*495ae853SAndroid Build Coastguard Worker                             ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL);
338*495ae853SAndroid Build Coastguard Worker 
339*495ae853SAndroid Build Coastguard Worker         /* initialize ref bank buffer manager */
340*495ae853SAndroid Build Coastguard Worker         error_status = isvce_svc_au_buf_mgr_add_bufs(ps_codec);
341*495ae853SAndroid Build Coastguard Worker 
342*495ae853SAndroid Build Coastguard Worker         SET_ERROR_ON_RETURN(error_status, IVE_FATALERROR,
343*495ae853SAndroid Build Coastguard Worker                             ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL);
344*495ae853SAndroid Build Coastguard Worker 
345*495ae853SAndroid Build Coastguard Worker         /* for the first frame, generate header when not requested explicitly */
346*495ae853SAndroid Build Coastguard Worker         if(ps_codec->i4_header_mode == 0 && ps_codec->u4_header_generated == 0)
347*495ae853SAndroid Build Coastguard Worker         {
348*495ae853SAndroid Build Coastguard Worker             ps_codec->i4_gen_header = 1;
349*495ae853SAndroid Build Coastguard Worker         }
350*495ae853SAndroid Build Coastguard Worker     }
351*495ae853SAndroid Build Coastguard Worker 
352*495ae853SAndroid Build Coastguard Worker     /* generate header and return when encoder is operated in header mode */
353*495ae853SAndroid Build Coastguard Worker     if(ps_codec->i4_header_mode == 1)
354*495ae853SAndroid Build Coastguard Worker     {
355*495ae853SAndroid Build Coastguard Worker         /* whenever the header is generated, this implies a start of sequence
356*495ae853SAndroid Build Coastguard Worker          * and a sequence needs to be started with IDR
357*495ae853SAndroid Build Coastguard Worker          */
358*495ae853SAndroid Build Coastguard Worker         ps_codec->force_curr_frame_type = IV_IDR_FRAME;
359*495ae853SAndroid Build Coastguard Worker 
360*495ae853SAndroid Build Coastguard Worker         s_inp_buf.s_svc_params = ps_codec->s_cfg.s_svc_params;
361*495ae853SAndroid Build Coastguard Worker         s_inp_buf.s_inp_props.s_raw_buf = ps_video_encode_ip->s_ive_ip.s_inp_buf;
362*495ae853SAndroid Build Coastguard Worker         s_inp_buf.s_inp_props.s_raw_buf.au4_wd[Y] = ps_codec->s_cfg.u4_wd;
363*495ae853SAndroid Build Coastguard Worker         s_inp_buf.s_inp_props.s_raw_buf.au4_ht[Y] = ps_codec->s_cfg.u4_ht;
364*495ae853SAndroid Build Coastguard Worker 
365*495ae853SAndroid Build Coastguard Worker         isvce_init_svc_dimension(&s_inp_buf);
366*495ae853SAndroid Build Coastguard Worker 
367*495ae853SAndroid Build Coastguard Worker         /* generate header */
368*495ae853SAndroid Build Coastguard Worker         error_status = isvce_generate_sps_pps(ps_codec, &s_inp_buf);
369*495ae853SAndroid Build Coastguard Worker 
370*495ae853SAndroid Build Coastguard Worker         /* send the input to app */
371*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.s_inp_buf = ps_video_encode_ip->s_ive_ip.s_inp_buf;
372*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.u4_timestamp_low =
373*495ae853SAndroid Build Coastguard Worker             ps_video_encode_ip->s_ive_ip.u4_timestamp_low;
374*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.u4_timestamp_high =
375*495ae853SAndroid Build Coastguard Worker             ps_video_encode_ip->s_ive_ip.u4_timestamp_high;
376*495ae853SAndroid Build Coastguard Worker 
377*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.u4_is_last = ps_video_encode_ip->s_ive_ip.u4_is_last;
378*495ae853SAndroid Build Coastguard Worker 
379*495ae853SAndroid Build Coastguard Worker         /* send the output to app */
380*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.output_present = 1;
381*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.dump_recon = 0;
382*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.s_out_buf = ps_codec->as_out_buf[ctxt_sel].as_bits_buf[0];
383*495ae853SAndroid Build Coastguard Worker 
384*495ae853SAndroid Build Coastguard Worker         for(i = 1; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers; i++)
385*495ae853SAndroid Build Coastguard Worker         {
386*495ae853SAndroid Build Coastguard Worker             memmove(((UWORD8 *) ps_video_encode_op->s_ive_op.s_out_buf.pv_buf +
387*495ae853SAndroid Build Coastguard Worker                      ps_video_encode_op->s_ive_op.s_out_buf.u4_bytes),
388*495ae853SAndroid Build Coastguard Worker                     ps_codec->as_out_buf[ctxt_sel].as_bits_buf[i].pv_buf,
389*495ae853SAndroid Build Coastguard Worker                     ps_codec->as_out_buf[ctxt_sel].as_bits_buf[i].u4_bytes);
390*495ae853SAndroid Build Coastguard Worker 
391*495ae853SAndroid Build Coastguard Worker             ps_video_encode_op->s_ive_op.s_out_buf.u4_bytes +=
392*495ae853SAndroid Build Coastguard Worker                 ps_codec->as_out_buf[ctxt_sel].as_bits_buf[i].u4_bytes;
393*495ae853SAndroid Build Coastguard Worker         }
394*495ae853SAndroid Build Coastguard Worker 
395*495ae853SAndroid Build Coastguard Worker         /* error status */
396*495ae853SAndroid Build Coastguard Worker         SET_ERROR_ON_RETURN(error_status, IVE_FATALERROR,
397*495ae853SAndroid Build Coastguard Worker                             ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL);
398*495ae853SAndroid Build Coastguard Worker 
399*495ae853SAndroid Build Coastguard Worker         /* indicates that header has been generated previously */
400*495ae853SAndroid Build Coastguard Worker         ps_codec->u4_header_generated = 1;
401*495ae853SAndroid Build Coastguard Worker 
402*495ae853SAndroid Build Coastguard Worker         /* api call cnt */
403*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_encode_api_call_cnt--;
404*495ae853SAndroid Build Coastguard Worker 
405*495ae853SAndroid Build Coastguard Worker         /* header mode tag is not sticky */
406*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_header_mode = 0;
407*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_gen_header = 0;
408*495ae853SAndroid Build Coastguard Worker 
409*495ae853SAndroid Build Coastguard Worker         return IV_SUCCESS;
410*495ae853SAndroid Build Coastguard Worker     }
411*495ae853SAndroid Build Coastguard Worker 
412*495ae853SAndroid Build Coastguard Worker     /* curr pic cnt */
413*495ae853SAndroid Build Coastguard Worker     ps_codec->i4_pic_cnt += 1;
414*495ae853SAndroid Build Coastguard Worker 
415*495ae853SAndroid Build Coastguard Worker     i4_rc_pre_enc_skip = 0;
416*495ae853SAndroid Build Coastguard Worker     for(i = 0; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers; i++)
417*495ae853SAndroid Build Coastguard Worker     {
418*495ae853SAndroid Build Coastguard Worker         i4_rc_pre_enc_skip =
419*495ae853SAndroid Build Coastguard Worker             isvce_input_queue_update(ps_codec, &ps_video_encode_ip->s_ive_ip, &s_inp_buf, i);
420*495ae853SAndroid Build Coastguard Worker     }
421*495ae853SAndroid Build Coastguard Worker 
422*495ae853SAndroid Build Coastguard Worker     s_out_buf.u4_is_last = s_inp_buf.s_inp_props.u4_is_last;
423*495ae853SAndroid Build Coastguard Worker     ps_video_encode_op->s_ive_op.u4_is_last = s_inp_buf.s_inp_props.u4_is_last;
424*495ae853SAndroid Build Coastguard Worker 
425*495ae853SAndroid Build Coastguard Worker     /* Only encode if the current frame is not pre-encode skip */
426*495ae853SAndroid Build Coastguard Worker     if(!i4_rc_pre_enc_skip && s_inp_buf.s_inp_props.s_raw_buf.apv_bufs[0])
427*495ae853SAndroid Build Coastguard Worker     {
428*495ae853SAndroid Build Coastguard Worker         isvce_process_ctxt_t *ps_proc = &ps_codec->as_process[ctxt_sel * MAX_PROCESS_THREADS];
429*495ae853SAndroid Build Coastguard Worker 
430*495ae853SAndroid Build Coastguard Worker         WORD32 num_thread_cnt = ps_codec->s_cfg.u4_num_cores - 1;
431*495ae853SAndroid Build Coastguard Worker 
432*495ae853SAndroid Build Coastguard Worker         ps_codec->ai4_pic_cnt[ctxt_sel] = ps_codec->i4_pic_cnt;
433*495ae853SAndroid Build Coastguard Worker 
434*495ae853SAndroid Build Coastguard Worker         error_status = isvce_svc_au_init(ps_codec, &s_inp_buf);
435*495ae853SAndroid Build Coastguard Worker 
436*495ae853SAndroid Build Coastguard Worker         SET_ERROR_ON_RETURN(error_status, IVE_FATALERROR,
437*495ae853SAndroid Build Coastguard Worker                             ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL);
438*495ae853SAndroid Build Coastguard Worker 
439*495ae853SAndroid Build Coastguard Worker         isvce_nalu_info_au_init(ps_codec->as_nalu_descriptors,
440*495ae853SAndroid Build Coastguard Worker                                 ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers);
441*495ae853SAndroid Build Coastguard Worker 
442*495ae853SAndroid Build Coastguard Worker #if ENABLE_MODE_STAT_VISUALISER
443*495ae853SAndroid Build Coastguard Worker         isvce_msv_get_input_frame(ps_codec->ps_mode_stat_visualiser, &s_inp_buf);
444*495ae853SAndroid Build Coastguard Worker #endif
445*495ae853SAndroid Build Coastguard Worker 
446*495ae853SAndroid Build Coastguard Worker         for(i = 0; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers; i++)
447*495ae853SAndroid Build Coastguard Worker         {
448*495ae853SAndroid Build Coastguard Worker             isvce_svc_layer_pic_init(ps_codec, &s_inp_buf, i);
449*495ae853SAndroid Build Coastguard Worker 
450*495ae853SAndroid Build Coastguard Worker             for(j = 0; j < num_thread_cnt; j++)
451*495ae853SAndroid Build Coastguard Worker             {
452*495ae853SAndroid Build Coastguard Worker                 ithread_create(ps_codec->apv_proc_thread_handle[j], NULL, isvce_process_thread,
453*495ae853SAndroid Build Coastguard Worker                                &ps_codec->as_process[j + 1]);
454*495ae853SAndroid Build Coastguard Worker 
455*495ae853SAndroid Build Coastguard Worker                 ps_codec->ai4_process_thread_created[j] = 1;
456*495ae853SAndroid Build Coastguard Worker 
457*495ae853SAndroid Build Coastguard Worker                 ps_codec->i4_proc_thread_cnt++;
458*495ae853SAndroid Build Coastguard Worker             }
459*495ae853SAndroid Build Coastguard Worker 
460*495ae853SAndroid Build Coastguard Worker             /* launch job */
461*495ae853SAndroid Build Coastguard Worker             isvce_process_thread(ps_proc);
462*495ae853SAndroid Build Coastguard Worker 
463*495ae853SAndroid Build Coastguard Worker             /* Join threads at the end of encoding a frame */
464*495ae853SAndroid Build Coastguard Worker             isvce_join_threads(ps_codec);
465*495ae853SAndroid Build Coastguard Worker 
466*495ae853SAndroid Build Coastguard Worker             ih264_list_reset(ps_codec->pv_proc_jobq);
467*495ae853SAndroid Build Coastguard Worker 
468*495ae853SAndroid Build Coastguard Worker             ih264_list_reset(ps_codec->pv_entropy_jobq);
469*495ae853SAndroid Build Coastguard Worker         }
470*495ae853SAndroid Build Coastguard Worker 
471*495ae853SAndroid Build Coastguard Worker #if ENABLE_MODE_STAT_VISUALISER
472*495ae853SAndroid Build Coastguard Worker         isvce_msv_dump_visualisation(ps_codec->ps_mode_stat_visualiser);
473*495ae853SAndroid Build Coastguard Worker #endif
474*495ae853SAndroid Build Coastguard Worker 
475*495ae853SAndroid Build Coastguard Worker         isvce_sub_pic_rc_dump_data(ps_codec->as_process->ps_sub_pic_rc_ctxt);
476*495ae853SAndroid Build Coastguard Worker     }
477*495ae853SAndroid Build Coastguard Worker 
478*495ae853SAndroid Build Coastguard Worker     /****************************************************************************
479*495ae853SAndroid Build Coastguard Worker      * RECON
480*495ae853SAndroid Build Coastguard Worker      *    Since we have forward dependent frames, we cannot return recon in
481*495ae853SAndroid Build Coastguard Worker      *encoding order. It must be in poc order, or input pic order. To achieve this
482*495ae853SAndroid Build Coastguard Worker      *we introduce a delay of 1 to the recon wrt encode. Now since we have that
483*495ae853SAndroid Build Coastguard Worker      *    delay, at any point minimum of pic_cnt in our ref buffer will be the
484*495ae853SAndroid Build Coastguard Worker      *    correct frame. For ex let our GOP be IBBP [1 2 3 4] . The encode order
485*495ae853SAndroid Build Coastguard Worker      *    will be [1 4 2 3] .Now since we have a delay of 1, when we are done with
486*495ae853SAndroid Build Coastguard Worker      *    encoding 4, the min in the list will be 1. After encoding 2, it will be
487*495ae853SAndroid Build Coastguard Worker      *    2, 3 after 3 and 4 after 4. Hence we can return in sequence. Note
488*495ae853SAndroid Build Coastguard Worker      *    that the 1 delay is critical. Hence if we have post enc skip, we must
489*495ae853SAndroid Build Coastguard Worker      *    skip here too. Note that since post enc skip already frees the recon
490*495ae853SAndroid Build Coastguard Worker      *    buffer we need not do any thing here
491*495ae853SAndroid Build Coastguard Worker      *
492*495ae853SAndroid Build Coastguard Worker      *    We need to return a recon when ever we consume an input buffer. This
493*495ae853SAndroid Build Coastguard Worker      *    comsumption include a pre or post enc skip. Thus dump recon is set for
494*495ae853SAndroid Build Coastguard Worker      *    all cases except when
495*495ae853SAndroid Build Coastguard Worker      *    1) We are waiting -> ps_codec->i4_pic_cnt >
496*495ae853SAndroid Build Coastguard Worker      *ps_codec->s_cfg.u4_num_bframe An exception need to be made for the case when
497*495ae853SAndroid Build Coastguard Worker      *we have the last buffer since we need to flush out the on remainig recon.
498*495ae853SAndroid Build Coastguard Worker      ****************************************************************************/
499*495ae853SAndroid Build Coastguard Worker 
500*495ae853SAndroid Build Coastguard Worker     ps_video_encode_op->s_ive_op.dump_recon = 0;
501*495ae853SAndroid Build Coastguard Worker 
502*495ae853SAndroid Build Coastguard Worker     if(ps_codec->s_cfg.u4_enable_recon &&
503*495ae853SAndroid Build Coastguard Worker        ((ps_codec->i4_pic_cnt > (WORD32) ps_codec->s_cfg.u4_num_bframes) ||
504*495ae853SAndroid Build Coastguard Worker         s_inp_buf.s_inp_props.u4_is_last))
505*495ae853SAndroid Build Coastguard Worker     {
506*495ae853SAndroid Build Coastguard Worker         /* error status */
507*495ae853SAndroid Build Coastguard Worker         IH264_ERROR_T ret = IH264_SUCCESS;
508*495ae853SAndroid Build Coastguard Worker 
509*495ae853SAndroid Build Coastguard Worker         svc_au_buf_t *ps_pic_buf = NULL;
510*495ae853SAndroid Build Coastguard Worker 
511*495ae853SAndroid Build Coastguard Worker         WORD32 i4_buf_status, i4_curr_poc = 32768;
512*495ae853SAndroid Build Coastguard Worker 
513*495ae853SAndroid Build Coastguard Worker         /* In case of skips we return recon, but indicate that buffer is zero size
514*495ae853SAndroid Build Coastguard Worker          */
515*495ae853SAndroid Build Coastguard Worker         if(ps_codec->s_rate_control.post_encode_skip[ctxt_sel] || i4_rc_pre_enc_skip)
516*495ae853SAndroid Build Coastguard Worker         {
517*495ae853SAndroid Build Coastguard Worker             ps_video_encode_op->s_ive_op.dump_recon = 1;
518*495ae853SAndroid Build Coastguard Worker             ps_video_encode_op->s_ive_op.s_recon_buf.au4_wd[0] = 0;
519*495ae853SAndroid Build Coastguard Worker             ps_video_encode_op->s_ive_op.s_recon_buf.au4_wd[1] = 0;
520*495ae853SAndroid Build Coastguard Worker         }
521*495ae853SAndroid Build Coastguard Worker         else
522*495ae853SAndroid Build Coastguard Worker         {
523*495ae853SAndroid Build Coastguard Worker             for(i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
524*495ae853SAndroid Build Coastguard Worker             {
525*495ae853SAndroid Build Coastguard Worker                 if(ps_codec->as_ref_set[i].i4_pic_cnt == -1) continue;
526*495ae853SAndroid Build Coastguard Worker 
527*495ae853SAndroid Build Coastguard Worker                 i4_buf_status = ih264_buf_mgr_get_status(
528*495ae853SAndroid Build Coastguard Worker                     ps_codec->pv_ref_buf_mgr, ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
529*495ae853SAndroid Build Coastguard Worker 
530*495ae853SAndroid Build Coastguard Worker                 if((i4_buf_status & BUF_MGR_IO) && (ps_codec->as_ref_set[i].i4_poc < i4_curr_poc))
531*495ae853SAndroid Build Coastguard Worker                 {
532*495ae853SAndroid Build Coastguard Worker                     ps_pic_buf = ps_codec->as_ref_set[i].ps_pic_buf;
533*495ae853SAndroid Build Coastguard Worker                     i4_curr_poc = ps_codec->as_ref_set[i].i4_poc;
534*495ae853SAndroid Build Coastguard Worker                 }
535*495ae853SAndroid Build Coastguard Worker             }
536*495ae853SAndroid Build Coastguard Worker 
537*495ae853SAndroid Build Coastguard Worker             ps_video_encode_op->s_ive_op.s_recon_buf = ps_video_encode_ip->s_ive_ip.s_recon_buf;
538*495ae853SAndroid Build Coastguard Worker 
539*495ae853SAndroid Build Coastguard Worker             /*
540*495ae853SAndroid Build Coastguard Worker              * If we get a valid buffer. output and free recon.
541*495ae853SAndroid Build Coastguard Worker              *
542*495ae853SAndroid Build Coastguard Worker              * we may get an invalid buffer if num_b_frames is 0. This is because
543*495ae853SAndroid Build Coastguard Worker              * We assume that there will be a ref frame in ref list after encoding
544*495ae853SAndroid Build Coastguard Worker              * the last frame. With B frames this is correct since its forward ref
545*495ae853SAndroid Build Coastguard Worker              * pic will be in the ref list. But if num_b_frames is 0, we will not
546*495ae853SAndroid Build Coastguard Worker              * have a forward ref pic
547*495ae853SAndroid Build Coastguard Worker              */
548*495ae853SAndroid Build Coastguard Worker 
549*495ae853SAndroid Build Coastguard Worker             if(ps_pic_buf)
550*495ae853SAndroid Build Coastguard Worker             {
551*495ae853SAndroid Build Coastguard Worker                 if((ps_video_encode_ip->s_ive_ip.s_recon_buf.au4_wd[Y] !=
552*495ae853SAndroid Build Coastguard Worker                     ps_codec->s_cfg.u4_disp_wd) ||
553*495ae853SAndroid Build Coastguard Worker                    (ps_video_encode_ip->s_ive_ip.s_recon_buf.au4_ht[Y] !=
554*495ae853SAndroid Build Coastguard Worker                     ps_codec->s_cfg.u4_disp_ht))
555*495ae853SAndroid Build Coastguard Worker                 {
556*495ae853SAndroid Build Coastguard Worker                     SET_ERROR_ON_RETURN(IH264E_NO_FREE_RECONBUF, IVE_FATALERROR,
557*495ae853SAndroid Build Coastguard Worker                                         ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL);
558*495ae853SAndroid Build Coastguard Worker                 }
559*495ae853SAndroid Build Coastguard Worker 
560*495ae853SAndroid Build Coastguard Worker                 isvce_fmt_conv(ps_codec, ps_pic_buf,
561*495ae853SAndroid Build Coastguard Worker                                ps_video_encode_ip->s_ive_ip.s_recon_buf.apv_bufs[0],
562*495ae853SAndroid Build Coastguard Worker                                ps_video_encode_ip->s_ive_ip.s_recon_buf.apv_bufs[1],
563*495ae853SAndroid Build Coastguard Worker                                ps_video_encode_ip->s_ive_ip.s_recon_buf.apv_bufs[2],
564*495ae853SAndroid Build Coastguard Worker                                ps_video_encode_ip->s_ive_ip.s_recon_buf.au4_wd[0],
565*495ae853SAndroid Build Coastguard Worker                                ps_video_encode_ip->s_ive_ip.s_recon_buf.au4_wd[1], 0,
566*495ae853SAndroid Build Coastguard Worker                                ps_codec->s_cfg.u4_disp_ht);
567*495ae853SAndroid Build Coastguard Worker 
568*495ae853SAndroid Build Coastguard Worker                 ps_video_encode_op->s_ive_op.dump_recon = 1;
569*495ae853SAndroid Build Coastguard Worker 
570*495ae853SAndroid Build Coastguard Worker                 ret = ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr, ps_pic_buf->i4_buf_id,
571*495ae853SAndroid Build Coastguard Worker                                             BUF_MGR_IO);
572*495ae853SAndroid Build Coastguard Worker 
573*495ae853SAndroid Build Coastguard Worker                 if(IH264_SUCCESS != ret)
574*495ae853SAndroid Build Coastguard Worker                 {
575*495ae853SAndroid Build Coastguard Worker                     SET_ERROR_ON_RETURN((IH264E_ERROR_T) ret, IVE_FATALERROR,
576*495ae853SAndroid Build Coastguard Worker                                         ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL);
577*495ae853SAndroid Build Coastguard Worker                 }
578*495ae853SAndroid Build Coastguard Worker             }
579*495ae853SAndroid Build Coastguard Worker         }
580*495ae853SAndroid Build Coastguard Worker     }
581*495ae853SAndroid Build Coastguard Worker 
582*495ae853SAndroid Build Coastguard Worker     /***************************************************************************
583*495ae853SAndroid Build Coastguard Worker      * Free reference buffers:
584*495ae853SAndroid Build Coastguard Worker      * In case of a post enc skip, we have to ensure that those pics will not
585*495ae853SAndroid Build Coastguard Worker      * be used as reference anymore. In all other cases we will not even mark
586*495ae853SAndroid Build Coastguard Worker      * the ref buffers
587*495ae853SAndroid Build Coastguard Worker      ***************************************************************************/
588*495ae853SAndroid Build Coastguard Worker     if(ps_codec->s_rate_control.post_encode_skip[ctxt_sel])
589*495ae853SAndroid Build Coastguard Worker     {
590*495ae853SAndroid Build Coastguard Worker         /* pic info */
591*495ae853SAndroid Build Coastguard Worker         svc_au_buf_t *ps_cur_pic;
592*495ae853SAndroid Build Coastguard Worker 
593*495ae853SAndroid Build Coastguard Worker         /* mv info */
594*495ae853SAndroid Build Coastguard Worker         svc_au_data_t *ps_cur_mv_buf;
595*495ae853SAndroid Build Coastguard Worker 
596*495ae853SAndroid Build Coastguard Worker         /* error status */
597*495ae853SAndroid Build Coastguard Worker         IH264_ERROR_T ret = IH264_SUCCESS;
598*495ae853SAndroid Build Coastguard Worker 
599*495ae853SAndroid Build Coastguard Worker         /* Decrement coded pic count */
600*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_poc--;
601*495ae853SAndroid Build Coastguard Worker 
602*495ae853SAndroid Build Coastguard Worker         /* loop through to get the min pic cnt among the list of pics stored in ref
603*495ae853SAndroid Build Coastguard Worker          * list */
604*495ae853SAndroid Build Coastguard Worker         /* since the skipped frame may not be on reference list, we may not have an
605*495ae853SAndroid Build Coastguard Worker          * MV bank hence free only if we have allocated */
606*495ae853SAndroid Build Coastguard Worker         for(i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
607*495ae853SAndroid Build Coastguard Worker         {
608*495ae853SAndroid Build Coastguard Worker             if(ps_codec->i4_pic_cnt == ps_codec->as_ref_set[i].i4_pic_cnt)
609*495ae853SAndroid Build Coastguard Worker             {
610*495ae853SAndroid Build Coastguard Worker                 ps_cur_pic = ps_codec->as_ref_set[i].ps_pic_buf;
611*495ae853SAndroid Build Coastguard Worker 
612*495ae853SAndroid Build Coastguard Worker                 ps_cur_mv_buf = ps_codec->as_ref_set[i].ps_svc_au_data;
613*495ae853SAndroid Build Coastguard Worker 
614*495ae853SAndroid Build Coastguard Worker                 /* release this frame from reference list and recon list */
615*495ae853SAndroid Build Coastguard Worker                 ret = ih264_buf_mgr_release(ps_codec->pv_svc_au_data_store_mgr,
616*495ae853SAndroid Build Coastguard Worker                                             ps_cur_mv_buf->i4_buf_id, BUF_MGR_REF);
617*495ae853SAndroid Build Coastguard Worker                 ret |= ih264_buf_mgr_release(ps_codec->pv_svc_au_data_store_mgr,
618*495ae853SAndroid Build Coastguard Worker                                              ps_cur_mv_buf->i4_buf_id, BUF_MGR_IO);
619*495ae853SAndroid Build Coastguard Worker                 SET_ERROR_ON_RETURN((IH264E_ERROR_T) ret, IVE_FATALERROR,
620*495ae853SAndroid Build Coastguard Worker                                     ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL);
621*495ae853SAndroid Build Coastguard Worker 
622*495ae853SAndroid Build Coastguard Worker                 ret = ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr, ps_cur_pic->i4_buf_id,
623*495ae853SAndroid Build Coastguard Worker                                             BUF_MGR_REF);
624*495ae853SAndroid Build Coastguard Worker                 ret |= ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr, ps_cur_pic->i4_buf_id,
625*495ae853SAndroid Build Coastguard Worker                                              BUF_MGR_IO);
626*495ae853SAndroid Build Coastguard Worker                 SET_ERROR_ON_RETURN((IH264E_ERROR_T) ret, IVE_FATALERROR,
627*495ae853SAndroid Build Coastguard Worker                                     ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL);
628*495ae853SAndroid Build Coastguard Worker                 break;
629*495ae853SAndroid Build Coastguard Worker             }
630*495ae853SAndroid Build Coastguard Worker         }
631*495ae853SAndroid Build Coastguard Worker     }
632*495ae853SAndroid Build Coastguard Worker 
633*495ae853SAndroid Build Coastguard Worker     /*
634*495ae853SAndroid Build Coastguard Worker      * Since recon is not in sync with output, ie there can be frame to be
635*495ae853SAndroid Build Coastguard Worker      * given back as recon even after last output. Hence we need to mark that
636*495ae853SAndroid Build Coastguard Worker      * the output is not the last.
637*495ae853SAndroid Build Coastguard Worker      * Hence search through reflist and mark appropriately
638*495ae853SAndroid Build Coastguard Worker      */
639*495ae853SAndroid Build Coastguard Worker     if(ps_codec->s_cfg.u4_enable_recon)
640*495ae853SAndroid Build Coastguard Worker     {
641*495ae853SAndroid Build Coastguard Worker         WORD32 i4_buf_status = 0;
642*495ae853SAndroid Build Coastguard Worker 
643*495ae853SAndroid Build Coastguard Worker         for(i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
644*495ae853SAndroid Build Coastguard Worker         {
645*495ae853SAndroid Build Coastguard Worker             if(ps_codec->as_ref_set[i].i4_pic_cnt == -1) continue;
646*495ae853SAndroid Build Coastguard Worker 
647*495ae853SAndroid Build Coastguard Worker             i4_buf_status |= ih264_buf_mgr_get_status(
648*495ae853SAndroid Build Coastguard Worker                 ps_codec->pv_ref_buf_mgr, ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
649*495ae853SAndroid Build Coastguard Worker         }
650*495ae853SAndroid Build Coastguard Worker 
651*495ae853SAndroid Build Coastguard Worker         if(i4_buf_status & BUF_MGR_IO)
652*495ae853SAndroid Build Coastguard Worker         {
653*495ae853SAndroid Build Coastguard Worker             s_out_buf.u4_is_last = 0;
654*495ae853SAndroid Build Coastguard Worker             ps_video_encode_op->s_ive_op.u4_is_last = 0;
655*495ae853SAndroid Build Coastguard Worker         }
656*495ae853SAndroid Build Coastguard Worker     }
657*495ae853SAndroid Build Coastguard Worker 
658*495ae853SAndroid Build Coastguard Worker     /**************************************************************************
659*495ae853SAndroid Build Coastguard Worker      * Signaling to APP
660*495ae853SAndroid Build Coastguard Worker      *  1) If we valid a valid output mark it so
661*495ae853SAndroid Build Coastguard Worker      *  2) Set the codec output ps_video_encode_op
662*495ae853SAndroid Build Coastguard Worker      *  3) Set the error status
663*495ae853SAndroid Build Coastguard Worker      *  4) Set the return Pic type
664*495ae853SAndroid Build Coastguard Worker      *      Note that we already has marked recon properly
665*495ae853SAndroid Build Coastguard Worker      *  5)Send the consumed input back to app so that it can free it if possible
666*495ae853SAndroid Build Coastguard Worker      *
667*495ae853SAndroid Build Coastguard Worker      *  We will have to return the output and input buffers unconditionally
668*495ae853SAndroid Build Coastguard Worker      *  so that app can release them
669*495ae853SAndroid Build Coastguard Worker      **************************************************************************/
670*495ae853SAndroid Build Coastguard Worker     if(!i4_rc_pre_enc_skip && !ps_codec->s_rate_control.post_encode_skip[ctxt_sel] &&
671*495ae853SAndroid Build Coastguard Worker        s_inp_buf.s_inp_props.s_raw_buf.apv_bufs[0])
672*495ae853SAndroid Build Coastguard Worker     {
673*495ae853SAndroid Build Coastguard Worker         /* receive output back from codec */
674*495ae853SAndroid Build Coastguard Worker         s_out_buf = ps_codec->as_out_buf[ctxt_sel];
675*495ae853SAndroid Build Coastguard Worker 
676*495ae853SAndroid Build Coastguard Worker         /* send the output to app */
677*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.output_present = 1;
678*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.u4_error_code = IV_SUCCESS;
679*495ae853SAndroid Build Coastguard Worker 
680*495ae853SAndroid Build Coastguard Worker         /* Set the time stamps of the encodec input */
681*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.u4_timestamp_low = s_inp_buf.s_inp_props.u4_timestamp_low;
682*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.u4_timestamp_high = s_inp_buf.s_inp_props.u4_timestamp_high;
683*495ae853SAndroid Build Coastguard Worker 
684*495ae853SAndroid Build Coastguard Worker         switch(ps_codec->pic_type)
685*495ae853SAndroid Build Coastguard Worker         {
686*495ae853SAndroid Build Coastguard Worker             case PIC_IDR:
687*495ae853SAndroid Build Coastguard Worker                 ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_IDR_FRAME;
688*495ae853SAndroid Build Coastguard Worker                 break;
689*495ae853SAndroid Build Coastguard Worker 
690*495ae853SAndroid Build Coastguard Worker             case PIC_I:
691*495ae853SAndroid Build Coastguard Worker                 ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_I_FRAME;
692*495ae853SAndroid Build Coastguard Worker                 break;
693*495ae853SAndroid Build Coastguard Worker 
694*495ae853SAndroid Build Coastguard Worker             case PIC_P:
695*495ae853SAndroid Build Coastguard Worker                 ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_P_FRAME;
696*495ae853SAndroid Build Coastguard Worker                 break;
697*495ae853SAndroid Build Coastguard Worker 
698*495ae853SAndroid Build Coastguard Worker             case PIC_B:
699*495ae853SAndroid Build Coastguard Worker                 ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_B_FRAME;
700*495ae853SAndroid Build Coastguard Worker                 break;
701*495ae853SAndroid Build Coastguard Worker 
702*495ae853SAndroid Build Coastguard Worker             default:
703*495ae853SAndroid Build Coastguard Worker                 ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_NA_FRAME;
704*495ae853SAndroid Build Coastguard Worker                 break;
705*495ae853SAndroid Build Coastguard Worker         }
706*495ae853SAndroid Build Coastguard Worker 
707*495ae853SAndroid Build Coastguard Worker         for(i = 0; i < (WORD32) ps_codec->s_cfg.u4_num_cores; i++)
708*495ae853SAndroid Build Coastguard Worker         {
709*495ae853SAndroid Build Coastguard Worker             error_status = ps_codec->as_process[ctxt_sel + i].i4_error_code;
710*495ae853SAndroid Build Coastguard Worker             SET_ERROR_ON_RETURN(error_status, IVE_FATALERROR,
711*495ae853SAndroid Build Coastguard Worker                                 ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL);
712*495ae853SAndroid Build Coastguard Worker         }
713*495ae853SAndroid Build Coastguard Worker     }
714*495ae853SAndroid Build Coastguard Worker     else
715*495ae853SAndroid Build Coastguard Worker     {
716*495ae853SAndroid Build Coastguard Worker         /* receive output back from codec */
717*495ae853SAndroid Build Coastguard Worker         s_out_buf = ps_codec->as_out_buf[ctxt_sel];
718*495ae853SAndroid Build Coastguard Worker 
719*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.output_present = 0;
720*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.u4_error_code = IV_SUCCESS;
721*495ae853SAndroid Build Coastguard Worker 
722*495ae853SAndroid Build Coastguard Worker         /* Set the time stamps of the encodec input */
723*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.u4_timestamp_low = 0;
724*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.u4_timestamp_high = 0;
725*495ae853SAndroid Build Coastguard Worker 
726*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.s_inp_buf = s_inp_buf.s_inp_props.s_raw_buf;
727*495ae853SAndroid Build Coastguard Worker 
728*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_NA_FRAME;
729*495ae853SAndroid Build Coastguard Worker     }
730*495ae853SAndroid Build Coastguard Worker 
731*495ae853SAndroid Build Coastguard Worker     /* Send the input to encoder so that it can free it if possible */
732*495ae853SAndroid Build Coastguard Worker     ps_video_encode_op->s_ive_op.s_out_buf = ps_codec->as_out_buf[ctxt_sel].as_bits_buf[0];
733*495ae853SAndroid Build Coastguard Worker 
734*495ae853SAndroid Build Coastguard Worker     for(i = 1; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers; i++)
735*495ae853SAndroid Build Coastguard Worker     {
736*495ae853SAndroid Build Coastguard Worker         memmove(((UWORD8 *) ps_video_encode_op->s_ive_op.s_out_buf.pv_buf +
737*495ae853SAndroid Build Coastguard Worker                  ps_video_encode_op->s_ive_op.s_out_buf.u4_bytes),
738*495ae853SAndroid Build Coastguard Worker                 ps_codec->as_out_buf[ctxt_sel].as_bits_buf[i].pv_buf,
739*495ae853SAndroid Build Coastguard Worker                 ps_codec->as_out_buf[ctxt_sel].as_bits_buf[i].u4_bytes);
740*495ae853SAndroid Build Coastguard Worker 
741*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.s_out_buf.u4_bytes +=
742*495ae853SAndroid Build Coastguard Worker             ps_codec->as_out_buf[ctxt_sel].as_bits_buf[i].u4_bytes;
743*495ae853SAndroid Build Coastguard Worker     }
744*495ae853SAndroid Build Coastguard Worker 
745*495ae853SAndroid Build Coastguard Worker     if(ps_codec->s_cfg.b_nalu_info_export_enable && !i4_rc_pre_enc_skip &&
746*495ae853SAndroid Build Coastguard Worker        !ps_codec->s_rate_control.post_encode_skip[ctxt_sel] &&
747*495ae853SAndroid Build Coastguard Worker        s_inp_buf.s_inp_props.s_raw_buf.apv_bufs[0])
748*495ae853SAndroid Build Coastguard Worker     {
749*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->b_is_nalu_info_present = true;
750*495ae853SAndroid Build Coastguard Worker 
751*495ae853SAndroid Build Coastguard Worker         for(i = 0; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers; i++)
752*495ae853SAndroid Build Coastguard Worker         {
753*495ae853SAndroid Build Coastguard Worker             isvce_nalu_info_csv_translator(&ps_codec->as_nalu_descriptors[i],
754*495ae853SAndroid Build Coastguard Worker                                            &ps_video_encode_ip->ps_nalu_info_buf[i]);
755*495ae853SAndroid Build Coastguard Worker 
756*495ae853SAndroid Build Coastguard Worker             ps_video_encode_op->ps_nalu_info_buf[i] = ps_video_encode_ip->ps_nalu_info_buf[i];
757*495ae853SAndroid Build Coastguard Worker         }
758*495ae853SAndroid Build Coastguard Worker     }
759*495ae853SAndroid Build Coastguard Worker     else
760*495ae853SAndroid Build Coastguard Worker     {
761*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->b_is_nalu_info_present = false;
762*495ae853SAndroid Build Coastguard Worker     }
763*495ae853SAndroid Build Coastguard Worker 
764*495ae853SAndroid Build Coastguard Worker     ps_video_encode_op->s_ive_op.s_inp_buf = s_inp_buf.s_inp_props.s_raw_buf;
765*495ae853SAndroid Build Coastguard Worker 
766*495ae853SAndroid Build Coastguard Worker     return IV_SUCCESS;
767*495ae853SAndroid Build Coastguard Worker }
768