xref: /aosp_15_r20/external/libavc/encoder/ih264e_encode.c (revision 495ae853bb871d1e5a258cb02c2cc13cde8ddb9a)
1*495ae853SAndroid Build Coastguard Worker /******************************************************************************
2*495ae853SAndroid Build Coastguard Worker  *
3*495ae853SAndroid Build Coastguard Worker  * Copyright (C) 2015 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 *  ih264e_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 *  - ih264e_join_threads
35*495ae853SAndroid Build Coastguard Worker *  - ih264e_wait_for_thread
36*495ae853SAndroid Build Coastguard Worker *  - ih264e_encode
37*495ae853SAndroid Build Coastguard Worker *
38*495ae853SAndroid Build Coastguard Worker ******************************************************************************
39*495ae853SAndroid Build Coastguard Worker */
40*495ae853SAndroid Build Coastguard Worker 
41*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
42*495ae853SAndroid Build Coastguard Worker /* File Includes                                                             */
43*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
44*495ae853SAndroid Build Coastguard Worker 
45*495ae853SAndroid Build Coastguard Worker /* System Include files */
46*495ae853SAndroid Build Coastguard Worker #include <stdio.h>
47*495ae853SAndroid Build Coastguard Worker #include <stddef.h>
48*495ae853SAndroid Build Coastguard Worker #include <stdlib.h>
49*495ae853SAndroid Build Coastguard Worker #include <string.h>
50*495ae853SAndroid Build Coastguard Worker #include <assert.h>
51*495ae853SAndroid Build Coastguard Worker #include <limits.h>
52*495ae853SAndroid Build Coastguard Worker #include <stdbool.h>
53*495ae853SAndroid Build Coastguard Worker 
54*495ae853SAndroid Build Coastguard Worker /* User Include Files */
55*495ae853SAndroid Build Coastguard Worker #include "ih264e_config.h"
56*495ae853SAndroid Build Coastguard Worker #include "ih264_typedefs.h"
57*495ae853SAndroid Build Coastguard Worker #include "iv2.h"
58*495ae853SAndroid Build Coastguard Worker #include "ive2.h"
59*495ae853SAndroid Build Coastguard Worker #include "ithread.h"
60*495ae853SAndroid Build Coastguard Worker 
61*495ae853SAndroid Build Coastguard Worker #include "ih264_debug.h"
62*495ae853SAndroid Build Coastguard Worker #include "ih264_macros.h"
63*495ae853SAndroid Build Coastguard Worker #include "ih264_error.h"
64*495ae853SAndroid Build Coastguard Worker #include "ih264_defs.h"
65*495ae853SAndroid Build Coastguard Worker #include "ih264_mem_fns.h"
66*495ae853SAndroid Build Coastguard Worker #include "ih264_padding.h"
67*495ae853SAndroid Build Coastguard Worker #include "ih264_structs.h"
68*495ae853SAndroid Build Coastguard Worker #include "ih264_trans_quant_itrans_iquant.h"
69*495ae853SAndroid Build Coastguard Worker #include "ih264_inter_pred_filters.h"
70*495ae853SAndroid Build Coastguard Worker #include "ih264_intra_pred_filters.h"
71*495ae853SAndroid Build Coastguard Worker #include "ih264_deblk_edge_filters.h"
72*495ae853SAndroid Build Coastguard Worker #include "ih264_cabac_tables.h"
73*495ae853SAndroid Build Coastguard Worker #include "ih264_buf_mgr.h"
74*495ae853SAndroid Build Coastguard Worker #include "ih264_list.h"
75*495ae853SAndroid Build Coastguard Worker #include "ih264_dpb_mgr.h"
76*495ae853SAndroid Build Coastguard Worker #include "ih264_platform_macros.h"
77*495ae853SAndroid Build Coastguard Worker 
78*495ae853SAndroid Build Coastguard Worker #include "ime_defs.h"
79*495ae853SAndroid Build Coastguard Worker #include "ime_distortion_metrics.h"
80*495ae853SAndroid Build Coastguard Worker #include "ime_structs.h"
81*495ae853SAndroid Build Coastguard Worker 
82*495ae853SAndroid Build Coastguard Worker #include "irc_mem_req_and_acq.h"
83*495ae853SAndroid Build Coastguard Worker #include "irc_cntrl_param.h"
84*495ae853SAndroid Build Coastguard Worker #include "irc_frame_info_collector.h"
85*495ae853SAndroid Build Coastguard Worker 
86*495ae853SAndroid Build Coastguard Worker #include "ih264e.h"
87*495ae853SAndroid Build Coastguard Worker #include "ih264e_error.h"
88*495ae853SAndroid Build Coastguard Worker #include "ih264e_defs.h"
89*495ae853SAndroid Build Coastguard Worker #include "ih264e_time_stamp.h"
90*495ae853SAndroid Build Coastguard Worker #include "ih264e_rate_control.h"
91*495ae853SAndroid Build Coastguard Worker #include "ih264e_bitstream.h"
92*495ae853SAndroid Build Coastguard Worker #include "ih264e_cabac_structs.h"
93*495ae853SAndroid Build Coastguard Worker #include "ih264e_structs.h"
94*495ae853SAndroid Build Coastguard Worker #include "ih264e_utils.h"
95*495ae853SAndroid Build Coastguard Worker #include "ih264e_encode_header.h"
96*495ae853SAndroid Build Coastguard Worker #include "ih264e_master.h"
97*495ae853SAndroid Build Coastguard Worker #include "ih264e_process.h"
98*495ae853SAndroid Build Coastguard Worker #include "ih264e_fmt_conv.h"
99*495ae853SAndroid Build Coastguard Worker #include "ih264e_statistics.h"
100*495ae853SAndroid Build Coastguard Worker #include "ih264e_trace.h"
101*495ae853SAndroid Build Coastguard Worker #ifdef LOGO_EN
102*495ae853SAndroid Build Coastguard Worker #include "ih264e_ittiam_logo.h"
103*495ae853SAndroid Build Coastguard Worker #endif
104*495ae853SAndroid Build Coastguard Worker 
105*495ae853SAndroid Build Coastguard Worker 
106*495ae853SAndroid Build Coastguard Worker #define SEI_BASED_FORCE_IDR 1
107*495ae853SAndroid Build Coastguard Worker 
108*495ae853SAndroid Build Coastguard Worker /*****************************************************************************/
109*495ae853SAndroid Build Coastguard Worker /* Function Definitions                                                      */
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 *
115*495ae853SAndroid Build Coastguard Worker * @brief
116*495ae853SAndroid Build Coastguard Worker *  This function joins all the spawned threads after successful completion of
117*495ae853SAndroid Build Coastguard Worker *  their tasks
118*495ae853SAndroid Build Coastguard Worker *
119*495ae853SAndroid Build Coastguard Worker * @par   Description
120*495ae853SAndroid Build Coastguard Worker *
121*495ae853SAndroid Build Coastguard Worker * @param[in] ps_codec
122*495ae853SAndroid Build Coastguard Worker *  pointer to codec context
123*495ae853SAndroid Build Coastguard Worker *
124*495ae853SAndroid Build Coastguard Worker * @returns  none
125*495ae853SAndroid Build Coastguard Worker *
126*495ae853SAndroid Build Coastguard Worker ******************************************************************************
127*495ae853SAndroid Build Coastguard Worker */
ih264e_join_threads(codec_t * ps_codec)128*495ae853SAndroid Build Coastguard Worker void ih264e_join_threads(codec_t *ps_codec)
129*495ae853SAndroid Build Coastguard Worker {
130*495ae853SAndroid Build Coastguard Worker     /* temp var */
131*495ae853SAndroid Build Coastguard Worker    WORD32 i = 0;
132*495ae853SAndroid Build Coastguard Worker    WORD32 ret = 0;
133*495ae853SAndroid Build Coastguard Worker 
134*495ae853SAndroid Build Coastguard Worker    /* join spawned threads */
135*495ae853SAndroid Build Coastguard Worker    while (i < ps_codec->i4_proc_thread_cnt)
136*495ae853SAndroid Build Coastguard Worker    {
137*495ae853SAndroid Build Coastguard Worker        if (ps_codec->ai4_process_thread_created[i])
138*495ae853SAndroid Build Coastguard Worker        {
139*495ae853SAndroid Build Coastguard Worker            ret = ithread_join(ps_codec->apv_proc_thread_handle[i], NULL);
140*495ae853SAndroid Build Coastguard Worker            if (ret != 0)
141*495ae853SAndroid Build Coastguard Worker            {
142*495ae853SAndroid Build Coastguard Worker                printf("pthread Join Failed");
143*495ae853SAndroid Build Coastguard Worker                assert(0);
144*495ae853SAndroid Build Coastguard Worker            }
145*495ae853SAndroid Build Coastguard Worker            ps_codec->ai4_process_thread_created[i] = 0;
146*495ae853SAndroid Build Coastguard Worker            i++;
147*495ae853SAndroid Build Coastguard Worker        }
148*495ae853SAndroid Build Coastguard Worker    }
149*495ae853SAndroid Build Coastguard Worker 
150*495ae853SAndroid Build Coastguard Worker    ps_codec->i4_proc_thread_cnt = 0;
151*495ae853SAndroid Build Coastguard Worker }
152*495ae853SAndroid Build Coastguard Worker 
153*495ae853SAndroid Build Coastguard Worker /**
154*495ae853SAndroid Build Coastguard Worker ******************************************************************************
155*495ae853SAndroid Build Coastguard Worker *
156*495ae853SAndroid Build Coastguard Worker * @brief This function puts the current thread to sleep for a duration
157*495ae853SAndroid Build Coastguard Worker *  of sleep_us
158*495ae853SAndroid Build Coastguard Worker *
159*495ae853SAndroid Build Coastguard Worker * @par Description
160*495ae853SAndroid Build Coastguard Worker *  ithread_yield() method causes the calling thread to yield execution to another
161*495ae853SAndroid Build Coastguard Worker *  thread that is ready to run on the current processor. The operating system
162*495ae853SAndroid Build Coastguard Worker *  selects the thread to yield to. ithread_usleep blocks the current thread for
163*495ae853SAndroid Build Coastguard Worker *  the specified number of milliseconds. In other words, yield just says,
164*495ae853SAndroid Build Coastguard Worker *  end my timeslice prematurely, look around for other threads to run. If there
165*495ae853SAndroid Build Coastguard Worker *  is nothing better than me, continue. Sleep says I don't want to run for x
166*495ae853SAndroid Build Coastguard Worker *  milliseconds. Even if no other thread wants to run, don't make me run.
167*495ae853SAndroid Build Coastguard Worker *
168*495ae853SAndroid Build Coastguard Worker * @param[in] sleep_us
169*495ae853SAndroid Build Coastguard Worker *  thread sleep duration
170*495ae853SAndroid Build Coastguard Worker *
171*495ae853SAndroid Build Coastguard Worker * @returns error_status
172*495ae853SAndroid Build Coastguard Worker *
173*495ae853SAndroid Build Coastguard Worker ******************************************************************************
174*495ae853SAndroid Build Coastguard Worker */
ih264e_wait_for_thread(UWORD32 sleep_us)175*495ae853SAndroid Build Coastguard Worker IH264E_ERROR_T ih264e_wait_for_thread(UWORD32 sleep_us)
176*495ae853SAndroid Build Coastguard Worker {
177*495ae853SAndroid Build Coastguard Worker     /* yield thread */
178*495ae853SAndroid Build Coastguard Worker     ithread_yield();
179*495ae853SAndroid Build Coastguard Worker 
180*495ae853SAndroid Build Coastguard Worker     /* put thread to sleep */
181*495ae853SAndroid Build Coastguard Worker     ithread_usleep(sleep_us);
182*495ae853SAndroid Build Coastguard Worker 
183*495ae853SAndroid Build Coastguard Worker     return IH264E_SUCCESS;
184*495ae853SAndroid Build Coastguard Worker }
185*495ae853SAndroid Build Coastguard Worker 
186*495ae853SAndroid Build Coastguard Worker /**
187*495ae853SAndroid Build Coastguard Worker *******************************************************************************
188*495ae853SAndroid Build Coastguard Worker *
189*495ae853SAndroid Build Coastguard Worker * @brief
190*495ae853SAndroid Build Coastguard Worker *  Used to test validity of input dimensions
191*495ae853SAndroid Build Coastguard Worker *
192*495ae853SAndroid Build Coastguard Worker * @par Description:
193*495ae853SAndroid Build Coastguard Worker *  Dimensions of the input buffer passed to encode call are validated
194*495ae853SAndroid Build Coastguard Worker *
195*495ae853SAndroid Build Coastguard Worker * @param[in] ps_codec
196*495ae853SAndroid Build Coastguard Worker *  Codec context
197*495ae853SAndroid Build Coastguard Worker *
198*495ae853SAndroid Build Coastguard Worker * @param[in] ps_ip
199*495ae853SAndroid Build Coastguard Worker *  Pointer to input structure
200*495ae853SAndroid Build Coastguard Worker *
201*495ae853SAndroid Build Coastguard Worker * @param[out] ps_op
202*495ae853SAndroid Build Coastguard Worker *  Pointer to output structure
203*495ae853SAndroid Build Coastguard Worker *
204*495ae853SAndroid Build Coastguard Worker * @returns error status
205*495ae853SAndroid Build Coastguard Worker *
206*495ae853SAndroid Build Coastguard Worker * @remarks none
207*495ae853SAndroid Build Coastguard Worker *
208*495ae853SAndroid Build Coastguard Worker *******************************************************************************
209*495ae853SAndroid Build Coastguard Worker */
api_check_input_dimensions(codec_t * ps_codec,ih264e_video_encode_ip_t * ps_ip,ih264e_video_encode_op_t * ps_op)210*495ae853SAndroid Build Coastguard Worker static IV_STATUS_T api_check_input_dimensions(codec_t *ps_codec,
211*495ae853SAndroid Build Coastguard Worker                                               ih264e_video_encode_ip_t *ps_ip,
212*495ae853SAndroid Build Coastguard Worker                                               ih264e_video_encode_op_t *ps_op)
213*495ae853SAndroid Build Coastguard Worker {
214*495ae853SAndroid Build Coastguard Worker     UWORD32 u4_wd, u4_ht;
215*495ae853SAndroid Build Coastguard Worker     cfg_params_t *ps_curr_cfg = &ps_codec->s_cfg;
216*495ae853SAndroid Build Coastguard Worker     iv_raw_buf_t *ps_inp_buf = &ps_ip->s_ive_ip.s_inp_buf;
217*495ae853SAndroid Build Coastguard Worker 
218*495ae853SAndroid Build Coastguard Worker     u4_wd = ps_inp_buf->au4_wd[0];
219*495ae853SAndroid Build Coastguard Worker     u4_ht = ps_inp_buf->au4_ht[0];
220*495ae853SAndroid Build Coastguard Worker     switch (ps_inp_buf->e_color_fmt)
221*495ae853SAndroid Build Coastguard Worker     {
222*495ae853SAndroid Build Coastguard Worker         case IV_YUV_420P:
223*495ae853SAndroid Build Coastguard Worker             if (((ps_inp_buf->au4_wd[0] / 2) != ps_inp_buf->au4_wd[1]) ||
224*495ae853SAndroid Build Coastguard Worker                             ((ps_inp_buf->au4_wd[0] / 2) != ps_inp_buf->au4_wd[2]) ||
225*495ae853SAndroid Build Coastguard Worker                             (ps_inp_buf->au4_wd[1] != ps_inp_buf->au4_wd[2]))
226*495ae853SAndroid Build Coastguard Worker             {
227*495ae853SAndroid Build Coastguard Worker                 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
228*495ae853SAndroid Build Coastguard Worker                 ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED;
229*495ae853SAndroid Build Coastguard Worker                 return (IV_FAIL);
230*495ae853SAndroid Build Coastguard Worker             }
231*495ae853SAndroid Build Coastguard Worker             if (((ps_inp_buf->au4_ht[0] / 2) != ps_inp_buf->au4_ht[1]) ||
232*495ae853SAndroid Build Coastguard Worker                             ((ps_inp_buf->au4_ht[0] / 2) != ps_inp_buf->au4_ht[2]) ||
233*495ae853SAndroid Build Coastguard Worker                             (ps_inp_buf->au4_ht[1] != ps_inp_buf->au4_ht[2]))
234*495ae853SAndroid Build Coastguard Worker             {
235*495ae853SAndroid Build Coastguard Worker                 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
236*495ae853SAndroid Build Coastguard Worker                 ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED;
237*495ae853SAndroid Build Coastguard Worker                 return (IV_FAIL);
238*495ae853SAndroid Build Coastguard Worker             }
239*495ae853SAndroid Build Coastguard Worker             break;
240*495ae853SAndroid Build Coastguard Worker         case IV_YUV_420SP_UV:
241*495ae853SAndroid Build Coastguard Worker         case IV_YUV_420SP_VU:
242*495ae853SAndroid Build Coastguard Worker             if (ps_inp_buf->au4_wd[0] != ps_inp_buf->au4_wd[1])
243*495ae853SAndroid Build Coastguard Worker             {
244*495ae853SAndroid Build Coastguard Worker                 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
245*495ae853SAndroid Build Coastguard Worker                 ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED;
246*495ae853SAndroid Build Coastguard Worker                 return (IV_FAIL);
247*495ae853SAndroid Build Coastguard Worker             }
248*495ae853SAndroid Build Coastguard Worker             if ((ps_inp_buf->au4_ht[0] / 2) != ps_inp_buf->au4_ht[1])
249*495ae853SAndroid Build Coastguard Worker             {
250*495ae853SAndroid Build Coastguard Worker                 ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
251*495ae853SAndroid Build Coastguard Worker                 ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED;
252*495ae853SAndroid Build Coastguard Worker                 return (IV_FAIL);
253*495ae853SAndroid Build Coastguard Worker             }
254*495ae853SAndroid Build Coastguard Worker             break;
255*495ae853SAndroid Build Coastguard Worker         case IV_YUV_422ILE:
256*495ae853SAndroid Build Coastguard Worker             u4_wd = ps_inp_buf->au4_wd[0] / 2;
257*495ae853SAndroid Build Coastguard Worker             break;
258*495ae853SAndroid Build Coastguard Worker         default:
259*495ae853SAndroid Build Coastguard Worker             ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
260*495ae853SAndroid Build Coastguard Worker             ps_op->s_ive_op.u4_error_code |= IH264E_INPUT_CHROMA_FORMAT_NOT_SUPPORTED;
261*495ae853SAndroid Build Coastguard Worker             return (IV_FAIL);
262*495ae853SAndroid Build Coastguard Worker     }
263*495ae853SAndroid Build Coastguard Worker 
264*495ae853SAndroid Build Coastguard Worker     if (u4_wd != ps_curr_cfg->u4_disp_wd)
265*495ae853SAndroid Build Coastguard Worker     {
266*495ae853SAndroid Build Coastguard Worker         ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
267*495ae853SAndroid Build Coastguard Worker         ps_op->s_ive_op.u4_error_code |= IH264E_WIDTH_NOT_SUPPORTED;
268*495ae853SAndroid Build Coastguard Worker         return (IV_FAIL);
269*495ae853SAndroid Build Coastguard Worker     }
270*495ae853SAndroid Build Coastguard Worker 
271*495ae853SAndroid Build Coastguard Worker     if (u4_ht != ps_curr_cfg->u4_disp_ht)
272*495ae853SAndroid Build Coastguard Worker     {
273*495ae853SAndroid Build Coastguard Worker         ps_op->s_ive_op.u4_error_code |= 1 << IVE_UNSUPPORTEDPARAM;
274*495ae853SAndroid Build Coastguard Worker         ps_op->s_ive_op.u4_error_code |= IH264E_HEIGHT_NOT_SUPPORTED;
275*495ae853SAndroid Build Coastguard Worker         return (IV_FAIL);
276*495ae853SAndroid Build Coastguard Worker     }
277*495ae853SAndroid Build Coastguard Worker 
278*495ae853SAndroid Build Coastguard Worker     return IV_SUCCESS;
279*495ae853SAndroid Build Coastguard Worker }
280*495ae853SAndroid Build Coastguard Worker 
281*495ae853SAndroid Build Coastguard Worker /**
282*495ae853SAndroid Build Coastguard Worker ******************************************************************************
283*495ae853SAndroid Build Coastguard Worker *
284*495ae853SAndroid Build Coastguard Worker * @brief
285*495ae853SAndroid Build Coastguard Worker *  Encodes in synchronous api mode
286*495ae853SAndroid Build Coastguard Worker *
287*495ae853SAndroid Build Coastguard Worker * @par Description
288*495ae853SAndroid Build Coastguard Worker *  This routine processes input yuv, encodes it and outputs bitstream and recon
289*495ae853SAndroid Build Coastguard Worker *
290*495ae853SAndroid Build Coastguard Worker * @param[in] ps_codec_obj
291*495ae853SAndroid Build Coastguard Worker *  Pointer to codec object at API level
292*495ae853SAndroid Build Coastguard Worker *
293*495ae853SAndroid Build Coastguard Worker * @param[in] pv_api_ip
294*495ae853SAndroid Build Coastguard Worker *  Pointer to input argument structure
295*495ae853SAndroid Build Coastguard Worker *
296*495ae853SAndroid Build Coastguard Worker * @param[out] pv_api_op
297*495ae853SAndroid Build Coastguard Worker *  Pointer to output argument structure
298*495ae853SAndroid Build Coastguard Worker *
299*495ae853SAndroid Build Coastguard Worker * @returns  Status
300*495ae853SAndroid Build Coastguard Worker *
301*495ae853SAndroid Build Coastguard Worker ******************************************************************************
302*495ae853SAndroid Build Coastguard Worker */
ih264e_encode(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)303*495ae853SAndroid Build Coastguard Worker WORD32 ih264e_encode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
304*495ae853SAndroid Build Coastguard Worker {
305*495ae853SAndroid Build Coastguard Worker     /* error status */
306*495ae853SAndroid Build Coastguard Worker     IH264E_ERROR_T error_status = IH264E_SUCCESS;
307*495ae853SAndroid Build Coastguard Worker 
308*495ae853SAndroid Build Coastguard Worker     /* codec ctxt */
309*495ae853SAndroid Build Coastguard Worker     codec_t *ps_codec = (codec_t *)ps_codec_obj->pv_codec_handle;
310*495ae853SAndroid Build Coastguard Worker 
311*495ae853SAndroid Build Coastguard Worker     /* input frame to encode */
312*495ae853SAndroid Build Coastguard Worker     ih264e_video_encode_ip_t *ps_video_encode_ip = pv_api_ip;
313*495ae853SAndroid Build Coastguard Worker 
314*495ae853SAndroid Build Coastguard Worker     /* output buffer to write stream */
315*495ae853SAndroid Build Coastguard Worker     ih264e_video_encode_op_t *ps_video_encode_op = pv_api_op;
316*495ae853SAndroid Build Coastguard Worker 
317*495ae853SAndroid Build Coastguard Worker     /* i/o structures */
318*495ae853SAndroid Build Coastguard Worker     inp_buf_t s_inp_buf = {};
319*495ae853SAndroid Build Coastguard Worker     out_buf_t s_out_buf = {};
320*495ae853SAndroid Build Coastguard Worker 
321*495ae853SAndroid Build Coastguard Worker     /* temp var */
322*495ae853SAndroid Build Coastguard Worker     WORD32 ctxt_sel = 0, i, i4_rc_pre_enc_skip;
323*495ae853SAndroid Build Coastguard Worker 
324*495ae853SAndroid Build Coastguard Worker     /********************************************************************/
325*495ae853SAndroid Build Coastguard Worker     /*                            BEGIN INIT                            */
326*495ae853SAndroid Build Coastguard Worker     /********************************************************************/
327*495ae853SAndroid Build Coastguard Worker     /* reset output structure */
328*495ae853SAndroid Build Coastguard Worker     ps_video_encode_op->s_ive_op.u4_error_code = IV_SUCCESS;
329*495ae853SAndroid Build Coastguard Worker     ps_video_encode_op->s_ive_op.output_present  = 0;
330*495ae853SAndroid Build Coastguard Worker     ps_video_encode_op->s_ive_op.dump_recon = 0;
331*495ae853SAndroid Build Coastguard Worker     ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_NA_FRAME;
332*495ae853SAndroid Build Coastguard Worker     /* By default set the current input buffer as the buffer to be freed */
333*495ae853SAndroid Build Coastguard Worker     /* This will later be updated to the actual input that gets encoded */
334*495ae853SAndroid Build Coastguard Worker     ps_video_encode_op->s_ive_op.s_inp_buf = ps_video_encode_ip->s_ive_ip.s_inp_buf;
335*495ae853SAndroid Build Coastguard Worker 
336*495ae853SAndroid Build Coastguard Worker     if (ps_codec->i4_error_code & (1 << IVE_FATALERROR))
337*495ae853SAndroid Build Coastguard Worker     {
338*495ae853SAndroid Build Coastguard Worker         error_status = ps_codec->i4_error_code & 0xFF;
339*495ae853SAndroid Build Coastguard Worker         SET_ERROR_ON_RETURN(error_status,
340*495ae853SAndroid Build Coastguard Worker                             IVE_FATALERROR,
341*495ae853SAndroid Build Coastguard Worker                             ps_video_encode_op->s_ive_op.u4_error_code,
342*495ae853SAndroid Build Coastguard Worker                             IV_FAIL);
343*495ae853SAndroid Build Coastguard Worker     }
344*495ae853SAndroid Build Coastguard Worker 
345*495ae853SAndroid Build Coastguard Worker     /* Check for output memory allocation size */
346*495ae853SAndroid Build Coastguard Worker     if (ps_video_encode_ip->s_ive_ip.s_out_buf.u4_bufsize < MIN_STREAM_SIZE)
347*495ae853SAndroid Build Coastguard Worker     {
348*495ae853SAndroid Build Coastguard Worker         error_status = IH264E_INSUFFICIENT_OUTPUT_BUFFER;
349*495ae853SAndroid Build Coastguard Worker         SET_ERROR_ON_RETURN(error_status,
350*495ae853SAndroid Build Coastguard Worker                             IVE_UNSUPPORTEDPARAM,
351*495ae853SAndroid Build Coastguard Worker                             ps_video_encode_op->s_ive_op.u4_error_code,
352*495ae853SAndroid Build Coastguard Worker                             IV_FAIL);
353*495ae853SAndroid Build Coastguard Worker     }
354*495ae853SAndroid Build Coastguard Worker 
355*495ae853SAndroid Build Coastguard Worker     if (ps_codec->i4_init_done != 1)
356*495ae853SAndroid Build Coastguard Worker     {
357*495ae853SAndroid Build Coastguard Worker         error_status = IH264E_INIT_NOT_DONE;
358*495ae853SAndroid Build Coastguard Worker         SET_ERROR_ON_RETURN(error_status,
359*495ae853SAndroid Build Coastguard Worker                             IVE_FATALERROR,
360*495ae853SAndroid Build Coastguard Worker                             ps_video_encode_op->s_ive_op.u4_error_code,
361*495ae853SAndroid Build Coastguard Worker                             IV_FAIL);
362*495ae853SAndroid Build Coastguard Worker     }
363*495ae853SAndroid Build Coastguard Worker 
364*495ae853SAndroid Build Coastguard Worker     /* copy output info. to internal structure */
365*495ae853SAndroid Build Coastguard Worker     s_out_buf.s_bits_buf = ps_video_encode_ip->s_ive_ip.s_out_buf;
366*495ae853SAndroid Build Coastguard Worker     s_out_buf.u4_is_last = 0;
367*495ae853SAndroid Build Coastguard Worker     s_out_buf.u4_timestamp_low = ps_video_encode_ip->s_ive_ip.u4_timestamp_low;
368*495ae853SAndroid Build Coastguard Worker     s_out_buf.u4_timestamp_high = ps_video_encode_ip->s_ive_ip.u4_timestamp_high;
369*495ae853SAndroid Build Coastguard Worker 
370*495ae853SAndroid Build Coastguard Worker     /* api call cnt */
371*495ae853SAndroid Build Coastguard Worker     ps_codec->i4_encode_api_call_cnt += 1;
372*495ae853SAndroid Build Coastguard Worker 
373*495ae853SAndroid Build Coastguard Worker     /* codec context selector */
374*495ae853SAndroid Build Coastguard Worker     ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS;
375*495ae853SAndroid Build Coastguard Worker 
376*495ae853SAndroid Build Coastguard Worker     /* reset status flags */
377*495ae853SAndroid Build Coastguard Worker     ps_codec->ai4_pic_cnt[ctxt_sel] = -1;
378*495ae853SAndroid Build Coastguard Worker     ps_codec->s_rate_control.post_encode_skip[ctxt_sel] = 0;
379*495ae853SAndroid Build Coastguard Worker     ps_codec->s_rate_control.pre_encode_skip[ctxt_sel] = 0;
380*495ae853SAndroid Build Coastguard Worker 
381*495ae853SAndroid Build Coastguard Worker     /* pass output buffer to codec */
382*495ae853SAndroid Build Coastguard Worker     ps_codec->as_out_buf[ctxt_sel] = s_out_buf;
383*495ae853SAndroid Build Coastguard Worker 
384*495ae853SAndroid Build Coastguard Worker     /* initialize codec ctxt with default params for the first encode api call */
385*495ae853SAndroid Build Coastguard Worker     if (ps_codec->i4_encode_api_call_cnt == 0)
386*495ae853SAndroid Build Coastguard Worker     {
387*495ae853SAndroid Build Coastguard Worker         ih264e_codec_init(ps_codec);
388*495ae853SAndroid Build Coastguard Worker     }
389*495ae853SAndroid Build Coastguard Worker 
390*495ae853SAndroid Build Coastguard Worker     /* parse configuration params */
391*495ae853SAndroid Build Coastguard Worker     for (i = 0; i < MAX_ACTIVE_CONFIG_PARAMS; i++)
392*495ae853SAndroid Build Coastguard Worker     {
393*495ae853SAndroid Build Coastguard Worker         cfg_params_t *ps_cfg = &ps_codec->as_cfg[i];
394*495ae853SAndroid Build Coastguard Worker 
395*495ae853SAndroid Build Coastguard Worker         if (1 == ps_cfg->u4_is_valid)
396*495ae853SAndroid Build Coastguard Worker         {
397*495ae853SAndroid Build Coastguard Worker             if ( ((ps_cfg->u4_timestamp_high == ps_video_encode_ip->s_ive_ip.u4_timestamp_high) &&
398*495ae853SAndroid Build Coastguard Worker                             (ps_cfg->u4_timestamp_low == ps_video_encode_ip->s_ive_ip.u4_timestamp_low)) ||
399*495ae853SAndroid Build Coastguard Worker                             ((WORD32)ps_cfg->u4_timestamp_high == -1) ||
400*495ae853SAndroid Build Coastguard Worker                             ((WORD32)ps_cfg->u4_timestamp_low == -1) )
401*495ae853SAndroid Build Coastguard Worker             {
402*495ae853SAndroid Build Coastguard Worker                 error_status = ih264e_codec_update_config(ps_codec, ps_cfg);
403*495ae853SAndroid Build Coastguard Worker                 SET_ERROR_ON_RETURN(error_status,
404*495ae853SAndroid Build Coastguard Worker                                     IVE_FATALERROR,
405*495ae853SAndroid Build Coastguard Worker                                     ps_video_encode_op->s_ive_op.u4_error_code,
406*495ae853SAndroid Build Coastguard Worker                                     IV_FAIL);
407*495ae853SAndroid Build Coastguard Worker 
408*495ae853SAndroid Build Coastguard Worker                 ps_cfg->u4_is_valid = 0;
409*495ae853SAndroid Build Coastguard Worker             }
410*495ae853SAndroid Build Coastguard Worker         }
411*495ae853SAndroid Build Coastguard Worker     }
412*495ae853SAndroid Build Coastguard Worker     /* Force IDR based on SEI params */
413*495ae853SAndroid Build Coastguard Worker #if SEI_BASED_FORCE_IDR
414*495ae853SAndroid Build Coastguard Worker     {
415*495ae853SAndroid Build Coastguard Worker         int i;
416*495ae853SAndroid Build Coastguard Worker         bool au4_sub_layer_num_units_in_shutter_interval_flag = 0;
417*495ae853SAndroid Build Coastguard Worker 
418*495ae853SAndroid Build Coastguard Worker         sei_mdcv_params_t *ps_sei_mdcv_params = &ps_codec->s_sei.s_sei_mdcv_params;
419*495ae853SAndroid Build Coastguard Worker         sei_mdcv_params_t *ps_cfg_sei_mdcv_params =
420*495ae853SAndroid Build Coastguard Worker                                 &ps_codec->s_cfg.s_sei.s_sei_mdcv_params;
421*495ae853SAndroid Build Coastguard Worker         sei_cll_params_t *ps_sei_cll_params = &ps_codec->s_sei.s_sei_cll_params;
422*495ae853SAndroid Build Coastguard Worker         sei_cll_params_t *ps_cfg_sei_cll_params =
423*495ae853SAndroid Build Coastguard Worker                                 &ps_codec->s_cfg.s_sei.s_sei_cll_params;
424*495ae853SAndroid Build Coastguard Worker         sei_ave_params_t *ps_sei_ave_params = &ps_codec->s_sei.s_sei_ave_params;
425*495ae853SAndroid Build Coastguard Worker         sei_ave_params_t *ps_cfg_sei_ave_params =
426*495ae853SAndroid Build Coastguard Worker                                 &ps_codec->s_cfg.s_sei.s_sei_ave_params;
427*495ae853SAndroid Build Coastguard Worker         sei_sii_params_t *ps_sei_sii_params = &ps_codec->s_sei.s_sei_sii_params;
428*495ae853SAndroid Build Coastguard Worker         sei_sii_params_t *ps_cfg_sei_sii_params = &ps_codec->s_cfg.s_sei.s_sei_sii_params;
429*495ae853SAndroid Build Coastguard Worker 
430*495ae853SAndroid Build Coastguard Worker         if((ps_sei_mdcv_params->au2_display_primaries_x[0]!=
431*495ae853SAndroid Build Coastguard Worker                                 ps_cfg_sei_mdcv_params->au2_display_primaries_x[0]) ||
432*495ae853SAndroid Build Coastguard Worker             (ps_sei_mdcv_params->au2_display_primaries_x[1] !=
433*495ae853SAndroid Build Coastguard Worker                                 ps_cfg_sei_mdcv_params->au2_display_primaries_x[1]) ||
434*495ae853SAndroid Build Coastguard Worker             (ps_sei_mdcv_params->au2_display_primaries_x[2] !=
435*495ae853SAndroid Build Coastguard Worker                                 ps_cfg_sei_mdcv_params->au2_display_primaries_x[2]) ||
436*495ae853SAndroid Build Coastguard Worker             (ps_sei_mdcv_params->au2_display_primaries_y[0] !=
437*495ae853SAndroid Build Coastguard Worker                                 ps_cfg_sei_mdcv_params->au2_display_primaries_y[0]) ||
438*495ae853SAndroid Build Coastguard Worker             (ps_sei_mdcv_params->au2_display_primaries_y[1] !=
439*495ae853SAndroid Build Coastguard Worker                                 ps_cfg_sei_mdcv_params->au2_display_primaries_y[1]) ||
440*495ae853SAndroid Build Coastguard Worker             (ps_sei_mdcv_params->au2_display_primaries_y[2] !=
441*495ae853SAndroid Build Coastguard Worker                                 ps_cfg_sei_mdcv_params->au2_display_primaries_y[2]) ||
442*495ae853SAndroid Build Coastguard Worker             (ps_sei_mdcv_params->u2_white_point_x !=
443*495ae853SAndroid Build Coastguard Worker                                 ps_cfg_sei_mdcv_params->u2_white_point_x) ||
444*495ae853SAndroid Build Coastguard Worker             (ps_sei_mdcv_params->u2_white_point_y !=
445*495ae853SAndroid Build Coastguard Worker                                 ps_cfg_sei_mdcv_params->u2_white_point_y) ||
446*495ae853SAndroid Build Coastguard Worker             (ps_sei_mdcv_params->u4_max_display_mastering_luminance !=
447*495ae853SAndroid Build Coastguard Worker                                 ps_cfg_sei_mdcv_params->u4_max_display_mastering_luminance) ||
448*495ae853SAndroid Build Coastguard Worker             (ps_sei_mdcv_params->u4_min_display_mastering_luminance !=
449*495ae853SAndroid Build Coastguard Worker                                 ps_cfg_sei_mdcv_params->u4_min_display_mastering_luminance))
450*495ae853SAndroid Build Coastguard Worker         {
451*495ae853SAndroid Build Coastguard Worker             ps_codec->s_sei.s_sei_mdcv_params = ps_codec->s_cfg.s_sei.s_sei_mdcv_params;
452*495ae853SAndroid Build Coastguard Worker             ps_codec->s_sei.u1_sei_mdcv_params_present_flag = 1;
453*495ae853SAndroid Build Coastguard Worker         }
454*495ae853SAndroid Build Coastguard Worker         else
455*495ae853SAndroid Build Coastguard Worker         {
456*495ae853SAndroid Build Coastguard Worker             ps_codec->s_sei.u1_sei_mdcv_params_present_flag = 0;
457*495ae853SAndroid Build Coastguard Worker         }
458*495ae853SAndroid Build Coastguard Worker 
459*495ae853SAndroid Build Coastguard Worker         if((ps_sei_cll_params->u2_max_content_light_level !=
460*495ae853SAndroid Build Coastguard Worker                                 ps_cfg_sei_cll_params->u2_max_content_light_level) ||
461*495ae853SAndroid Build Coastguard Worker                 (ps_sei_cll_params->u2_max_pic_average_light_level !=
462*495ae853SAndroid Build Coastguard Worker                                 ps_cfg_sei_cll_params->u2_max_pic_average_light_level))
463*495ae853SAndroid Build Coastguard Worker         {
464*495ae853SAndroid Build Coastguard Worker             ps_codec->s_sei.s_sei_cll_params = ps_codec->s_cfg.s_sei.s_sei_cll_params;
465*495ae853SAndroid Build Coastguard Worker             ps_codec->s_sei.u1_sei_cll_params_present_flag = 1;
466*495ae853SAndroid Build Coastguard Worker         }
467*495ae853SAndroid Build Coastguard Worker         else
468*495ae853SAndroid Build Coastguard Worker         {
469*495ae853SAndroid Build Coastguard Worker             ps_codec->s_sei.u1_sei_cll_params_present_flag = 0;
470*495ae853SAndroid Build Coastguard Worker         }
471*495ae853SAndroid Build Coastguard Worker 
472*495ae853SAndroid Build Coastguard Worker         if((ps_sei_ave_params->u4_ambient_illuminance !=
473*495ae853SAndroid Build Coastguard Worker                                 ps_cfg_sei_ave_params->u4_ambient_illuminance) ||
474*495ae853SAndroid Build Coastguard Worker                 (ps_sei_ave_params->u2_ambient_light_x !=
475*495ae853SAndroid Build Coastguard Worker                                 ps_cfg_sei_ave_params->u2_ambient_light_x) ||
476*495ae853SAndroid Build Coastguard Worker                 (ps_sei_ave_params->u2_ambient_light_y !=
477*495ae853SAndroid Build Coastguard Worker                                 ps_cfg_sei_ave_params->u2_ambient_light_y))
478*495ae853SAndroid Build Coastguard Worker         {
479*495ae853SAndroid Build Coastguard Worker             ps_codec->s_sei.s_sei_ave_params = ps_codec->s_cfg.s_sei.s_sei_ave_params;
480*495ae853SAndroid Build Coastguard Worker             ps_codec->s_sei.u1_sei_ave_params_present_flag = 1;
481*495ae853SAndroid Build Coastguard Worker         }
482*495ae853SAndroid Build Coastguard Worker         else
483*495ae853SAndroid Build Coastguard Worker         {
484*495ae853SAndroid Build Coastguard Worker             ps_codec->s_sei.u1_sei_ave_params_present_flag = 0;
485*495ae853SAndroid Build Coastguard Worker         }
486*495ae853SAndroid Build Coastguard Worker 
487*495ae853SAndroid Build Coastguard Worker         for(i = 0; i <= ps_cfg_sei_sii_params->u1_sii_max_sub_layers_minus1; i++)
488*495ae853SAndroid Build Coastguard Worker         {
489*495ae853SAndroid Build Coastguard Worker             au4_sub_layer_num_units_in_shutter_interval_flag =
490*495ae853SAndroid Build Coastguard Worker                 (au4_sub_layer_num_units_in_shutter_interval_flag ||
491*495ae853SAndroid Build Coastguard Worker                  (ps_sei_sii_params->au4_sub_layer_num_units_in_shutter_interval[i] !=
492*495ae853SAndroid Build Coastguard Worker                   ps_cfg_sei_sii_params->au4_sub_layer_num_units_in_shutter_interval[i]));
493*495ae853SAndroid Build Coastguard Worker         }
494*495ae853SAndroid Build Coastguard Worker 
495*495ae853SAndroid Build Coastguard Worker         if((ps_sei_sii_params->u4_sii_sub_layer_idx !=
496*495ae853SAndroid Build Coastguard Worker             ps_cfg_sei_sii_params->u4_sii_sub_layer_idx) ||
497*495ae853SAndroid Build Coastguard Worker            (ps_sei_sii_params->u1_shutter_interval_info_present_flag !=
498*495ae853SAndroid Build Coastguard Worker             ps_cfg_sei_sii_params->u1_shutter_interval_info_present_flag) ||
499*495ae853SAndroid Build Coastguard Worker            (ps_sei_sii_params->u4_sii_time_scale != ps_cfg_sei_sii_params->u4_sii_time_scale) ||
500*495ae853SAndroid Build Coastguard Worker            (ps_sei_sii_params->u1_fixed_shutter_interval_within_cvs_flag !=
501*495ae853SAndroid Build Coastguard Worker             ps_cfg_sei_sii_params->u1_fixed_shutter_interval_within_cvs_flag) ||
502*495ae853SAndroid Build Coastguard Worker            (ps_sei_sii_params->u4_sii_num_units_in_shutter_interval !=
503*495ae853SAndroid Build Coastguard Worker             ps_cfg_sei_sii_params->u4_sii_num_units_in_shutter_interval) ||
504*495ae853SAndroid Build Coastguard Worker            (ps_sei_sii_params->u1_sii_max_sub_layers_minus1 !=
505*495ae853SAndroid Build Coastguard Worker             ps_cfg_sei_sii_params->u1_sii_max_sub_layers_minus1) ||
506*495ae853SAndroid Build Coastguard Worker            au4_sub_layer_num_units_in_shutter_interval_flag)
507*495ae853SAndroid Build Coastguard Worker         {
508*495ae853SAndroid Build Coastguard Worker             ps_codec->s_sei.s_sei_sii_params = ps_codec->s_cfg.s_sei.s_sei_sii_params;
509*495ae853SAndroid Build Coastguard Worker             ps_codec->s_sei.u1_sei_sii_params_present_flag = 1;
510*495ae853SAndroid Build Coastguard Worker         }
511*495ae853SAndroid Build Coastguard Worker         else
512*495ae853SAndroid Build Coastguard Worker         {
513*495ae853SAndroid Build Coastguard Worker             ps_codec->s_sei.u1_sei_sii_params_present_flag = 0;
514*495ae853SAndroid Build Coastguard Worker         }
515*495ae853SAndroid Build Coastguard Worker 
516*495ae853SAndroid Build Coastguard Worker         if((1 == ps_codec->s_sei.u1_sei_mdcv_params_present_flag) ||
517*495ae853SAndroid Build Coastguard Worker                 (1 == ps_codec->s_sei.u1_sei_cll_params_present_flag) ||
518*495ae853SAndroid Build Coastguard Worker            (1 == ps_codec->s_sei.u1_sei_ave_params_present_flag) ||
519*495ae853SAndroid Build Coastguard Worker            (1 == ps_codec->s_sei.u1_sei_sii_params_present_flag))
520*495ae853SAndroid Build Coastguard Worker         {
521*495ae853SAndroid Build Coastguard Worker             ps_codec->force_curr_frame_type = IV_IDR_FRAME;
522*495ae853SAndroid Build Coastguard Worker         }
523*495ae853SAndroid Build Coastguard Worker     }
524*495ae853SAndroid Build Coastguard Worker #endif
525*495ae853SAndroid Build Coastguard Worker 
526*495ae853SAndroid Build Coastguard Worker     if (ps_video_encode_ip->s_ive_ip.s_inp_buf.apv_bufs[0] != NULL &&
527*495ae853SAndroid Build Coastguard Worker                     ps_codec->i4_header_mode != 1)
528*495ae853SAndroid Build Coastguard Worker     {
529*495ae853SAndroid Build Coastguard Worker         if (IV_SUCCESS != api_check_input_dimensions(ps_codec, pv_api_ip, pv_api_op))
530*495ae853SAndroid Build Coastguard Worker         {
531*495ae853SAndroid Build Coastguard Worker             error_status = IH264E_FAIL;
532*495ae853SAndroid Build Coastguard Worker             SET_ERROR_ON_RETURN(error_status,
533*495ae853SAndroid Build Coastguard Worker                                 IVE_FATALERROR,
534*495ae853SAndroid Build Coastguard Worker                                 ps_video_encode_op->s_ive_op.u4_error_code,
535*495ae853SAndroid Build Coastguard Worker                                 IV_FAIL);
536*495ae853SAndroid Build Coastguard Worker         }
537*495ae853SAndroid Build Coastguard Worker         /******************************************************************
538*495ae853SAndroid Build Coastguard Worker          * INSERT LOGO
539*495ae853SAndroid Build Coastguard Worker          *****************************************************************/
540*495ae853SAndroid Build Coastguard Worker #ifdef LOGO_EN
541*495ae853SAndroid Build Coastguard Worker         ih264e_insert_logo(ps_video_encode_ip->s_ive_ip.s_inp_buf.apv_bufs[0],
542*495ae853SAndroid Build Coastguard Worker                            ps_video_encode_ip->s_ive_ip.s_inp_buf.apv_bufs[1],
543*495ae853SAndroid Build Coastguard Worker                            ps_video_encode_ip->s_ive_ip.s_inp_buf.apv_bufs[2],
544*495ae853SAndroid Build Coastguard Worker                            ps_video_encode_ip->s_ive_ip.s_inp_buf.au4_strd[0],
545*495ae853SAndroid Build Coastguard Worker                            0,
546*495ae853SAndroid Build Coastguard Worker                            0,
547*495ae853SAndroid Build Coastguard Worker                            ps_codec->s_cfg.e_inp_color_fmt,
548*495ae853SAndroid Build Coastguard Worker                            ps_codec->s_cfg.u4_disp_wd,
549*495ae853SAndroid Build Coastguard Worker                            ps_codec->s_cfg.u4_disp_ht);
550*495ae853SAndroid Build Coastguard Worker #endif /*LOGO_EN*/
551*495ae853SAndroid Build Coastguard Worker     }
552*495ae853SAndroid Build Coastguard Worker 
553*495ae853SAndroid Build Coastguard Worker     /* In case of alt ref and B pics we will have non reference frame in stream */
554*495ae853SAndroid Build Coastguard Worker     if (ps_codec->s_cfg.u4_enable_alt_ref || ps_codec->s_cfg.u4_num_bframes)
555*495ae853SAndroid Build Coastguard Worker     {
556*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_non_ref_frames_in_stream = 1;
557*495ae853SAndroid Build Coastguard Worker     }
558*495ae853SAndroid Build Coastguard Worker 
559*495ae853SAndroid Build Coastguard Worker     if (ps_codec->i4_encode_api_call_cnt == 0)
560*495ae853SAndroid Build Coastguard Worker     {
561*495ae853SAndroid Build Coastguard Worker         /********************************************************************/
562*495ae853SAndroid Build Coastguard Worker         /*   number of mv/ref bank buffers used by the codec,               */
563*495ae853SAndroid Build Coastguard Worker         /*      1 to handle curr frame                                      */
564*495ae853SAndroid Build Coastguard Worker         /*      1 to store information of ref frame                         */
565*495ae853SAndroid Build Coastguard Worker         /*      1 more additional because of the codec employs 2 ctxt sets  */
566*495ae853SAndroid Build Coastguard Worker         /*        to assist asynchronous API                                */
567*495ae853SAndroid Build Coastguard Worker         /********************************************************************/
568*495ae853SAndroid Build Coastguard Worker 
569*495ae853SAndroid Build Coastguard Worker         /* initialize mv bank buffer manager */
570*495ae853SAndroid Build Coastguard Worker         error_status = ih264e_mv_buf_mgr_add_bufs(ps_codec);
571*495ae853SAndroid Build Coastguard Worker         SET_ERROR_ON_RETURN(error_status,
572*495ae853SAndroid Build Coastguard Worker                             IVE_FATALERROR,
573*495ae853SAndroid Build Coastguard Worker                             ps_video_encode_op->s_ive_op.u4_error_code,
574*495ae853SAndroid Build Coastguard Worker                             IV_FAIL);
575*495ae853SAndroid Build Coastguard Worker 
576*495ae853SAndroid Build Coastguard Worker         /* initialize ref bank buffer manager */
577*495ae853SAndroid Build Coastguard Worker         error_status = ih264e_pic_buf_mgr_add_bufs(ps_codec);
578*495ae853SAndroid Build Coastguard Worker         SET_ERROR_ON_RETURN(error_status,
579*495ae853SAndroid Build Coastguard Worker                             IVE_FATALERROR,
580*495ae853SAndroid Build Coastguard Worker                             ps_video_encode_op->s_ive_op.u4_error_code,
581*495ae853SAndroid Build Coastguard Worker                             IV_FAIL);
582*495ae853SAndroid Build Coastguard Worker 
583*495ae853SAndroid Build Coastguard Worker         /* for the first frame, generate header when not requested explicitly */
584*495ae853SAndroid Build Coastguard Worker         if (ps_codec->i4_header_mode == 0 &&
585*495ae853SAndroid Build Coastguard Worker                         ps_codec->u4_header_generated == 0)
586*495ae853SAndroid Build Coastguard Worker         {
587*495ae853SAndroid Build Coastguard Worker             ps_codec->i4_gen_header = 1;
588*495ae853SAndroid Build Coastguard Worker         }
589*495ae853SAndroid Build Coastguard Worker     }
590*495ae853SAndroid Build Coastguard Worker 
591*495ae853SAndroid Build Coastguard Worker     /* generate header and return when encoder is operated in header mode */
592*495ae853SAndroid Build Coastguard Worker     if (ps_codec->i4_header_mode == 1)
593*495ae853SAndroid Build Coastguard Worker     {
594*495ae853SAndroid Build Coastguard Worker         /* whenever the header is generated, this implies a start of sequence
595*495ae853SAndroid Build Coastguard Worker          * and a sequence needs to be started with IDR
596*495ae853SAndroid Build Coastguard Worker          */
597*495ae853SAndroid Build Coastguard Worker         ps_codec->force_curr_frame_type = IV_IDR_FRAME;
598*495ae853SAndroid Build Coastguard Worker 
599*495ae853SAndroid Build Coastguard Worker         /* generate header */
600*495ae853SAndroid Build Coastguard Worker         error_status = ih264e_generate_sps_pps(ps_codec);
601*495ae853SAndroid Build Coastguard Worker 
602*495ae853SAndroid Build Coastguard Worker         /* send the input to app */
603*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.s_inp_buf = ps_video_encode_ip->s_ive_ip.s_inp_buf;
604*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.u4_timestamp_low = ps_video_encode_ip->s_ive_ip.u4_timestamp_low;
605*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.u4_timestamp_high = ps_video_encode_ip->s_ive_ip.u4_timestamp_high;
606*495ae853SAndroid Build Coastguard Worker 
607*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.u4_is_last = ps_video_encode_ip->s_ive_ip.u4_is_last;
608*495ae853SAndroid Build Coastguard Worker 
609*495ae853SAndroid Build Coastguard Worker         /* send the output to app */
610*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.output_present  = 1;
611*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.dump_recon = 0;
612*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.s_out_buf = ps_codec->as_out_buf[ctxt_sel].s_bits_buf;
613*495ae853SAndroid Build Coastguard Worker 
614*495ae853SAndroid Build Coastguard Worker         /* error status */
615*495ae853SAndroid Build Coastguard Worker         SET_ERROR_ON_RETURN(error_status,
616*495ae853SAndroid Build Coastguard Worker                             IVE_UNSUPPORTEDPARAM,
617*495ae853SAndroid Build Coastguard Worker                             ps_video_encode_op->s_ive_op.u4_error_code,
618*495ae853SAndroid Build Coastguard Worker                             IV_FAIL);
619*495ae853SAndroid Build Coastguard Worker 
620*495ae853SAndroid Build Coastguard Worker         /* indicates that header has been generated previously */
621*495ae853SAndroid Build Coastguard Worker         ps_codec->u4_header_generated = 1;
622*495ae853SAndroid Build Coastguard Worker 
623*495ae853SAndroid Build Coastguard Worker         /* api call cnt */
624*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_encode_api_call_cnt --;
625*495ae853SAndroid Build Coastguard Worker 
626*495ae853SAndroid Build Coastguard Worker         /* header mode tag is not sticky */
627*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_header_mode = 0;
628*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_gen_header = 0;
629*495ae853SAndroid Build Coastguard Worker 
630*495ae853SAndroid Build Coastguard Worker         return IV_SUCCESS;
631*495ae853SAndroid Build Coastguard Worker     }
632*495ae853SAndroid Build Coastguard Worker 
633*495ae853SAndroid Build Coastguard Worker     /* curr pic cnt */
634*495ae853SAndroid Build Coastguard Worker     ps_codec->i4_pic_cnt += 1;
635*495ae853SAndroid Build Coastguard Worker 
636*495ae853SAndroid Build Coastguard Worker     i4_rc_pre_enc_skip = 0;
637*495ae853SAndroid Build Coastguard Worker     i4_rc_pre_enc_skip = ih264e_input_queue_update(
638*495ae853SAndroid Build Coastguard Worker                     ps_codec, &ps_video_encode_ip->s_ive_ip, &s_inp_buf);
639*495ae853SAndroid Build Coastguard Worker 
640*495ae853SAndroid Build Coastguard Worker     s_out_buf.u4_is_last = s_inp_buf.u4_is_last;
641*495ae853SAndroid Build Coastguard Worker     ps_video_encode_op->s_ive_op.u4_is_last = s_inp_buf.u4_is_last;
642*495ae853SAndroid Build Coastguard Worker 
643*495ae853SAndroid Build Coastguard Worker     /* Send the input to application so that it can free it */
644*495ae853SAndroid Build Coastguard Worker     ps_video_encode_op->s_ive_op.s_inp_buf = s_inp_buf.s_raw_buf;
645*495ae853SAndroid Build Coastguard Worker 
646*495ae853SAndroid Build Coastguard Worker     /* Only encode if the current frame is not pre-encode skip */
647*495ae853SAndroid Build Coastguard Worker     if (!i4_rc_pre_enc_skip && s_inp_buf.s_raw_buf.apv_bufs[0])
648*495ae853SAndroid Build Coastguard Worker     {
649*495ae853SAndroid Build Coastguard Worker         /* proc ctxt base idx */
650*495ae853SAndroid Build Coastguard Worker         WORD32 proc_ctxt_select = ctxt_sel * MAX_PROCESS_THREADS;
651*495ae853SAndroid Build Coastguard Worker 
652*495ae853SAndroid Build Coastguard Worker         /* proc ctxt */
653*495ae853SAndroid Build Coastguard Worker         process_ctxt_t *ps_proc = &ps_codec->as_process[proc_ctxt_select];
654*495ae853SAndroid Build Coastguard Worker 
655*495ae853SAndroid Build Coastguard Worker         WORD32 ret = 0;
656*495ae853SAndroid Build Coastguard Worker 
657*495ae853SAndroid Build Coastguard Worker         /* number of addl. threads to be created */
658*495ae853SAndroid Build Coastguard Worker         WORD32 num_thread_cnt = ps_codec->s_cfg.u4_num_cores - 1;
659*495ae853SAndroid Build Coastguard Worker 
660*495ae853SAndroid Build Coastguard Worker         /* array giving pic cnt that is being processed in curr context set */
661*495ae853SAndroid Build Coastguard Worker         ps_codec->ai4_pic_cnt[ctxt_sel] = ps_codec->i4_pic_cnt;
662*495ae853SAndroid Build Coastguard Worker 
663*495ae853SAndroid Build Coastguard Worker         /* initialize all relevant process ctxts */
664*495ae853SAndroid Build Coastguard Worker         error_status = ih264e_pic_init(ps_codec, &s_inp_buf);
665*495ae853SAndroid Build Coastguard Worker         SET_ERROR_ON_RETURN(error_status,
666*495ae853SAndroid Build Coastguard Worker                             IVE_FATALERROR,
667*495ae853SAndroid Build Coastguard Worker                             ps_video_encode_op->s_ive_op.u4_error_code,
668*495ae853SAndroid Build Coastguard Worker                             IV_FAIL);
669*495ae853SAndroid Build Coastguard Worker 
670*495ae853SAndroid Build Coastguard Worker         for (i = 0; i < num_thread_cnt; i++)
671*495ae853SAndroid Build Coastguard Worker         {
672*495ae853SAndroid Build Coastguard Worker             ret = ithread_create(ps_codec->apv_proc_thread_handle[i],
673*495ae853SAndroid Build Coastguard Worker                                  NULL,
674*495ae853SAndroid Build Coastguard Worker                                  (void *)ih264e_process_thread,
675*495ae853SAndroid Build Coastguard Worker                                  &ps_codec->as_process[i + 1]);
676*495ae853SAndroid Build Coastguard Worker             if (ret != 0)
677*495ae853SAndroid Build Coastguard Worker             {
678*495ae853SAndroid Build Coastguard Worker                 printf("pthread Create Failed");
679*495ae853SAndroid Build Coastguard Worker                 assert(0);
680*495ae853SAndroid Build Coastguard Worker             }
681*495ae853SAndroid Build Coastguard Worker 
682*495ae853SAndroid Build Coastguard Worker             ps_codec->ai4_process_thread_created[i] = 1;
683*495ae853SAndroid Build Coastguard Worker 
684*495ae853SAndroid Build Coastguard Worker             ps_codec->i4_proc_thread_cnt++;
685*495ae853SAndroid Build Coastguard Worker         }
686*495ae853SAndroid Build Coastguard Worker 
687*495ae853SAndroid Build Coastguard Worker 
688*495ae853SAndroid Build Coastguard Worker         /* launch job */
689*495ae853SAndroid Build Coastguard Worker         ih264e_process_thread(ps_proc);
690*495ae853SAndroid Build Coastguard Worker 
691*495ae853SAndroid Build Coastguard Worker         /* Join threads at the end of encoding a frame */
692*495ae853SAndroid Build Coastguard Worker         ih264e_join_threads(ps_codec);
693*495ae853SAndroid Build Coastguard Worker 
694*495ae853SAndroid Build Coastguard Worker         ih264_list_reset(ps_codec->pv_proc_jobq);
695*495ae853SAndroid Build Coastguard Worker 
696*495ae853SAndroid Build Coastguard Worker         ih264_list_reset(ps_codec->pv_entropy_jobq);
697*495ae853SAndroid Build Coastguard Worker 
698*495ae853SAndroid Build Coastguard Worker         error_status = ih264e_update_rc_post_enc(ps_codec, ctxt_sel, (ps_codec->i4_poc == 0));
699*495ae853SAndroid Build Coastguard Worker         SET_ERROR_ON_RETURN(error_status,
700*495ae853SAndroid Build Coastguard Worker                             ((error_status == IH264E_BITSTREAM_BUFFER_OVERFLOW) ?
701*495ae853SAndroid Build Coastguard Worker                                             IVE_UNSUPPORTEDPARAM : IVE_FATALERROR),
702*495ae853SAndroid Build Coastguard Worker                             ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL);
703*495ae853SAndroid Build Coastguard Worker 
704*495ae853SAndroid Build Coastguard Worker         if (ps_codec->s_cfg.u4_enable_quality_metrics & QUALITY_MASK_PSNR)
705*495ae853SAndroid Build Coastguard Worker         {
706*495ae853SAndroid Build Coastguard Worker             ih264e_compute_quality_stats(ps_proc);
707*495ae853SAndroid Build Coastguard Worker         }
708*495ae853SAndroid Build Coastguard Worker 
709*495ae853SAndroid Build Coastguard Worker     }
710*495ae853SAndroid Build Coastguard Worker 
711*495ae853SAndroid Build Coastguard Worker    /****************************************************************************
712*495ae853SAndroid Build Coastguard Worker    * RECON
713*495ae853SAndroid Build Coastguard Worker    *    Since we have forward dependent frames, we cannot return recon in encoding
714*495ae853SAndroid Build Coastguard Worker    *    order. It must be in poc order, or input pic order. To achieve this we
715*495ae853SAndroid Build Coastguard Worker    *    introduce a delay of 1 to the recon wrt encode. Now since we have that
716*495ae853SAndroid Build Coastguard Worker    *    delay, at any point minimum of pic_cnt in our ref buffer will be the
717*495ae853SAndroid Build Coastguard Worker    *    correct frame. For ex let our GOP be IBBP [1 2 3 4] . The encode order
718*495ae853SAndroid Build Coastguard Worker    *    will be [1 4 2 3] .Now since we have a delay of 1, when we are done with
719*495ae853SAndroid Build Coastguard Worker    *    encoding 4, the min in the list will be 1. After encoding 2, it will be
720*495ae853SAndroid Build Coastguard Worker    *    2, 3 after 3 and 4 after 4. Hence we can return in sequence. Note
721*495ae853SAndroid Build Coastguard Worker    *    that the 1 delay is critical. Hence if we have post enc skip, we must
722*495ae853SAndroid Build Coastguard Worker    *    skip here too. Note that since post enc skip already frees the recon
723*495ae853SAndroid Build Coastguard Worker    *    buffer we need not do any thing here
724*495ae853SAndroid Build Coastguard Worker    *
725*495ae853SAndroid Build Coastguard Worker    *    We need to return a recon when ever we consume an input buffer. This
726*495ae853SAndroid Build Coastguard Worker    *    comsumption include a pre or post enc skip. Thus dump recon is set for
727*495ae853SAndroid Build Coastguard Worker    *    all cases except when
728*495ae853SAndroid Build Coastguard Worker    *    1) We are waiting -> ps_codec->i4_pic_cnt > ps_codec->s_cfg.u4_num_bframe
729*495ae853SAndroid Build Coastguard Worker    *        An exception need to be made for the case when we have the last buffer
730*495ae853SAndroid Build Coastguard Worker    *        since we need to flush out the on remainig recon.
731*495ae853SAndroid Build Coastguard Worker    ****************************************************************************/
732*495ae853SAndroid Build Coastguard Worker 
733*495ae853SAndroid Build Coastguard Worker     ps_video_encode_op->s_ive_op.dump_recon = 0;
734*495ae853SAndroid Build Coastguard Worker 
735*495ae853SAndroid Build Coastguard Worker     if (ps_codec->s_cfg.u4_enable_recon
736*495ae853SAndroid Build Coastguard Worker                     && (ps_codec->i4_pic_cnt > (WORD32)ps_codec->s_cfg.u4_num_bframes ||
737*495ae853SAndroid Build Coastguard Worker                         s_inp_buf.u4_is_last))
738*495ae853SAndroid Build Coastguard Worker     {
739*495ae853SAndroid Build Coastguard Worker         /* error status */
740*495ae853SAndroid Build Coastguard Worker         IH264_ERROR_T ret = IH264_SUCCESS;
741*495ae853SAndroid Build Coastguard Worker         pic_buf_t *ps_pic_buf = NULL;
742*495ae853SAndroid Build Coastguard Worker         WORD32 i4_buf_status, i4_curr_poc = 32768;
743*495ae853SAndroid Build Coastguard Worker         WORD8 buf_idx = -1;
744*495ae853SAndroid Build Coastguard Worker 
745*495ae853SAndroid Build Coastguard Worker         /* In case of skips we return recon, but indicate that buffer is zero size */
746*495ae853SAndroid Build Coastguard Worker         if (ps_codec->s_rate_control.post_encode_skip[ctxt_sel]
747*495ae853SAndroid Build Coastguard Worker                         || i4_rc_pre_enc_skip)
748*495ae853SAndroid Build Coastguard Worker         {
749*495ae853SAndroid Build Coastguard Worker 
750*495ae853SAndroid Build Coastguard Worker             ps_video_encode_op->s_ive_op.dump_recon = 1;
751*495ae853SAndroid Build Coastguard Worker             ps_video_encode_op->s_ive_op.s_recon_buf.au4_wd[0] = 0;
752*495ae853SAndroid Build Coastguard Worker             ps_video_encode_op->s_ive_op.s_recon_buf.au4_wd[1] = 0;
753*495ae853SAndroid Build Coastguard Worker 
754*495ae853SAndroid Build Coastguard Worker         }
755*495ae853SAndroid Build Coastguard Worker         else
756*495ae853SAndroid Build Coastguard Worker         {
757*495ae853SAndroid Build Coastguard Worker             for (i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
758*495ae853SAndroid Build Coastguard Worker             {
759*495ae853SAndroid Build Coastguard Worker                 if (ps_codec->as_ref_set[i].i4_pic_cnt == -1)
760*495ae853SAndroid Build Coastguard Worker                     continue;
761*495ae853SAndroid Build Coastguard Worker 
762*495ae853SAndroid Build Coastguard Worker                 i4_buf_status = ih264_buf_mgr_get_status(
763*495ae853SAndroid Build Coastguard Worker                                 ps_codec->pv_ref_buf_mgr,
764*495ae853SAndroid Build Coastguard Worker                                 ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
765*495ae853SAndroid Build Coastguard Worker 
766*495ae853SAndroid Build Coastguard Worker                 if ((i4_buf_status & BUF_MGR_IO)
767*495ae853SAndroid Build Coastguard Worker                                 && (ps_codec->as_ref_set[i].i4_poc < i4_curr_poc))
768*495ae853SAndroid Build Coastguard Worker                 {
769*495ae853SAndroid Build Coastguard Worker                     ps_pic_buf = ps_codec->as_ref_set[i].ps_pic_buf;
770*495ae853SAndroid Build Coastguard Worker                     i4_curr_poc = ps_codec->as_ref_set[i].i4_poc;
771*495ae853SAndroid Build Coastguard Worker                     buf_idx = i;
772*495ae853SAndroid Build Coastguard Worker                 }
773*495ae853SAndroid Build Coastguard Worker             }
774*495ae853SAndroid Build Coastguard Worker             if ((ps_codec->s_cfg.u4_enable_quality_metrics & QUALITY_MASK_PSNR)
775*495ae853SAndroid Build Coastguard Worker                                 && buf_idx >= 0)
776*495ae853SAndroid Build Coastguard Worker             {
777*495ae853SAndroid Build Coastguard Worker                 UWORD8 comp;
778*495ae853SAndroid Build Coastguard Worker                 for(comp = 0; comp < 3; comp++)
779*495ae853SAndroid Build Coastguard Worker                 {
780*495ae853SAndroid Build Coastguard Worker                     DEBUG("PSNR[%d]: %f\n", comp,
781*495ae853SAndroid Build Coastguard Worker                         ps_codec->as_ref_set[buf_idx].s_pic_quality_stats.total_psnr[comp]);
782*495ae853SAndroid Build Coastguard Worker                 }
783*495ae853SAndroid Build Coastguard Worker             }
784*495ae853SAndroid Build Coastguard Worker 
785*495ae853SAndroid Build Coastguard Worker             ps_video_encode_op->s_ive_op.s_recon_buf =
786*495ae853SAndroid Build Coastguard Worker                             ps_video_encode_ip->s_ive_ip.s_recon_buf;
787*495ae853SAndroid Build Coastguard Worker 
788*495ae853SAndroid Build Coastguard Worker             /*
789*495ae853SAndroid Build Coastguard Worker              * If we get a valid buffer. output and free recon.
790*495ae853SAndroid Build Coastguard Worker              *
791*495ae853SAndroid Build Coastguard Worker              * we may get an invalid buffer if num_b_frames is 0. This is because
792*495ae853SAndroid Build Coastguard Worker              * We assume that there will be a ref frame in ref list after encoding
793*495ae853SAndroid Build Coastguard Worker              * the last frame. With B frames this is correct since its forward ref
794*495ae853SAndroid Build Coastguard Worker              * pic will be in the ref list. But if num_b_frames is 0, we will not
795*495ae853SAndroid Build Coastguard Worker              * have a forward ref pic
796*495ae853SAndroid Build Coastguard Worker              */
797*495ae853SAndroid Build Coastguard Worker 
798*495ae853SAndroid Build Coastguard Worker             if (ps_pic_buf)
799*495ae853SAndroid Build Coastguard Worker             {
800*495ae853SAndroid Build Coastguard Worker                 /* copy/convert the recon buffer and return */
801*495ae853SAndroid Build Coastguard Worker                 ih264e_fmt_conv(ps_codec,
802*495ae853SAndroid Build Coastguard Worker                                 ps_pic_buf,
803*495ae853SAndroid Build Coastguard Worker                                 ps_video_encode_ip->s_ive_ip.s_recon_buf.apv_bufs[0],
804*495ae853SAndroid Build Coastguard Worker                                 ps_video_encode_ip->s_ive_ip.s_recon_buf.apv_bufs[1],
805*495ae853SAndroid Build Coastguard Worker                                 ps_video_encode_ip->s_ive_ip.s_recon_buf.apv_bufs[2],
806*495ae853SAndroid Build Coastguard Worker                                 ps_video_encode_ip->s_ive_ip.s_recon_buf.au4_wd[0],
807*495ae853SAndroid Build Coastguard Worker                                 ps_video_encode_ip->s_ive_ip.s_recon_buf.au4_wd[1],
808*495ae853SAndroid Build Coastguard Worker                                 0, ps_codec->s_cfg.u4_disp_ht);
809*495ae853SAndroid Build Coastguard Worker 
810*495ae853SAndroid Build Coastguard Worker                 ps_video_encode_op->s_ive_op.dump_recon = 1;
811*495ae853SAndroid Build Coastguard Worker 
812*495ae853SAndroid Build Coastguard Worker                 ret = ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr,
813*495ae853SAndroid Build Coastguard Worker                                             ps_pic_buf->i4_buf_id, BUF_MGR_IO);
814*495ae853SAndroid Build Coastguard Worker 
815*495ae853SAndroid Build Coastguard Worker                 if (IH264_SUCCESS != ret)
816*495ae853SAndroid Build Coastguard Worker                 {
817*495ae853SAndroid Build Coastguard Worker                     SET_ERROR_ON_RETURN(
818*495ae853SAndroid Build Coastguard Worker                                     (IH264E_ERROR_T)ret, IVE_FATALERROR,
819*495ae853SAndroid Build Coastguard Worker                                     ps_video_encode_op->s_ive_op.u4_error_code,
820*495ae853SAndroid Build Coastguard Worker                                     IV_FAIL);
821*495ae853SAndroid Build Coastguard Worker                 }
822*495ae853SAndroid Build Coastguard Worker             }
823*495ae853SAndroid Build Coastguard Worker         }
824*495ae853SAndroid Build Coastguard Worker     }
825*495ae853SAndroid Build Coastguard Worker 
826*495ae853SAndroid Build Coastguard Worker     /***************************************************************************
827*495ae853SAndroid Build Coastguard Worker      * Free reference buffers:
828*495ae853SAndroid Build Coastguard Worker      * In case of a post enc skip, we have to ensure that those pics will not
829*495ae853SAndroid Build Coastguard Worker      * be used as reference anymore. In all other cases we will not even mark
830*495ae853SAndroid Build Coastguard Worker      * the ref buffers
831*495ae853SAndroid Build Coastguard Worker      ***************************************************************************/
832*495ae853SAndroid Build Coastguard Worker     if (ps_codec->s_rate_control.post_encode_skip[ctxt_sel])
833*495ae853SAndroid Build Coastguard Worker     {
834*495ae853SAndroid Build Coastguard Worker         /* pic info */
835*495ae853SAndroid Build Coastguard Worker         pic_buf_t *ps_cur_pic;
836*495ae853SAndroid Build Coastguard Worker 
837*495ae853SAndroid Build Coastguard Worker         /* mv info */
838*495ae853SAndroid Build Coastguard Worker         mv_buf_t *ps_cur_mv_buf;
839*495ae853SAndroid Build Coastguard Worker 
840*495ae853SAndroid Build Coastguard Worker         /* error status */
841*495ae853SAndroid Build Coastguard Worker         IH264_ERROR_T ret = IH264_SUCCESS;
842*495ae853SAndroid Build Coastguard Worker 
843*495ae853SAndroid Build Coastguard Worker         /* Decrement coded pic count */
844*495ae853SAndroid Build Coastguard Worker         ps_codec->i4_poc--;
845*495ae853SAndroid Build Coastguard Worker 
846*495ae853SAndroid Build Coastguard Worker         /* loop through to get the min pic cnt among the list of pics stored in ref list */
847*495ae853SAndroid Build Coastguard Worker         /* since the skipped frame may not be on reference list, we may not have an MV bank
848*495ae853SAndroid Build Coastguard Worker          * hence free only if we have allocated */
849*495ae853SAndroid Build Coastguard Worker         for (i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
850*495ae853SAndroid Build Coastguard Worker         {
851*495ae853SAndroid Build Coastguard Worker             if (ps_codec->i4_pic_cnt == ps_codec->as_ref_set[i].i4_pic_cnt)
852*495ae853SAndroid Build Coastguard Worker             {
853*495ae853SAndroid Build Coastguard Worker 
854*495ae853SAndroid Build Coastguard Worker                 ps_cur_pic = ps_codec->as_ref_set[i].ps_pic_buf;
855*495ae853SAndroid Build Coastguard Worker 
856*495ae853SAndroid Build Coastguard Worker                 ps_cur_mv_buf = ps_codec->as_ref_set[i].ps_mv_buf;
857*495ae853SAndroid Build Coastguard Worker 
858*495ae853SAndroid Build Coastguard Worker                 /* release this frame from reference list and recon list */
859*495ae853SAndroid Build Coastguard Worker                 ret = ih264_buf_mgr_release(ps_codec->pv_mv_buf_mgr, ps_cur_mv_buf->i4_buf_id , BUF_MGR_REF);
860*495ae853SAndroid Build Coastguard Worker                 ret |= ih264_buf_mgr_release(ps_codec->pv_mv_buf_mgr, ps_cur_mv_buf->i4_buf_id , BUF_MGR_IO);
861*495ae853SAndroid Build Coastguard Worker                 SET_ERROR_ON_RETURN((IH264E_ERROR_T)ret,
862*495ae853SAndroid Build Coastguard Worker                                     IVE_FATALERROR,
863*495ae853SAndroid Build Coastguard Worker                                     ps_video_encode_op->s_ive_op.u4_error_code,
864*495ae853SAndroid Build Coastguard Worker                                     IV_FAIL);
865*495ae853SAndroid Build Coastguard Worker 
866*495ae853SAndroid Build Coastguard Worker                 ret = ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr, ps_cur_pic->i4_buf_id , BUF_MGR_REF);
867*495ae853SAndroid Build Coastguard Worker                 ret |= ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr, ps_cur_pic->i4_buf_id , BUF_MGR_IO);
868*495ae853SAndroid Build Coastguard Worker                 SET_ERROR_ON_RETURN((IH264E_ERROR_T)ret,
869*495ae853SAndroid Build Coastguard Worker                                     IVE_FATALERROR,
870*495ae853SAndroid Build Coastguard Worker                                     ps_video_encode_op->s_ive_op.u4_error_code,
871*495ae853SAndroid Build Coastguard Worker                                     IV_FAIL);
872*495ae853SAndroid Build Coastguard Worker                 break;
873*495ae853SAndroid Build Coastguard Worker             }
874*495ae853SAndroid Build Coastguard Worker         }
875*495ae853SAndroid Build Coastguard Worker     }
876*495ae853SAndroid Build Coastguard Worker 
877*495ae853SAndroid Build Coastguard Worker     /*
878*495ae853SAndroid Build Coastguard Worker      * Since recon is not in sync with output, ie there can be frame to be
879*495ae853SAndroid Build Coastguard Worker      * given back as recon even after last output. Hence we need to mark that
880*495ae853SAndroid Build Coastguard Worker      * the output is not the last.
881*495ae853SAndroid Build Coastguard Worker      * Hence search through reflist and mark appropriately
882*495ae853SAndroid Build Coastguard Worker      */
883*495ae853SAndroid Build Coastguard Worker     if (ps_codec->s_cfg.u4_enable_recon)
884*495ae853SAndroid Build Coastguard Worker     {
885*495ae853SAndroid Build Coastguard Worker         WORD32 i4_buf_status = 0;
886*495ae853SAndroid Build Coastguard Worker 
887*495ae853SAndroid Build Coastguard Worker         for (i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
888*495ae853SAndroid Build Coastguard Worker         {
889*495ae853SAndroid Build Coastguard Worker             if (ps_codec->as_ref_set[i].i4_pic_cnt == -1)
890*495ae853SAndroid Build Coastguard Worker                 continue;
891*495ae853SAndroid Build Coastguard Worker 
892*495ae853SAndroid Build Coastguard Worker             i4_buf_status |= ih264_buf_mgr_get_status(
893*495ae853SAndroid Build Coastguard Worker                             ps_codec->pv_ref_buf_mgr,
894*495ae853SAndroid Build Coastguard Worker                             ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
895*495ae853SAndroid Build Coastguard Worker         }
896*495ae853SAndroid Build Coastguard Worker 
897*495ae853SAndroid Build Coastguard Worker         if (i4_buf_status & BUF_MGR_IO)
898*495ae853SAndroid Build Coastguard Worker         {
899*495ae853SAndroid Build Coastguard Worker             s_out_buf.u4_is_last = 0;
900*495ae853SAndroid Build Coastguard Worker             ps_video_encode_op->s_ive_op.u4_is_last = 0;
901*495ae853SAndroid Build Coastguard Worker         }
902*495ae853SAndroid Build Coastguard Worker     }
903*495ae853SAndroid Build Coastguard Worker 
904*495ae853SAndroid Build Coastguard Worker     /**************************************************************************
905*495ae853SAndroid Build Coastguard Worker      * Signaling to APP
906*495ae853SAndroid Build Coastguard Worker      *  1) If we valid a valid output mark it so
907*495ae853SAndroid Build Coastguard Worker      *  2) Set the codec output ps_video_encode_op
908*495ae853SAndroid Build Coastguard Worker      *  3) Set the error status
909*495ae853SAndroid Build Coastguard Worker      *  4) Set the return Pic type
910*495ae853SAndroid Build Coastguard Worker      *      Note that we already has marked recon properly
911*495ae853SAndroid Build Coastguard Worker      *  5)Send the consumed input back to app so that it can free it if possible
912*495ae853SAndroid Build Coastguard Worker      *
913*495ae853SAndroid Build Coastguard Worker      *  We will have to return the output and input buffers unconditionally
914*495ae853SAndroid Build Coastguard Worker      *  so that app can release them
915*495ae853SAndroid Build Coastguard Worker      **************************************************************************/
916*495ae853SAndroid Build Coastguard Worker     if (!i4_rc_pre_enc_skip
917*495ae853SAndroid Build Coastguard Worker                     && !ps_codec->s_rate_control.post_encode_skip[ctxt_sel]
918*495ae853SAndroid Build Coastguard Worker                     && s_inp_buf.s_raw_buf.apv_bufs[0])
919*495ae853SAndroid Build Coastguard Worker     {
920*495ae853SAndroid Build Coastguard Worker 
921*495ae853SAndroid Build Coastguard Worker         /* receive output back from codec */
922*495ae853SAndroid Build Coastguard Worker         s_out_buf = ps_codec->as_out_buf[ctxt_sel];
923*495ae853SAndroid Build Coastguard Worker 
924*495ae853SAndroid Build Coastguard Worker         /* send the output to app */
925*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.output_present  = 1;
926*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.u4_error_code = IV_SUCCESS;
927*495ae853SAndroid Build Coastguard Worker 
928*495ae853SAndroid Build Coastguard Worker         /* Set the time stamps of the encodec input */
929*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.u4_timestamp_low = s_inp_buf.u4_timestamp_low;
930*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.u4_timestamp_high = s_inp_buf.u4_timestamp_high;
931*495ae853SAndroid Build Coastguard Worker 
932*495ae853SAndroid Build Coastguard Worker         switch (ps_codec->pic_type)
933*495ae853SAndroid Build Coastguard Worker         {
934*495ae853SAndroid Build Coastguard Worker             case PIC_IDR:
935*495ae853SAndroid Build Coastguard Worker                 ps_video_encode_op->s_ive_op.u4_encoded_frame_type =IV_IDR_FRAME;
936*495ae853SAndroid Build Coastguard Worker                 break;
937*495ae853SAndroid Build Coastguard Worker 
938*495ae853SAndroid Build Coastguard Worker             case PIC_I:
939*495ae853SAndroid Build Coastguard Worker                 ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_I_FRAME;
940*495ae853SAndroid Build Coastguard Worker                 break;
941*495ae853SAndroid Build Coastguard Worker 
942*495ae853SAndroid Build Coastguard Worker             case PIC_P:
943*495ae853SAndroid Build Coastguard Worker                 ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_P_FRAME;
944*495ae853SAndroid Build Coastguard Worker                 break;
945*495ae853SAndroid Build Coastguard Worker 
946*495ae853SAndroid Build Coastguard Worker             case PIC_B:
947*495ae853SAndroid Build Coastguard Worker                 ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_B_FRAME;
948*495ae853SAndroid Build Coastguard Worker                 break;
949*495ae853SAndroid Build Coastguard Worker 
950*495ae853SAndroid Build Coastguard Worker             default:
951*495ae853SAndroid Build Coastguard Worker                 ps_video_encode_op->s_ive_op.u4_encoded_frame_type = IV_NA_FRAME;
952*495ae853SAndroid Build Coastguard Worker                 break;
953*495ae853SAndroid Build Coastguard Worker         }
954*495ae853SAndroid Build Coastguard Worker 
955*495ae853SAndroid Build Coastguard Worker         for (i = 0; i < (WORD32)ps_codec->s_cfg.u4_num_cores; i++)
956*495ae853SAndroid Build Coastguard Worker         {
957*495ae853SAndroid Build Coastguard Worker             error_status |= ps_codec->as_process[ctxt_sel + i].i4_error_code;
958*495ae853SAndroid Build Coastguard Worker         }
959*495ae853SAndroid Build Coastguard Worker         SET_ERROR_ON_RETURN(error_status,
960*495ae853SAndroid Build Coastguard Worker                             ((error_status == IH264E_BITSTREAM_BUFFER_OVERFLOW) ?
961*495ae853SAndroid Build Coastguard Worker                                             IVE_UNSUPPORTEDPARAM : IVE_FATALERROR),
962*495ae853SAndroid Build Coastguard Worker                             ps_video_encode_op->s_ive_op.u4_error_code, IV_FAIL);
963*495ae853SAndroid Build Coastguard Worker     }
964*495ae853SAndroid Build Coastguard Worker     else
965*495ae853SAndroid Build Coastguard Worker     {
966*495ae853SAndroid Build Coastguard Worker         /* receive output back from codec */
967*495ae853SAndroid Build Coastguard Worker         s_out_buf = ps_codec->as_out_buf[ctxt_sel];
968*495ae853SAndroid Build Coastguard Worker 
969*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.output_present = 0;
970*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.u4_error_code = IV_SUCCESS;
971*495ae853SAndroid Build Coastguard Worker 
972*495ae853SAndroid Build Coastguard Worker         /* Set the time stamps of the encodec input */
973*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.u4_timestamp_low = 0;
974*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.u4_timestamp_high = 0;
975*495ae853SAndroid Build Coastguard Worker 
976*495ae853SAndroid Build Coastguard Worker         ps_video_encode_op->s_ive_op.u4_encoded_frame_type =  IV_NA_FRAME;
977*495ae853SAndroid Build Coastguard Worker 
978*495ae853SAndroid Build Coastguard Worker     }
979*495ae853SAndroid Build Coastguard Worker 
980*495ae853SAndroid Build Coastguard Worker     ps_video_encode_op->s_ive_op.s_out_buf = s_out_buf.s_bits_buf;
981*495ae853SAndroid Build Coastguard Worker 
982*495ae853SAndroid Build Coastguard Worker     return IV_SUCCESS;
983*495ae853SAndroid Build Coastguard Worker }
984