Coverage Report

Created: 2024-07-27 06:35

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