Coverage Report

Created: 2025-07-09 06:41

/src/libavc/encoder/svc/isvce_utils.c
Line
Count
Source (jump to first uncovered line)
1
/******************************************************************************
2
 *
3
 * Copyright (C) 2022 The Android Open Source Project
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at:
8
 *
9
 * http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 *****************************************************************************
18
 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19
 */
20
21
/**
22
*******************************************************************************
23
* @file
24
*  ih264e_svc_utils.c
25
*
26
* @brief
27
*  Contains utility functions used for SVC encoding
28
*
29
* @author
30
*  ittiam
31
*
32
* @par List of Functions:
33
*  - ih264e_svc_ref_list_refresh()
34
*  - ih264e_svc_inp_params_validate()
35
*
36
* @remarks
37
*  None
38
*
39
*******************************************************************************
40
*/
41
#include <math.h>
42
#include <limits.h>
43
44
#include "ih264_typedefs.h"
45
46
/* Dependencies of ih264_buf_mgr.h */
47
/* Dependencies of ih264_list.h */
48
#include "ih264_error.h"
49
50
#include "ih264_buf_mgr.h"
51
#include "ih264_list.h"
52
#include "ih264_trans_data.h"
53
#include "ih264_size_defs.h"
54
55
/* Dependencies of ih264_common_tables.h */
56
#include "ih264_defs.h"
57
#include "ih264_structs.h"
58
59
#include "ih264_common_tables.h"
60
61
/* Dependencies of ih264e_bitstream.h */
62
#include "ih264e_error.h"
63
64
/* Dependencies of ih264e_cabac_structs.h */
65
#include "ih264_cabac_tables.h"
66
67
/* Dependencies of ime_structs.h */
68
#include "ime_defs.h"
69
#include "ime_distortion_metrics.h"
70
71
/* Dependencies of ih264e_structs.h */
72
#include "iv2.h"
73
#include "ive2.h"
74
#include "ih264_defs.h"
75
#include "ih264_deblk_edge_filters.h"
76
#include "ih264_inter_pred_filters.h"
77
#include "ih264_structs.h"
78
#include "ih264_trans_quant_itrans_iquant.h"
79
#include "ih264e_bitstream.h"
80
#include "ih264e_cabac_structs.h"
81
#include "ime_statistics.h"
82
#include "ime_structs.h"
83
/* Dependencies of 'irc_picture_type.h' */
84
#include "irc_cntrl_param.h"
85
#include "irc_frame_info_collector.h"
86
#include "irc_mem_req_and_acq.h"
87
/* Dependencies of 'irc_rate_control_api_structs' */
88
#include "irc_picture_type.h"
89
#include "irc_rd_model.h"
90
#include "irc_vbr_storage_vbv.h"
91
#include "irc_est_sad.h"
92
#include "irc_bit_allocation.h"
93
#include "irc_mb_model_based.h"
94
#include "irc_cbr_buffer_control.h"
95
#include "irc_vbr_str_prms.h"
96
#include "irc_common.h"
97
#include "irc_rate_control_api_structs.h"
98
#include "irc_rate_control_api.h"
99
#include "irc_svc_rate_control_api.h"
100
/* Dependencies of 'ih264e_utils.h' */
101
#include "ih264e_defs.h"
102
#include "ih264e_structs.h"
103
/* Dependencies of 'ih264e_utils.h' */
104
#include "irc_mem_req_and_acq.h"
105
#include "ih264e_rc_mem_interface.h"
106
#include "ih264e_time_stamp.h"
107
#include "ih264e_utils.h"
108
#include "ime.h"
109
#include "isvc_macros.h"
110
#include "isvce_cabac.h"
111
#include "isvce_core_coding.h"
112
#include "isvce_defs.h"
113
#include "isvce_error.h"
114
#include "isvce_me.h"
115
#include "isvce_utils.h"
116
#include "isvce_downscaler.h"
117
#include "isvce_encode_header.h"
118
#include "isvce_rate_control.h"
119
#include "isvce_sub_pic_rc.h"
120
121
static const UWORD32 gu4_downscaler_blk_size = 96;
122
123
static FORCEINLINE UWORD32 isvce_get_downscaler_blk_dims(UWORD32 u4_frame_dim, UWORD32 u4_blk_pos,
124
                                                         UWORD32 u4_default_blk_size)
125
2.02M
{
126
2.02M
    return ((u4_frame_dim - u4_blk_pos * u4_default_blk_size) < u4_default_blk_size)
127
2.02M
               ? (u4_frame_dim - u4_blk_pos * u4_default_blk_size)
128
2.02M
               : u4_default_blk_size;
129
2.02M
}
130
131
/**
132
*******************************************************************************
133
*
134
* @brief
135
*  Reference and MV bank Buffer Manager for SVC
136
*
137
* @par Description:
138
*  Here we will
139
*      1) Find the correct ref pics for the current frame
140
*      2) Free the ref pics that are not going to be used anymore
141
*
142
*  1) Finding correct ref pic
143
*      All pics needed for future are arranged in a picture list called
144
*      ps_codec->as_ref_set. Each picture in this will have a pic buffer and
145
*      MV buffer that is marked appropriately as BUF_MGR_REF, BUF_MGR_IO or
146
*      BUF_MGR_CODEC. pic_cnt, poc, and temporal_id will also be present.
147
*      The strategy is to pick the closest references that belongs to the
148
*      same temporal_id or lesser. The closeness is measured via the
149
*      smallest absolute difference between ref and cur pocs.
150
*
151
*      Note that i4_pic_cnt == -1 is used to filter uninitialised ref pics.
152
*      Now since we only have max two ref pics, we will always find max 2
153
*      ref pics.
154
*
155
*  2) Self explanatory
156
*
157
* @param[in] ps_codec
158
*  Pointer to codeec context
159
*
160
* @param[in] pps_ref_pics
161
*  Array of pointers to refPicBufs
162
*
163
* @param[in] pps_mv_bufs
164
*  Array of pointers to refMVBufs
165
*
166
* @param[in] e_pic_type
167
*  Picture type
168
*
169
* @returns Nothing
170
*
171
*******************************************************************************
172
*/
173
static WORD32 isvce_ref_list_refresh(isvce_codec_t *ps_codec, svc_au_buf_t **pps_ref_pics,
174
                                     svc_au_data_t **pps_mv_bufs, WORD32 *pi4_ref_set_id,
175
                                     PIC_TYPE_T e_pic_type)
176
29.5k
{
177
29.5k
    typedef struct
178
29.5k
    {
179
29.5k
        WORD32 i4_buf_id;
180
181
29.5k
        WORD32 i4_abs_poc_diff;
182
183
29.5k
        WORD8 i1_temporal_id;
184
29.5k
    } ref_pic_props_t;
185
186
29.5k
    ref_pic_props_t s_ref_pic_props = {0, 0, -1};
187
188
29.5k
    WORD32 i, buf_status;
189
190
29.5k
    WORD32 i4_cur_pic_poc = ps_codec->i4_poc;
191
29.5k
    WORD32 i4_cur_pic_temporal_id = isvce_svc_temporal_id_compute(
192
29.5k
        ps_codec->i4_poc, ps_codec->s_cfg.s_svc_params.u1_num_temporal_layers, e_pic_type);
193
194
29.5k
    if(e_pic_type == PIC_B)
195
0
    {
196
0
        return IH264E_FAIL;
197
0
    }
198
199
29.5k
    ASSERT(1 == MAX_LAYER_REFERENCE_PICS);
200
201
    /* Pick a ref_pic for the current picture */
202
29.5k
    if(e_pic_type != PIC_IDR)
203
21.0k
    {
204
123k
        for(i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
205
102k
        {
206
102k
            WORD32 i4_abs_poc_diff;
207
102k
            WORD8 i1_temporal_id;
208
209
102k
            if(ps_codec->as_ref_set[i].i4_pic_cnt == -1)
210
53.4k
            {
211
53.4k
                continue;
212
53.4k
            }
213
214
49.1k
            buf_status = ih264_buf_mgr_get_status(ps_codec->pv_ref_buf_mgr,
215
49.1k
                                                  ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
216
217
49.1k
            if(buf_status & BUF_MGR_REF)
218
46.4k
            {
219
46.4k
                i4_abs_poc_diff = ABS(ps_codec->as_ref_set[i].i4_poc - i4_cur_pic_poc);
220
46.4k
                i1_temporal_id = ps_codec->as_ref_set[i].ps_pic_buf->i1_temporal_id;
221
222
46.4k
                if(s_ref_pic_props.i1_temporal_id > -1)
223
20.1k
                {
224
20.1k
                    if((i1_temporal_id <= i4_cur_pic_temporal_id) &&
225
20.1k
                       (s_ref_pic_props.i4_abs_poc_diff > i4_abs_poc_diff))
226
6.15k
                    {
227
6.15k
                        s_ref_pic_props.i4_abs_poc_diff = i4_abs_poc_diff;
228
6.15k
                        s_ref_pic_props.i1_temporal_id = i1_temporal_id;
229
6.15k
                        s_ref_pic_props.i4_buf_id = i;
230
6.15k
                    }
231
20.1k
                }
232
26.2k
                else if(i1_temporal_id <= i4_cur_pic_temporal_id)
233
20.8k
                {
234
20.8k
                    s_ref_pic_props.i4_abs_poc_diff = i4_abs_poc_diff;
235
20.8k
                    s_ref_pic_props.i1_temporal_id = i1_temporal_id;
236
20.8k
                    s_ref_pic_props.i4_buf_id = i;
237
20.8k
                }
238
46.4k
            }
239
49.1k
        }
240
241
21.0k
        if(s_ref_pic_props.i1_temporal_id < 0)
242
173
        {
243
173
            return IH264E_FAIL;
244
173
        }
245
246
20.8k
        pps_ref_pics[0] = pps_ref_pics[1] =
247
20.8k
            ps_codec->as_ref_set[s_ref_pic_props.i4_buf_id].ps_pic_buf;
248
20.8k
        pps_mv_bufs[0] = pps_mv_bufs[1] =
249
20.8k
            ps_codec->as_ref_set[s_ref_pic_props.i4_buf_id].ps_svc_au_data;
250
251
        /* Pick all ref pic_bufs to be freed. */
252
122k
        for(i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
253
101k
        {
254
101k
            if(ps_codec->as_ref_set[i].i4_pic_cnt == -1)
255
53.4k
            {
256
53.4k
                continue;
257
53.4k
            }
258
259
48.4k
            buf_status = ih264_buf_mgr_get_status(ps_codec->pv_ref_buf_mgr,
260
48.4k
                                                  ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
261
262
48.4k
            if((buf_status & (BUF_MGR_REF | BUF_MGR_CODEC | BUF_MGR_IO)) == 0)
263
229
            {
264
229
                ps_codec->as_ref_set[i].i4_pic_cnt = -1;
265
229
                ps_codec->as_ref_set[i].i4_poc = 32768;
266
267
229
                continue;
268
229
            }
269
270
48.1k
            if(buf_status & BUF_MGR_REF)
271
46.4k
            {
272
46.4k
                if((i4_cur_pic_temporal_id <= ps_codec->as_ref_set[i].ps_pic_buf->i1_temporal_id) &&
273
46.4k
                   (pps_ref_pics[0]->i4_frame_num !=
274
32.0k
                    ps_codec->as_ref_set[i].ps_pic_buf->i4_frame_num) &&
275
46.4k
                   (pps_ref_pics[0]->i4_frame_num !=
276
15.7k
                    ps_codec->as_ref_set[i].ps_pic_buf->i4_frame_num))
277
15.7k
                {
278
15.7k
                    ih264_buf_mgr_release(ps_codec->pv_svc_au_data_store_mgr,
279
15.7k
                                          ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id,
280
15.7k
                                          BUF_MGR_REF);
281
282
15.7k
                    ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr,
283
15.7k
                                          ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id,
284
15.7k
                                          BUF_MGR_REF);
285
15.7k
                }
286
46.4k
            }
287
48.1k
        }
288
20.8k
    }
289
8.51k
    else
290
8.51k
    {
291
50.4k
        for(i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
292
41.9k
        {
293
41.9k
            if(ps_codec->as_ref_set[i].i4_pic_cnt == -1)
294
36.2k
            {
295
36.2k
                continue;
296
36.2k
            }
297
298
5.63k
            buf_status = ih264_buf_mgr_get_status(ps_codec->pv_ref_buf_mgr,
299
5.63k
                                                  ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
300
301
5.63k
            if((buf_status & (BUF_MGR_REF | BUF_MGR_CODEC | BUF_MGR_IO)) == 0)
302
277
            {
303
277
                ps_codec->as_ref_set[i].i4_pic_cnt = -1;
304
277
                ps_codec->as_ref_set[i].i4_poc = 32768;
305
306
277
                continue;
307
277
            }
308
309
5.35k
            if(buf_status & BUF_MGR_REF)
310
4.01k
            {
311
4.01k
                ih264_buf_mgr_release(ps_codec->pv_svc_au_data_store_mgr,
312
4.01k
                                      ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id, BUF_MGR_REF);
313
314
4.01k
                ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr,
315
4.01k
                                      ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id, BUF_MGR_REF);
316
4.01k
            }
317
5.35k
        }
318
8.51k
    }
319
320
    /*
321
     * Mark all reference pic with unused buffers to be free
322
     * We need this step since each one, ie ref, recon io etc only unset their
323
     * respective flags. Hence we need to combine togather and mark the ref set
324
     * accordingly
325
     */
326
29.3k
    pi4_ref_set_id[0] = -1;
327
328
173k
    for(i = 0; i < ps_codec->i4_ref_buf_cnt; i++)
329
143k
    {
330
143k
        if(ps_codec->as_ref_set[i].i4_pic_cnt == -1)
331
90.2k
        {
332
90.2k
            pi4_ref_set_id[0] = i;
333
90.2k
            continue;
334
90.2k
        }
335
336
53.5k
        buf_status = ih264_buf_mgr_get_status(ps_codec->pv_ref_buf_mgr,
337
53.5k
                                              ps_codec->as_ref_set[i].ps_pic_buf->i4_buf_id);
338
339
53.5k
        if((buf_status & (BUF_MGR_REF | BUF_MGR_CODEC | BUF_MGR_IO)) == 0)
340
18.4k
        {
341
18.4k
            ps_codec->as_ref_set[i].i4_pic_cnt = -1;
342
18.4k
            ps_codec->as_ref_set[i].i4_poc = 32768;
343
344
18.4k
            pi4_ref_set_id[0] = i;
345
18.4k
        }
346
53.5k
    }
347
348
    /* An asssert failure here means we donot have any free buffs */
349
29.3k
    if(pi4_ref_set_id[0] < 0)
350
1.13k
    {
351
1.13k
        return IH264E_FAIL;
352
1.13k
    }
353
354
28.2k
    return IH264E_SUCCESS;
355
29.3k
}
356
357
/**
358
*******************************************************************************
359
*
360
* @brief
361
*  Validates SVC AU properties
362
*
363
* @param[in] ps_cfg
364
*  Cfg parameters
365
*
366
* @returns  error code in conformance with 'IH264E_ERROR_T'
367
*
368
*******************************************************************************
369
*/
370
WORD32 isvce_svc_au_props_validate(svc_inp_params_t *ps_svc_inp_params, UWORD32 u4_inp_wd,
371
                                   UWORD32 u4_inp_ht, UWORD32 u4_svc_comp_wd,
372
                                   UWORD32 u4_svc_comp_ht)
373
14.8k
{
374
14.8k
    typedef struct
375
14.8k
    {
376
14.8k
        DOUBLE d_spatial_res_ratio;
377
378
14.8k
        UWORD8 u1_max_num_spatial_layers;
379
14.8k
    } spatial_layer_props_t;
380
381
14.8k
    UWORD8 i;
382
14.8k
    UWORD32 au4_svc_wd[MAX_NUM_SPATIAL_LAYERS];
383
14.8k
    UWORD32 au4_svc_ht[MAX_NUM_SPATIAL_LAYERS];
384
385
14.8k
    DOUBLE d_scaling_factor = ps_svc_inp_params->d_spatial_res_ratio;
386
14.8k
    UWORD8 u1_num_spatial_layers = ps_svc_inp_params->u1_num_spatial_layers;
387
14.8k
    const spatial_layer_props_t gas_valid_spatial_layer_props[] = {{1.5, 2}, {2, 3}};
388
14.8k
    UWORD32 u4_error_code = IV_SUCCESS;
389
14.8k
    const UWORD8 u1_min_num_temporal_layers = 1;
390
14.8k
    const UWORD8 u1_min_num_spatial_layers = 1;
391
14.8k
    const UWORD8 u1_max_num_temporal_layers = MAX_NUM_TEMPORAL_LAYERS;
392
14.8k
    const UWORD8 u1_max_num_spatial_layers = MAX_NUM_SPATIAL_LAYERS;
393
14.8k
    const UWORD8 u1_num_valid_spatial_layer_props =
394
14.8k
        sizeof(gas_valid_spatial_layer_props) / sizeof(gas_valid_spatial_layer_props[0]);
395
396
14.8k
    if((ps_svc_inp_params->u1_num_temporal_layers < u1_min_num_temporal_layers) ||
397
14.8k
       (ps_svc_inp_params->u1_num_temporal_layers > u1_max_num_temporal_layers))
398
0
    {
399
0
        u4_error_code |= IH264E_INVALID_SVC_PARAMS | IH264E_INVALID_NUM_TEMPORAL_LAYERS;
400
0
    }
401
402
14.8k
    if((ps_svc_inp_params->u1_num_spatial_layers < u1_min_num_spatial_layers) ||
403
14.8k
       (ps_svc_inp_params->u1_num_spatial_layers > u1_max_num_spatial_layers))
404
0
    {
405
0
        u4_error_code |= IH264E_INVALID_SVC_PARAMS | IH264E_INVALID_NUM_SPATIAL_LAYERS;
406
0
    }
407
408
14.8k
    {
409
14.8k
        UWORD8 u1_is_input_ratio_valid = 0;
410
411
24.5k
        for(i = 0; i < u1_num_valid_spatial_layer_props; i++)
412
24.5k
        {
413
24.5k
            if(ps_svc_inp_params->d_spatial_res_ratio ==
414
24.5k
               gas_valid_spatial_layer_props[i].d_spatial_res_ratio)
415
14.8k
            {
416
14.8k
                u1_is_input_ratio_valid = 1;
417
418
14.8k
                if(ps_svc_inp_params->u1_num_spatial_layers >
419
14.8k
                   gas_valid_spatial_layer_props[i].u1_max_num_spatial_layers)
420
1
                {
421
1
                    u4_error_code |= IH264E_INVALID_SVC_PARAMS | IH264E_INVALID_NUM_SPATIAL_LAYERS;
422
1
                }
423
424
14.8k
                break;
425
14.8k
            }
426
24.5k
        }
427
428
14.8k
        if(!u1_is_input_ratio_valid)
429
0
        {
430
0
            u4_error_code |= IH264E_INVALID_SVC_PARAMS | IH264E_INVALID_SPATIAL_RES_RATIO;
431
0
        }
432
14.8k
    }
433
434
14.8k
    if((u4_svc_comp_wd > SVCE_MAX_INP_DIM) || (u4_svc_comp_ht > SVCE_MAX_INP_DIM) ||
435
14.8k
       ((u4_svc_comp_wd * u4_svc_comp_ht) > SVCE_MAX_INP_FRAME_SIZE) ||
436
14.8k
       (u4_svc_comp_wd % 16 != 0) || (u4_svc_comp_ht % 16 != 0))
437
7
    {
438
7
        u4_error_code |= IH264E_INVALID_SVC_INPUT_DIMENSIONS;
439
7
    }
440
441
    /* Constraint from padding intrinsics */
442
14.8k
    if((u4_svc_comp_wd - u4_inp_wd) % 16)
443
1
    {
444
1
        u4_error_code |= IH264E_INVALID_SVC_INPUT_DIMENSIONS;
445
1
    }
446
447
    /* Constraint from 420p to 420sp conversion */
448
14.8k
    if((u4_svc_comp_ht - u4_inp_ht) % 4)
449
1
    {
450
1
        u4_error_code |= IH264E_INVALID_SVC_INPUT_DIMENSIONS;
451
1
    }
452
453
14.8k
    au4_svc_wd[u1_num_spatial_layers - 1] = u4_svc_comp_wd;
454
14.8k
    au4_svc_ht[u1_num_spatial_layers - 1] = u4_svc_comp_ht;
455
456
34.2k
    for(i = (u1_num_spatial_layers - 1); i > 0; i--)
457
19.4k
    {
458
19.4k
        au4_svc_wd[i - 1] = au4_svc_wd[i] / d_scaling_factor;
459
19.4k
        au4_svc_ht[i - 1] = au4_svc_ht[i] / d_scaling_factor;
460
461
19.4k
        if((au4_svc_wd[i - 1] * d_scaling_factor != au4_svc_wd[i]) ||
462
19.4k
           (au4_svc_ht[i - 1] * d_scaling_factor != au4_svc_ht[i]) ||
463
19.4k
           (au4_svc_ht[i - 1] % 16 != 0) || (au4_svc_ht[i - 1] % 16 != 0))
464
0
        {
465
0
            u4_error_code |= IH264E_INVALID_SVC_INPUT_DIMENSIONS;
466
0
        }
467
19.4k
    }
468
469
14.8k
    return u4_error_code;
470
14.8k
}
471
472
/**
473
*******************************************************************************
474
*
475
* @brief
476
*  Validates SVC input params
477
*
478
* @param[in] ps_cfg
479
*  Cfg parameters
480
*
481
* @returns  error code in conformance with 'IH264E_ERROR_T'
482
*
483
*******************************************************************************
484
*/
485
WORD32 isvce_svc_inp_params_validate(isvce_init_ip_t *ps_ip, isvce_cfg_params_t *ps_cfg)
486
4.93k
{
487
4.93k
    UWORD32 u4_error_code = isvce_svc_au_props_validate(&ps_ip->s_svc_inp_params, ps_ip->u4_wd,
488
4.93k
                                                        ps_ip->u4_ht, ps_cfg->u4_wd, ps_cfg->u4_ht);
489
490
4.93k
    if(ps_cfg->u4_enable_alt_ref)
491
0
    {
492
0
        u4_error_code |= IH264E_INVALID_ALT_REF_OPTION;
493
0
    }
494
495
4.93k
    if(ps_cfg->u4_num_bframes)
496
0
    {
497
0
        u4_error_code |= IH264E_BFRAMES_NOT_SUPPORTED;
498
0
    }
499
500
4.93k
    if(ps_cfg->e_slice_mode != IVE_SLICE_MODE_NONE)
501
0
    {
502
0
        u4_error_code |= IH264E_SLICE_TYPE_INPUT_INVALID;
503
0
    }
504
505
4.93k
    if(ps_cfg->e_content_type != IV_PROGRESSIVE)
506
0
    {
507
0
        u4_error_code |= IH264E_CONTENT_TYPE_NOT_SUPPORTED;
508
0
    }
509
510
4.93k
    if(ps_cfg->u4_weighted_prediction)
511
0
    {
512
0
        u4_error_code |= IH264E_WEIGHTED_PRED_NOT_SUPPORTED;
513
0
    }
514
515
4.93k
    return u4_error_code;
516
4.93k
}
517
518
/**
519
*******************************************************************************
520
*
521
* @brief
522
*  Validates SVC RC params
523
*
524
* @param[in] ps_cfg
525
*  Cfg parameters
526
*
527
* @returns  error code in conformance with 'IH264E_ERROR_T'
528
*
529
*******************************************************************************
530
*/
531
static WORD32 isvce_svc_rc_params_validate(isvce_cfg_params_t *ps_cfg)
532
13.1k
{
533
13.1k
    WORD32 i;
534
535
    /* RC requires total bits in a second to fit int32_t */
536
42.7k
    for(i = 0; i < ps_cfg->s_svc_params.u1_num_spatial_layers; i++)
537
30.0k
    {
538
30.0k
        if((((((UWORD64) ps_cfg->au4_target_bitrate[i]) * 1000llu) / ps_cfg->u4_tgt_frame_rate) *
539
30.0k
            ps_cfg->u4_idr_frm_interval) > ((UWORD64) INT32_MAX))
540
433
        {
541
433
            return IH264E_BITRATE_NOT_SUPPORTED;
542
433
        }
543
30.0k
    }
544
545
12.7k
    return IH264E_SUCCESS;
546
13.1k
}
547
548
/**
549
*******************************************************************************
550
*
551
* @brief
552
*  Validates SVC frame-level input params
553
*
554
* @param[in] ps_cfg
555
*  Cfg parameters
556
*
557
* @returns  error code in conformance with 'IH264E_ERROR_T'
558
*
559
*******************************************************************************
560
*/
561
WORD32 isvce_svc_frame_params_validate(
562
    rate_control_api_t *aps_rate_control_api[MAX_NUM_SPATIAL_LAYERS], UWORD8 u1_num_spatial_layers)
563
43.1k
{
564
43.1k
    WORD32 i;
565
566
    /* RC requires total bits in a second to fit int32_t */
567
133k
    for(i = 0; i < u1_num_spatial_layers; i++)
568
91.7k
    {
569
91.7k
        if((((UWORD64) irc_get_bits_per_frame(aps_rate_control_api[i])) *
570
91.7k
            irc_get_intra_frame_interval(aps_rate_control_api[i])) > ((UWORD64) INT32_MAX))
571
1.92k
        {
572
1.92k
            return IH264E_BITRATE_NOT_SUPPORTED;
573
1.92k
        }
574
91.7k
    }
575
576
41.2k
    return IV_SUCCESS;
577
43.1k
}
578
579
/**
580
*******************************************************************************
581
*
582
* @brief
583
*  Used to get reference picture buffer size for a given level and
584
*  and padding used
585
*
586
* @param[in] ps_svc_inp_params
587
*  Struct containing SVC specific input params
588
*
589
* @param[in] i4_pic_size
590
*  Number of luma samples (Width * Height)
591
*
592
* @param[in] i4_level
593
*  Level
594
*
595
* @param[in] i4_horz_pad
596
*  Total padding used in horizontal direction
597
*
598
* @param[in] i4_vert_pad
599
*  Total padding used in vertical direction
600
*
601
* @param[in] i4_num_ref_frames
602
*  Num Reference Frames
603
*
604
* @param[in] i4_num_reorder_frames
605
*  Num Reorder Frames
606
*
607
* @returns  Total picture buffer size
608
*
609
*******************************************************************************
610
*/
611
WORD32 isvce_get_total_svc_au_buf_size(svc_inp_params_t *ps_svc_inp_params, WORD32 i4_pic_size,
612
                                       WORD32 i4_level, WORD32 i4_horz_pad, WORD32 i4_vert_pad,
613
                                       WORD32 i4_num_ref_frames, WORD32 i4_num_reorder_frames)
614
9.87k
{
615
9.87k
    WORD32 i;
616
9.87k
    WORD32 size;
617
9.87k
    WORD32 num_luma_samples;
618
9.87k
    WORD32 lvl_idx;
619
9.87k
    WORD32 max_wd, min_ht;
620
9.87k
    WORD32 num_samples;
621
9.87k
    WORD32 max_num_bufs;
622
623
9.87k
    WORD32 pad = MAX(i4_horz_pad, i4_vert_pad);
624
9.87k
    DOUBLE d_svc_size_multiplier = 1;
625
626
22.8k
    for(i = 1; i < ps_svc_inp_params->u1_num_spatial_layers; i++)
627
12.9k
    {
628
12.9k
        d_svc_size_multiplier += 1. / pow(ps_svc_inp_params->d_spatial_res_ratio, i);
629
12.9k
    }
630
631
    /*
632
     * If i4_num_ref_frames and num_reorder_frmaes is specified
633
     * Use minimum value
634
     */
635
9.87k
    max_num_bufs = (i4_num_ref_frames + i4_num_reorder_frames + MAX_CTXT_SETS +
636
9.87k
                    ps_svc_inp_params->u1_num_temporal_layers);
637
638
    /* Get i4_level index */
639
9.87k
    lvl_idx = ih264e_get_lvl_idx(i4_level);
640
641
    /* Maximum number of luma samples in a picture at given i4_level */
642
9.87k
    num_luma_samples = gai4_ih264_max_luma_pic_size[lvl_idx];
643
9.87k
    num_luma_samples = MAX(num_luma_samples, i4_pic_size);
644
645
    /* Account for chroma */
646
9.87k
    num_samples = num_luma_samples * 3 / 2;
647
648
    /* Maximum width of luma samples in a picture at given i4_level */
649
9.87k
    max_wd = gai4_ih264_max_wd_ht[lvl_idx];
650
651
    /* Minimum height of luma samples in a picture at given i4_level */
652
9.87k
    min_ht = gai4_ih264_min_wd_ht[lvl_idx];
653
654
    /* Allocation is required for
655
     * (Wd + i4_horz_pad) * (Ht + i4_vert_pad) * (2 * max_dpb_size + 1)
656
     *
657
     * Above expanded as
658
     * ((Wd * Ht) + (i4_horz_pad * i4_vert_pad) + Wd * i4_vert_pad + Ht *
659
     * i4_horz_pad) * (2 * max_dpb_size + 1) (Wd * Ht) * (2 * max_dpb_size + 1) +
660
     * ((i4_horz_pad * i4_vert_pad) + Wd * i4_vert_pad + Ht * i4_horz_pad) * (2 *
661
     * max_dpb_size + 1) Now max_dpb_size increases with smaller Wd and Ht, but Wd
662
     * * ht * max_dpb_size will still be lesser or equal to max_wd * max_ht *
663
     * dpb_size
664
     *
665
     * In the above equation (Wd * Ht) * (2 * max_dpb_size + 1) is accounted by
666
     * using num_samples * (2 * max_dpb_size + 1) below
667
     *
668
     * For the padded area use MAX(i4_horz_pad, i4_vert_pad) as pad
669
     * ((pad * pad) + pad * (Wd + Ht)) * (2 * max_dpb_size + 1) has to accounted
670
     * from the above for padding
671
     *
672
     * Since Width and Height can change worst Wd + Ht is when One of the
673
     * dimensions is max and other is min So use max_wd and min_ht
674
     */
675
676
    /* Number of bytes in reference pictures */
677
9.87k
    size = num_samples * max_num_bufs;
678
679
    /* Account for Spatial Layers */
680
9.87k
    size = (WORD32) (size * d_svc_size_multiplier + 0.99);
681
682
    /* Account for padding area */
683
9.87k
    size += ((pad * pad) + pad * (max_wd + min_ht)) * 3 / 2 * max_num_bufs *
684
9.87k
            ps_svc_inp_params->u1_num_spatial_layers;
685
686
9.87k
    size += ps_svc_inp_params->u1_num_spatial_layers * sizeof(yuv_buf_props_t);
687
688
9.87k
    return size;
689
9.87k
}
690
691
/**
692
*******************************************************************************
693
*
694
* @brief
695
*  Used to get size of buffers used for storing prediction data
696
*
697
* @param[in] ps_svc_inp_params
698
*  Struct containing SVC specific input params
699
*
700
* @param[in] i4_num_luma_samples
701
*  Number of luma samples (Width * Height)
702
*
703
* @returns  Size of buffers used for storing prediction data
704
*
705
*******************************************************************************
706
*/
707
UWORD32 isvce_get_total_svc_au_data_size(WORD32 i4_num_luma_samples, UWORD8 u1_num_spatial_layers,
708
                                         DOUBLE d_spatial_res_ratio)
709
9.87k
{
710
9.87k
    WORD32 i;
711
712
9.87k
    UWORD32 u4_svc_au_data_size = 0;
713
714
9.87k
    u4_svc_au_data_size += u1_num_spatial_layers * sizeof(svc_layer_data_t);
715
716
32.7k
    for(i = 0; i < u1_num_spatial_layers; i++)
717
22.8k
    {
718
22.8k
        WORD32 i4_layer_luma_samples =
719
22.8k
            ((DOUBLE) i4_num_luma_samples) / pow(pow(d_spatial_res_ratio, i), 2) + 0.99;
720
22.8k
        WORD32 i4_num_mbs = i4_layer_luma_samples / (MB_SIZE * MB_SIZE);
721
722
        /* isvce_mb_info_t */
723
22.8k
        u4_svc_au_data_size += i4_num_mbs * sizeof(isvce_mb_info_t);
724
725
        /* pu4_num_pus_in_mb */
726
22.8k
        u4_svc_au_data_size += i4_num_mbs * sizeof(UWORD32);
727
22.8k
    }
728
729
9.87k
    return u4_svc_au_data_size;
730
9.87k
}
731
732
/**
733
*******************************************************************************
734
*
735
* @brief Function to add buffers to SVC AU Data Store Manager
736
*
737
* @param[in] ps_codec
738
*  Pointer to codec context
739
*
740
* @returns  error status
741
*
742
*******************************************************************************
743
*/
744
IH264E_ERROR_T isvce_svc_au_data_mgr_add_bufs(isvce_codec_t *ps_codec)
745
9.77k
{
746
9.77k
    IH264_ERROR_T ret;
747
748
9.77k
    WORD32 i, j;
749
9.77k
    UWORD8 *pu1_buf;
750
751
9.77k
    svc_au_data_t *ps_svc_au_data = ps_codec->ps_svc_au_data_base;
752
753
9.77k
    WORD32 i4_max_dpb_size = ps_codec->i4_ref_buf_cnt;
754
9.77k
    WORD64 i8_alloc_mem_size = ps_codec->i4_svc_au_data_size;
755
9.77k
    WORD32 i4_num_luma_samples = ALIGN16(ps_codec->s_cfg.u4_wd) * ALIGN16(ps_codec->s_cfg.u4_ht);
756
9.77k
    UWORD8 u1_num_spatial_layers = ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers;
757
9.77k
    DOUBLE d_spatial_res_ratio = ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio;
758
759
9.77k
    ps_codec->ps_svc_au_data = ps_svc_au_data;
760
9.77k
    pu1_buf = (UWORD8 *) ps_svc_au_data;
761
9.77k
    pu1_buf += BUF_MGR_MAX_CNT * sizeof(ps_svc_au_data[0]);
762
763
9.77k
    i8_alloc_mem_size -= (BUF_MGR_MAX_CNT * sizeof(ps_svc_au_data[0]));
764
765
9.77k
    i = 0;
766
767
57.2k
    while(i < i4_max_dpb_size)
768
47.4k
    {
769
47.4k
        ps_svc_au_data->ps_svc_layer_data = (svc_layer_data_t *) pu1_buf;
770
47.4k
        pu1_buf += u1_num_spatial_layers * sizeof(ps_svc_au_data->ps_svc_layer_data[0]);
771
47.4k
        i8_alloc_mem_size -= u1_num_spatial_layers * sizeof(ps_svc_au_data->ps_svc_layer_data[0]);
772
773
158k
        for(j = u1_num_spatial_layers - 1; j >= 0; j--)
774
110k
        {
775
110k
            WORD32 i4_layer_luma_samples =
776
110k
                ((DOUBLE) i4_num_luma_samples) /
777
110k
                    pow(pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - j), 2) +
778
110k
                0.99;
779
110k
            WORD32 i4_num_mbs = i4_layer_luma_samples / (MB_SIZE * MB_SIZE);
780
781
110k
            ps_svc_au_data->ps_svc_layer_data[j].pu4_num_pus_in_mb = (UWORD32 *) pu1_buf;
782
110k
            pu1_buf +=
783
110k
                i4_num_mbs * sizeof(ps_svc_au_data->ps_svc_layer_data[j].pu4_num_pus_in_mb[0]);
784
110k
            i8_alloc_mem_size -=
785
110k
                i4_num_mbs * sizeof(ps_svc_au_data->ps_svc_layer_data[j].pu4_num_pus_in_mb[0]);
786
787
110k
            ps_svc_au_data->ps_svc_layer_data[j].ps_mb_info = (isvce_mb_info_t *) pu1_buf;
788
110k
            pu1_buf += i4_num_mbs * sizeof(ps_svc_au_data->ps_svc_layer_data[j].ps_mb_info[0]);
789
110k
            i8_alloc_mem_size -=
790
110k
                i4_num_mbs * sizeof(ps_svc_au_data->ps_svc_layer_data[j].ps_mb_info[0]);
791
792
110k
            ASSERT(i8_alloc_mem_size >= 0);
793
110k
        }
794
795
47.4k
        if(i8_alloc_mem_size < 0)
796
0
        {
797
0
            ps_codec->i4_error_code = IH264E_INSUFFICIENT_MEM_MVBANK;
798
799
0
            return IH264E_INSUFFICIENT_MEM_MVBANK;
800
0
        }
801
802
47.4k
        ret =
803
47.4k
            ih264_buf_mgr_add((buf_mgr_t *) ps_codec->pv_svc_au_data_store_mgr, ps_svc_au_data, i);
804
805
47.4k
        if(IH264_SUCCESS != ret)
806
0
        {
807
0
            ps_codec->i4_error_code = IH264E_BUF_MGR_ERROR;
808
809
0
            return IH264E_BUF_MGR_ERROR;
810
0
        }
811
812
47.4k
        ps_svc_au_data++;
813
47.4k
        i++;
814
47.4k
    }
815
816
9.77k
    return IH264E_SUCCESS;
817
9.77k
}
818
819
/**
820
*******************************************************************************
821
*
822
* @brief
823
*  Function to initialize svc_au_buf_t structs add au buffers to
824
*  buffer manager in case of non-shared mode
825
*
826
* @param[in] ps_codec
827
*  Pointer to codec context
828
*
829
* @returns  error status
830
*
831
*******************************************************************************
832
*/
833
IH264E_ERROR_T isvce_svc_au_buf_mgr_add_bufs(isvce_codec_t *ps_codec)
834
9.77k
{
835
9.77k
    WORD32 i, j;
836
9.77k
    WORD32 buf_ret;
837
838
9.77k
    svc_au_buf_t *ps_pic_buf = ps_codec->ps_pic_buf;
839
840
9.77k
    IH264E_ERROR_T ret = IH264E_SUCCESS;
841
842
9.77k
    WORD32 i4_max_dpb_size = ps_codec->i4_ref_buf_cnt;
843
9.77k
    WORD64 i8_alloc_mem_size =
844
9.77k
        ps_codec->i4_total_pic_buf_size - BUF_MGR_MAX_CNT * sizeof(ps_pic_buf[0]);
845
9.77k
    UWORD8 *pu1_buf = (UWORD8 *) ps_codec->ps_pic_buf;
846
9.77k
    UWORD8 u1_num_spatial_layers = ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers;
847
9.77k
    DOUBLE d_spatial_res_ratio = ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio;
848
849
9.77k
    pu1_buf += BUF_MGR_MAX_CNT * sizeof(svc_au_buf_t);
850
851
57.2k
    for(i = 0; i < i4_max_dpb_size; i++)
852
47.4k
    {
853
47.4k
        WORD32 i4_total_fpel_mem_size = 0;
854
855
47.4k
        ps_pic_buf->ps_layer_yuv_buf_props = (yuv_buf_props_t *) pu1_buf;
856
47.4k
        pu1_buf += u1_num_spatial_layers * sizeof(ps_pic_buf->ps_layer_yuv_buf_props[0]);
857
47.4k
        i8_alloc_mem_size -= u1_num_spatial_layers * sizeof(ps_pic_buf->ps_layer_yuv_buf_props[0]);
858
859
47.4k
        if(i8_alloc_mem_size < 0)
860
0
        {
861
0
            ps_codec->i4_error_code = IH264E_INSUFFICIENT_MEM_PICBUF;
862
0
            return IH264E_INSUFFICIENT_MEM_PICBUF;
863
0
        }
864
865
158k
        for(j = u1_num_spatial_layers - 1; j >= 0; j--)
866
110k
        {
867
110k
            WORD32 i4_layer_luma_wd = ((DOUBLE) ps_codec->s_cfg.u4_wd /
868
110k
                                       pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - j)) +
869
110k
                                      0.99;
870
110k
            WORD32 i4_layer_luma_ht = ((DOUBLE) ps_codec->s_cfg.u4_ht /
871
110k
                                       pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - j)) +
872
110k
                                      0.99;
873
110k
            WORD32 i4_layer_luma_samples =
874
110k
                (ALIGN16(i4_layer_luma_wd) + PAD_WD) * (i4_layer_luma_ht + PAD_HT);
875
110k
            WORD32 i4_layer_uv_wd = i4_layer_luma_wd;
876
110k
            WORD32 i4_layer_uv_ht = i4_layer_luma_ht / 2.0 + 0.99;
877
110k
            WORD32 i4_layer_uv_samples =
878
110k
                (ALIGN16(i4_layer_uv_wd) + PAD_WD) * (i4_layer_uv_ht + PAD_HT);
879
880
110k
            ps_pic_buf->ps_layer_yuv_buf_props[j].as_component_bufs[0].i4_data_stride =
881
110k
                ALIGN16(i4_layer_luma_wd) + PAD_WD;
882
110k
            ps_pic_buf->ps_layer_yuv_buf_props[j].as_component_bufs[0].pv_data =
883
110k
                pu1_buf +
884
110k
                ps_pic_buf->ps_layer_yuv_buf_props[j].as_component_bufs[0].i4_data_stride *
885
110k
                    PAD_TOP +
886
110k
                PAD_LEFT;
887
888
110k
            pu1_buf += i4_layer_luma_samples;
889
890
110k
            ps_pic_buf->ps_layer_yuv_buf_props[j].as_component_bufs[1].i4_data_stride =
891
110k
                ALIGN16(i4_layer_uv_wd) + PAD_WD;
892
110k
            ps_pic_buf->ps_layer_yuv_buf_props[j].as_component_bufs[1].pv_data =
893
110k
                pu1_buf +
894
110k
                ps_pic_buf->ps_layer_yuv_buf_props[j].as_component_bufs[1].i4_data_stride *
895
110k
                    (PAD_TOP / 2) +
896
110k
                PAD_LEFT;
897
898
110k
            pu1_buf += i4_layer_uv_samples;
899
900
110k
            ps_pic_buf->ps_layer_yuv_buf_props[j].u4_width = i4_layer_luma_wd;
901
110k
            ps_pic_buf->ps_layer_yuv_buf_props[j].u4_height = i4_layer_luma_ht;
902
110k
            ps_pic_buf->ps_layer_yuv_buf_props[j].u1_bit_depth = 8;
903
110k
            ps_pic_buf->ps_layer_yuv_buf_props[j].e_color_format = IV_YUV_420SP_UV;
904
905
110k
            i8_alloc_mem_size -= i4_layer_luma_samples + i4_layer_uv_samples;
906
110k
            i4_total_fpel_mem_size += i4_layer_luma_samples + i4_layer_uv_samples;
907
908
110k
            if(i8_alloc_mem_size < 0)
909
23
            {
910
23
                ps_codec->i4_error_code = IH264E_INSUFFICIENT_MEM_PICBUF;
911
23
                return IH264E_INSUFFICIENT_MEM_PICBUF;
912
23
            }
913
110k
        }
914
915
47.4k
        buf_ret = ih264_buf_mgr_add((buf_mgr_t *) ps_codec->pv_ref_buf_mgr, ps_pic_buf, i);
916
917
47.4k
        if(0 != buf_ret)
918
0
        {
919
0
            ps_codec->i4_error_code = IH264E_BUF_MGR_ERROR;
920
0
            return IH264E_BUF_MGR_ERROR;
921
0
        }
922
923
47.4k
        pu1_buf += (HPEL_PLANES_CNT - 1) * i4_total_fpel_mem_size;
924
47.4k
        ps_pic_buf++;
925
47.4k
    }
926
927
9.75k
    return ret;
928
9.77k
}
929
930
/**
931
*******************************************************************************
932
*
933
* @brief
934
*  Returns size of buffers for storing SVC input data
935
*
936
* @param[in] u1_num_spatial_layers
937
*  Num Spatial Layers
938
*
939
* @param[in] d_spatial_res_ratio
940
*  Resolution Ratio b/w spatial layers
941
*
942
* @param[in] u4_wd
943
*  Input Width
944
*
945
* @param[in] u4_ht
946
*  Input Height
947
*
948
* @returns  Size of buffers
949
*
950
*******************************************************************************
951
*/
952
UWORD32 isvce_get_svc_inp_buf_size(UWORD8 u1_num_spatial_layers, DOUBLE d_spatial_res_ratio,
953
                                   UWORD32 u4_wd, UWORD32 u4_ht)
954
14.8k
{
955
14.8k
    padding_dims_t s_pad_dims;
956
957
14.8k
    UWORD32 i;
958
14.8k
    UWORD8 u1_filter_padding_size_x, u1_filter_padding_size_y;
959
960
14.8k
    UWORD32 u4_size = 0;
961
962
14.8k
    isvce_get_downscaler_padding_dims(&s_pad_dims);
963
964
14.8k
    u1_filter_padding_size_x = s_pad_dims.u1_left_pad_size + s_pad_dims.u1_right_pad_size;
965
966
14.8k
    u1_filter_padding_size_y = s_pad_dims.u1_top_pad_size + s_pad_dims.u1_bottom_pad_size;
967
968
49.0k
    for(i = 0; i < u1_num_spatial_layers; i++)
969
34.2k
    {
970
34.2k
        WORD32 i4_layer_luma_wd = ((DOUBLE) u4_wd / pow(d_spatial_res_ratio, i)) + 0.99;
971
34.2k
        WORD32 i4_layer_luma_ht = ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, i)) + 0.99;
972
34.2k
        WORD32 i4_layer_luma_samples =
973
34.2k
            (ALIGN16(i4_layer_luma_wd) + PAD_WD + u1_filter_padding_size_x) *
974
34.2k
            (i4_layer_luma_ht + PAD_HT + u1_filter_padding_size_y);
975
34.2k
        WORD32 i4_layer_uv_wd = i4_layer_luma_wd;
976
34.2k
        WORD32 i4_layer_uv_ht = i4_layer_luma_ht / 2.0 + 0.99;
977
        /* u1_filter_padding_size_x * 2 because U and V
978
        both need same amount of padding */
979
34.2k
        WORD32 i4_layer_uv_samples =
980
34.2k
            (ALIGN16(i4_layer_uv_wd) + PAD_WD + u1_filter_padding_size_x * 2) *
981
34.2k
            (i4_layer_uv_ht + PAD_HT + u1_filter_padding_size_y);
982
983
34.2k
        u4_size += (i4_layer_luma_samples + i4_layer_uv_samples) * sizeof(UWORD8);
984
34.2k
    }
985
986
14.8k
    return SVC_MAX_NUM_INP_FRAMES * u4_size;
987
14.8k
}
988
989
/**
990
*******************************************************************************
991
*
992
* @brief
993
*  Function to initialize svc input buffers
994
*
995
* @param[in] ps_codec
996
*  Pointer to codec context
997
*
998
* @param[in] ps_mem_rec
999
*  Pointer to memory allocated for input buffers
1000
*
1001
*******************************************************************************
1002
*/
1003
void isvce_svc_inp_buf_init(isvce_codec_t *ps_codec, iv_mem_rec_t *ps_mem_rec)
1004
4.93k
{
1005
4.93k
    padding_dims_t s_pad_dims;
1006
1007
4.93k
    WORD32 i, j;
1008
4.93k
    UWORD8 u1_filter_padding_size_x, u1_filter_padding_size_y;
1009
1010
4.93k
    DOUBLE d_spatial_res_ratio = ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio;
1011
4.93k
    UWORD8 u1_num_spatial_layers = ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers;
1012
4.93k
    UWORD32 u4_wd = ps_codec->s_cfg.u4_wd;
1013
4.93k
    UWORD32 u4_ht = ps_codec->s_cfg.u4_ht;
1014
4.93k
    UWORD8 *pu1_buf = ps_mem_rec->pv_base;
1015
4.93k
    WORD64 i8_alloc_mem_size =
1016
4.93k
        isvce_get_svc_inp_buf_size(u1_num_spatial_layers, d_spatial_res_ratio, u4_wd, u4_ht);
1017
1018
4.93k
    isvce_get_downscaler_padding_dims(&s_pad_dims);
1019
1020
4.93k
    u1_filter_padding_size_x = s_pad_dims.u1_left_pad_size + s_pad_dims.u1_right_pad_size;
1021
1022
4.93k
    u1_filter_padding_size_y = s_pad_dims.u1_top_pad_size + s_pad_dims.u1_bottom_pad_size;
1023
1024
14.8k
    for(i = 0; i < SVC_MAX_NUM_INP_FRAMES; i++)
1025
9.86k
    {
1026
9.86k
        ps_codec->as_inp_list[i].s_svc_params = ps_codec->s_cfg.s_svc_params;
1027
1028
32.6k
        for(j = u1_num_spatial_layers - 1; j >= 0; j--)
1029
22.8k
        {
1030
22.8k
            WORD32 i4_layer_luma_wd =
1031
22.8k
                ((DOUBLE) u4_wd / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - j)) + 0.99;
1032
22.8k
            WORD32 i4_layer_luma_ht =
1033
22.8k
                ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - j)) + 0.99;
1034
22.8k
            WORD32 i4_layer_luma_samples =
1035
22.8k
                (ALIGN16(i4_layer_luma_wd) + PAD_WD + u1_filter_padding_size_x) *
1036
22.8k
                (i4_layer_luma_ht + PAD_HT + u1_filter_padding_size_y);
1037
22.8k
            WORD32 i4_layer_uv_wd = i4_layer_luma_wd;
1038
22.8k
            WORD32 i4_layer_uv_ht = i4_layer_luma_ht / 2.0 + 0.99;
1039
            /* u1_filter_padding_size_x * 2 because U and V
1040
            both need same amount of padding */
1041
22.8k
            WORD32 i4_layer_uv_samples =
1042
22.8k
                (ALIGN16(i4_layer_uv_wd) + PAD_WD + u1_filter_padding_size_x * 2) *
1043
22.8k
                (i4_layer_uv_ht + PAD_HT + u1_filter_padding_size_y);
1044
1045
22.8k
            ps_codec->as_inp_list[i].as_layer_yuv_buf_props[j].as_component_bufs[Y].i4_data_stride =
1046
22.8k
                ALIGN16(i4_layer_luma_wd) + PAD_WD + u1_filter_padding_size_x;
1047
22.8k
            ps_codec->as_inp_list[i].as_layer_yuv_buf_props[j].as_component_bufs[Y].pv_data =
1048
22.8k
                pu1_buf +
1049
22.8k
                ps_codec->as_inp_list[i]
1050
22.8k
                        .as_layer_yuv_buf_props[j]
1051
22.8k
                        .as_component_bufs[Y]
1052
22.8k
                        .i4_data_stride *
1053
22.8k
                    (PAD_TOP + s_pad_dims.u1_top_pad_size) +
1054
22.8k
                (PAD_LEFT + s_pad_dims.u1_left_pad_size);
1055
22.8k
            pu1_buf += i4_layer_luma_samples * sizeof(UWORD8);
1056
22.8k
            i8_alloc_mem_size -= i4_layer_luma_samples * sizeof(UWORD8);
1057
1058
22.8k
            ps_codec->as_inp_list[i]
1059
22.8k
                .as_layer_yuv_buf_props[j]
1060
22.8k
                .as_component_bufs[UV]
1061
22.8k
                .i4_data_stride = ALIGN16(i4_layer_uv_wd) + PAD_WD + u1_filter_padding_size_x * 2;
1062
22.8k
            ps_codec->as_inp_list[i].as_layer_yuv_buf_props[j].as_component_bufs[UV].pv_data =
1063
22.8k
                pu1_buf +
1064
22.8k
                ps_codec->as_inp_list[i]
1065
22.8k
                        .as_layer_yuv_buf_props[j]
1066
22.8k
                        .as_component_bufs[UV]
1067
22.8k
                        .i4_data_stride *
1068
22.8k
                    (PAD_TOP + s_pad_dims.u1_top_pad_size) +
1069
22.8k
                (PAD_LEFT + s_pad_dims.u1_left_pad_size * 2);
1070
22.8k
            pu1_buf += i4_layer_uv_samples * sizeof(UWORD8);
1071
22.8k
            i8_alloc_mem_size -= i4_layer_uv_samples * sizeof(UWORD8);
1072
1073
            /* Chroma is always stored interleaved */
1074
22.8k
            ps_codec->as_inp_list[i].as_layer_yuv_buf_props[j].as_component_bufs[V].pv_data = NULL;
1075
1076
22.8k
            ps_codec->as_inp_list[i].as_layer_yuv_buf_props[j].u1_bit_depth = 8;
1077
22.8k
            ps_codec->as_inp_list[i].as_layer_yuv_buf_props[j].e_color_format = IV_YUV_420SP_UV;
1078
22.8k
            ps_codec->as_inp_list[i].as_layer_yuv_buf_props[j].u4_width = i4_layer_luma_wd;
1079
22.8k
            ps_codec->as_inp_list[i].as_layer_yuv_buf_props[j].u4_height = i4_layer_luma_ht;
1080
1081
22.8k
            ASSERT(i8_alloc_mem_size >= 0);
1082
22.8k
        }
1083
9.86k
    }
1084
4.93k
}
1085
1086
void isvce_init_svc_dimension(isvce_inp_buf_t *ps_inp)
1087
4.93k
{
1088
4.93k
    WORD32 i;
1089
1090
4.93k
    UWORD8 u1_num_spatial_layers = ps_inp->s_svc_params.u1_num_spatial_layers;
1091
4.93k
    DOUBLE d_spatial_res_ratio = ps_inp->s_svc_params.d_spatial_res_ratio;
1092
4.93k
    UWORD32 u4_wd = ps_inp->s_inp_props.s_raw_buf.au4_wd[Y];
1093
4.93k
    UWORD32 u4_ht = ps_inp->s_inp_props.s_raw_buf.au4_ht[Y];
1094
1095
16.3k
    for(i = 0; i < u1_num_spatial_layers; i++)
1096
11.4k
    {
1097
11.4k
        ps_inp->as_layer_yuv_buf_props[i].u4_width =
1098
11.4k
            ((DOUBLE) u4_wd / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) + 0.99;
1099
11.4k
        ps_inp->as_layer_yuv_buf_props[i].u4_height =
1100
11.4k
            ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) + 0.99;
1101
11.4k
    }
1102
4.93k
}
1103
1104
/**
1105
*******************************************************************************
1106
*
1107
* @brief
1108
*  Pads input buf as assumed by the downscaler filter
1109
*
1110
* @param[in] ps_codec
1111
*  Pointer to codec ctxt
1112
*
1113
* @param[in] ps_inp
1114
*  Pointer to svc input buffer
1115
*
1116
* @param[in] u1_svc_layer_index
1117
*  SVC layer index of the buffer
1118
*
1119
*******************************************************************************
1120
*/
1121
1122
static void isvce_pad_buf_for_filtering(isvce_codec_t *ps_codec, isvce_inp_buf_t *ps_inp,
1123
                                        UWORD8 u1_svc_layer_index)
1124
95.3k
{
1125
95.3k
    padding_dims_t s_pad_dims;
1126
1127
95.3k
    UWORD8 *pu1_buf;
1128
95.3k
    UWORD32 u4_buf_width, u4_buf_height;
1129
1130
95.3k
    UWORD8 u1_pad_left_size;
1131
95.3k
    UWORD8 u1_pad_right_size;
1132
95.3k
    UWORD8 u1_pad_top_size;
1133
95.3k
    UWORD8 u1_pad_bottom_size;
1134
95.3k
    UWORD8 u1_filter_padding_size_x;
1135
95.3k
    UWORD8 u1_filter_padding_size_chroma_x;
1136
1137
95.3k
    ASSERT(ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].e_color_format == IV_YUV_420SP_UV);
1138
1139
95.3k
    isvce_get_downscaler_padding_dims(&s_pad_dims);
1140
1141
95.3k
    u1_pad_left_size = s_pad_dims.u1_left_pad_size;
1142
95.3k
    u1_pad_right_size = s_pad_dims.u1_right_pad_size;
1143
95.3k
    u1_pad_top_size = s_pad_dims.u1_top_pad_size;
1144
95.3k
    u1_pad_bottom_size = s_pad_dims.u1_bottom_pad_size;
1145
95.3k
    u1_filter_padding_size_x = u1_pad_left_size + u1_pad_right_size;
1146
95.3k
    u1_filter_padding_size_chroma_x = u1_filter_padding_size_x * 2;
1147
1148
95.3k
    u4_buf_width = ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].u4_width;
1149
1150
95.3k
    u4_buf_height = ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].u4_height;
1151
1152
95.3k
    pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index]
1153
95.3k
                              .as_component_bufs[0]
1154
95.3k
                              .pv_data);
1155
1156
95.3k
    ps_codec->pf_pad_left_luma(
1157
95.3k
        pu1_buf,
1158
95.3k
        ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].as_component_bufs[0].i4_data_stride,
1159
95.3k
        u4_buf_height, u1_pad_left_size);
1160
1161
95.3k
    pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index]
1162
95.3k
                              .as_component_bufs[0]
1163
95.3k
                              .pv_data);
1164
1165
95.3k
    pu1_buf += u4_buf_width;
1166
1167
95.3k
    ps_codec->pf_pad_right_luma(
1168
95.3k
        pu1_buf,
1169
95.3k
        ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].as_component_bufs[0].i4_data_stride,
1170
95.3k
        u4_buf_height, u1_pad_right_size);
1171
1172
95.3k
    pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index]
1173
95.3k
                              .as_component_bufs[1]
1174
95.3k
                              .pv_data);
1175
1176
95.3k
    ps_codec->pf_pad_left_chroma(
1177
95.3k
        pu1_buf,
1178
95.3k
        ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].as_component_bufs[1].i4_data_stride,
1179
95.3k
        u4_buf_height / 2, u1_pad_left_size * 2);
1180
1181
95.3k
    pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index]
1182
95.3k
                              .as_component_bufs[1]
1183
95.3k
                              .pv_data);
1184
1185
95.3k
    pu1_buf += u4_buf_width;
1186
1187
95.3k
    ps_codec->pf_pad_right_chroma(
1188
95.3k
        pu1_buf,
1189
95.3k
        ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].as_component_bufs[1].i4_data_stride,
1190
95.3k
        u4_buf_height / 2, u1_pad_right_size * 2);
1191
1192
95.3k
    pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index]
1193
95.3k
                              .as_component_bufs[0]
1194
95.3k
                              .pv_data) -
1195
95.3k
              u1_pad_left_size;
1196
1197
95.3k
    ps_codec->pf_pad_top(
1198
95.3k
        pu1_buf,
1199
95.3k
        ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].as_component_bufs[0].i4_data_stride,
1200
95.3k
        (u4_buf_width + u1_filter_padding_size_x), u1_pad_top_size);
1201
1202
95.3k
    pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index]
1203
95.3k
                              .as_component_bufs[0]
1204
95.3k
                              .pv_data) -
1205
95.3k
              u1_pad_left_size;
1206
1207
95.3k
    pu1_buf +=
1208
95.3k
        (u4_buf_height *
1209
95.3k
         ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].as_component_bufs[0].i4_data_stride);
1210
1211
95.3k
    ps_codec->pf_pad_bottom(
1212
95.3k
        pu1_buf,
1213
95.3k
        ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].as_component_bufs[0].i4_data_stride,
1214
95.3k
        (u4_buf_width + u1_filter_padding_size_x), u1_pad_bottom_size);
1215
1216
95.3k
    pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index]
1217
95.3k
                              .as_component_bufs[1]
1218
95.3k
                              .pv_data) -
1219
95.3k
              u1_pad_left_size * 2;
1220
1221
95.3k
    ps_codec->pf_pad_top(
1222
95.3k
        pu1_buf,
1223
95.3k
        ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].as_component_bufs[1].i4_data_stride,
1224
95.3k
        (u4_buf_width + u1_filter_padding_size_chroma_x), u1_pad_top_size);
1225
1226
95.3k
    pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index]
1227
95.3k
                              .as_component_bufs[1]
1228
95.3k
                              .pv_data) -
1229
95.3k
              u1_pad_left_size * 2;
1230
1231
95.3k
    pu1_buf +=
1232
95.3k
        ((u4_buf_height / 2) *
1233
95.3k
         ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].as_component_bufs[1].i4_data_stride);
1234
1235
95.3k
    ps_codec->pf_pad_bottom(
1236
95.3k
        pu1_buf,
1237
95.3k
        ps_inp->as_layer_yuv_buf_props[u1_svc_layer_index].as_component_bufs[1].i4_data_stride,
1238
95.3k
        (u4_buf_width + u1_filter_padding_size_chroma_x), u1_pad_bottom_size);
1239
95.3k
}
1240
1241
/**
1242
*******************************************************************************
1243
*
1244
* @brief
1245
*  Pads raw input to satisfy SVC compliant input dimensions
1246
*
1247
* @param[in] ps_codec
1248
*  Pointer to codec ctxt
1249
*
1250
* @param[in] ps_inp
1251
*  Pointer to svc input buffer
1252
*
1253
*******************************************************************************
1254
*/
1255
1256
static void isvce_pad_input_to_svc_compliant_dims(isvce_codec_t *ps_codec, isvce_inp_buf_t *ps_inp)
1257
65.7k
{
1258
65.7k
    UWORD8 *pu1_buf;
1259
65.7k
    UWORD32 u4_raw_input_wd, u4_raw_input_ht, u4_padded_width, u4_padded_height, u4_width_delta,
1260
65.7k
        u4_height_delta;
1261
65.7k
    UWORD8 u1_num_layers = ps_inp->s_svc_params.u1_num_spatial_layers;
1262
1263
65.7k
    ASSERT(ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].e_color_format == IV_YUV_420SP_UV);
1264
1265
65.7k
    u4_padded_width = ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].u4_width;
1266
65.7k
    u4_padded_height = ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].u4_height;
1267
65.7k
    u4_raw_input_wd = ps_inp->s_inp_props.s_raw_buf.au4_wd[0];
1268
65.7k
    u4_raw_input_ht = ps_inp->s_inp_props.s_raw_buf.au4_ht[0];
1269
65.7k
    u4_width_delta = u4_padded_width - u4_raw_input_wd;
1270
65.7k
    u4_height_delta = u4_padded_height - u4_raw_input_ht;
1271
1272
65.7k
    ASSERT(!(u4_width_delta & 1));
1273
65.7k
    ASSERT(!(u4_height_delta & 1));
1274
1275
65.7k
    if(u4_width_delta)
1276
53.1k
    {
1277
53.1k
        pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
1278
53.1k
                                  .as_component_bufs[0]
1279
53.1k
                                  .pv_data);
1280
1281
53.1k
        pu1_buf += ((u4_width_delta / 2) + (ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
1282
53.1k
                                                .as_component_bufs[0]
1283
53.1k
                                                .i4_data_stride) *
1284
53.1k
                                               (u4_height_delta / 2));
1285
1286
53.1k
        ps_codec->pf_pad_left_luma(
1287
53.1k
            pu1_buf,
1288
53.1k
            ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].as_component_bufs[0].i4_data_stride,
1289
53.1k
            u4_padded_height, u4_width_delta / 2);
1290
1291
53.1k
        pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
1292
53.1k
                                  .as_component_bufs[0]
1293
53.1k
                                  .pv_data);
1294
1295
53.1k
        pu1_buf += ((u4_width_delta / 2) + (ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
1296
53.1k
                                                .as_component_bufs[0]
1297
53.1k
                                                .i4_data_stride) *
1298
53.1k
                                               (u4_height_delta / 2));
1299
1300
53.1k
        pu1_buf += u4_raw_input_wd;
1301
1302
53.1k
        ps_codec->pf_pad_right_luma(
1303
53.1k
            pu1_buf,
1304
53.1k
            ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].as_component_bufs[0].i4_data_stride,
1305
53.1k
            u4_padded_height, u4_width_delta / 2);
1306
1307
53.1k
        pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
1308
53.1k
                                  .as_component_bufs[1]
1309
53.1k
                                  .pv_data);
1310
1311
53.1k
        pu1_buf += ((u4_width_delta / 2) + (ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
1312
53.1k
                                                .as_component_bufs[1]
1313
53.1k
                                                .i4_data_stride) *
1314
53.1k
                                               (u4_height_delta / 4));
1315
1316
53.1k
        ps_codec->pf_pad_left_chroma(
1317
53.1k
            pu1_buf,
1318
53.1k
            ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].as_component_bufs[1].i4_data_stride,
1319
53.1k
            u4_padded_height / 2, u4_width_delta / 2);
1320
1321
53.1k
        pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
1322
53.1k
                                  .as_component_bufs[1]
1323
53.1k
                                  .pv_data);
1324
1325
53.1k
        pu1_buf += ((u4_width_delta / 2) + (ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
1326
53.1k
                                                .as_component_bufs[1]
1327
53.1k
                                                .i4_data_stride) *
1328
53.1k
                                               (u4_height_delta / 4));
1329
1330
53.1k
        pu1_buf += u4_raw_input_wd;
1331
1332
53.1k
        ps_codec->pf_pad_right_chroma(
1333
53.1k
            pu1_buf,
1334
53.1k
            ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].as_component_bufs[1].i4_data_stride,
1335
53.1k
            u4_padded_height / 2, u4_width_delta / 2);
1336
53.1k
    }
1337
1338
65.7k
    if(u4_height_delta)
1339
61.0k
    {
1340
61.0k
        pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
1341
61.0k
                                  .as_component_bufs[0]
1342
61.0k
                                  .pv_data);
1343
1344
61.0k
        pu1_buf += ((ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
1345
61.0k
                         .as_component_bufs[0]
1346
61.0k
                         .i4_data_stride) *
1347
61.0k
                    (u4_height_delta / 2));
1348
1349
61.0k
        ps_codec->pf_pad_top(
1350
61.0k
            pu1_buf,
1351
61.0k
            ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].as_component_bufs[0].i4_data_stride,
1352
61.0k
            u4_padded_width, u4_height_delta / 2);
1353
1354
61.0k
        pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
1355
61.0k
                                  .as_component_bufs[0]
1356
61.0k
                                  .pv_data);
1357
1358
61.0k
        pu1_buf += ((ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
1359
61.0k
                         .as_component_bufs[0]
1360
61.0k
                         .i4_data_stride) *
1361
61.0k
                    (u4_height_delta / 2));
1362
1363
61.0k
        pu1_buf +=
1364
61.0k
            (u4_raw_input_ht *
1365
61.0k
             ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].as_component_bufs[0].i4_data_stride);
1366
1367
61.0k
        ps_codec->pf_pad_bottom(
1368
61.0k
            pu1_buf,
1369
61.0k
            ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].as_component_bufs[0].i4_data_stride,
1370
61.0k
            u4_padded_width, u4_height_delta / 2);
1371
1372
61.0k
        pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
1373
61.0k
                                  .as_component_bufs[1]
1374
61.0k
                                  .pv_data);
1375
1376
61.0k
        pu1_buf += ((ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
1377
61.0k
                         .as_component_bufs[1]
1378
61.0k
                         .i4_data_stride) *
1379
61.0k
                    (u4_height_delta / 4));
1380
1381
61.0k
        ps_codec->pf_pad_top(
1382
61.0k
            pu1_buf,
1383
61.0k
            ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].as_component_bufs[1].i4_data_stride,
1384
61.0k
            u4_padded_width, u4_height_delta / 4);
1385
1386
61.0k
        pu1_buf = (UWORD8 *) (ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
1387
61.0k
                                  .as_component_bufs[1]
1388
61.0k
                                  .pv_data);
1389
1390
61.0k
        pu1_buf += ((ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1]
1391
61.0k
                         .as_component_bufs[1]
1392
61.0k
                         .i4_data_stride) *
1393
61.0k
                    (u4_height_delta / 4));
1394
1395
61.0k
        pu1_buf +=
1396
61.0k
            ((u4_raw_input_ht / 2) *
1397
61.0k
             ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].as_component_bufs[1].i4_data_stride);
1398
1399
61.0k
        ps_codec->pf_pad_bottom(
1400
61.0k
            pu1_buf,
1401
61.0k
            ps_inp->as_layer_yuv_buf_props[u1_num_layers - 1].as_component_bufs[1].i4_data_stride,
1402
61.0k
            u4_padded_width, u4_height_delta / 4);
1403
61.0k
    }
1404
65.7k
}
1405
1406
/**
1407
*******************************************************************************
1408
*
1409
* @brief
1410
*  Format conversion and downsampling for deriving spatial layer inputs
1411
*
1412
* @param[in] ps_inp
1413
*  Pointer to input buffer
1414
*
1415
*******************************************************************************
1416
*/
1417
void isvce_svc_inp_buf_populate(isvce_codec_t *ps_codec, isvce_inp_buf_t *ps_inp)
1418
65.7k
{
1419
65.7k
    yuv_buf_props_t s_src_buf_props, s_dst_buf_props;
1420
1421
65.7k
    UWORD32 i;
1422
65.7k
    UWORD32 u4_blk_x, u4_blk_y;
1423
65.7k
    UWORD8 *pu1_planar_y, *pu1_planar_u, *pu1_planar_v, *pu1_semi_planar_y, *pu1_semi_planar_uv;
1424
65.7k
    UWORD8 *pu1_src_luma, *pu1_src_chroma, *pu1_dst_luma, *pu1_dst_chroma;
1425
65.7k
    UWORD32 u4_num_blocks_x, u4_num_blocks_y;
1426
65.7k
    UWORD32 u4_scaled_block_wd, u4_scaled_block_ht;
1427
65.7k
    UWORD32 u4_blk_wd_luma, u4_blk_ht_luma;
1428
1429
65.7k
    downscaler_ctxt_t *ps_scaler = &ps_codec->s_scaler;
1430
65.7k
    isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
1431
65.7k
    mem_fxns_t *ps_mem_fxns = &ps_isa_dependent_fxns->s_mem_fxns;
1432
1433
65.7k
    const UWORD8 u1_num_yuv_components_420sp = NUM_SP_COMPONENTS;
1434
65.7k
    UWORD8 u1_num_spatial_layers = ps_inp->s_svc_params.u1_num_spatial_layers;
1435
65.7k
    UWORD32 u4_padded_width = ps_inp->as_layer_yuv_buf_props[u1_num_spatial_layers - 1].u4_width;
1436
65.7k
    UWORD32 u4_padded_height = ps_inp->as_layer_yuv_buf_props[u1_num_spatial_layers - 1].u4_height;
1437
65.7k
    UWORD32 u4_raw_input_wd = ps_inp->s_inp_props.s_raw_buf.au4_wd[0];
1438
65.7k
    UWORD32 u4_raw_input_ht = ps_inp->s_inp_props.s_raw_buf.au4_ht[0];
1439
65.7k
    UWORD32 u4_width_delta = u4_padded_width - u4_raw_input_wd;
1440
65.7k
    UWORD32 u4_height_delta = u4_padded_height - u4_raw_input_ht;
1441
1442
65.7k
    ASSERT(!(u4_width_delta & 1));
1443
65.7k
    ASSERT(!(u4_height_delta & 1));
1444
1445
65.7k
    ASSERT((ps_inp->s_inp_props.s_raw_buf.e_color_fmt == IV_YUV_420P) ||
1446
65.7k
           (ps_inp->s_inp_props.s_raw_buf.e_color_fmt == IV_YUV_420SP_UV));
1447
1448
    /* Check is input is valid */
1449
65.7k
    if(!(ps_inp->s_inp_props.s_raw_buf.apv_bufs[0]))
1450
0
    {
1451
0
        ASSERT(0);
1452
1453
0
        return;
1454
0
    }
1455
1456
    /* Convert the input into semi-planar in case of other formats */
1457
65.7k
    if(ps_inp->s_inp_props.s_raw_buf.e_color_fmt == IV_YUV_420P)
1458
55.7k
    {
1459
55.7k
        pu1_planar_y = (UWORD8 *) ps_inp->s_inp_props.s_raw_buf.apv_bufs[0];
1460
55.7k
        pu1_planar_u = (UWORD8 *) ps_inp->s_inp_props.s_raw_buf.apv_bufs[1];
1461
55.7k
        pu1_planar_v = (UWORD8 *) ps_inp->s_inp_props.s_raw_buf.apv_bufs[2];
1462
1463
55.7k
        pu1_semi_planar_y = (UWORD8 *) ps_inp->as_layer_yuv_buf_props[u1_num_spatial_layers - 1]
1464
55.7k
                                .as_component_bufs[0]
1465
55.7k
                                .pv_data;
1466
1467
55.7k
        pu1_semi_planar_uv = (UWORD8 *) ps_inp->as_layer_yuv_buf_props[u1_num_spatial_layers - 1]
1468
55.7k
                                 .as_component_bufs[1]
1469
55.7k
                                 .pv_data;
1470
1471
55.7k
        pu1_semi_planar_y +=
1472
55.7k
            ((u4_width_delta / 2) + (ps_inp->as_layer_yuv_buf_props[u1_num_spatial_layers - 1]
1473
55.7k
                                         .as_component_bufs[0]
1474
55.7k
                                         .i4_data_stride) *
1475
55.7k
                                        (u4_height_delta / 2));
1476
1477
55.7k
        pu1_semi_planar_uv +=
1478
55.7k
            ((u4_width_delta / 2) + (ps_inp->as_layer_yuv_buf_props[u1_num_spatial_layers - 1]
1479
55.7k
                                         .as_component_bufs[1]
1480
55.7k
                                         .i4_data_stride) *
1481
55.7k
                                        (u4_height_delta / 4));
1482
1483
55.7k
        ps_codec->pf_ih264e_conv_420p_to_420sp(
1484
55.7k
            pu1_planar_y, pu1_planar_u, pu1_planar_v, pu1_semi_planar_y, pu1_semi_planar_uv,
1485
55.7k
            ps_inp->s_inp_props.s_raw_buf.au4_ht[0], ps_inp->s_inp_props.s_raw_buf.au4_wd[0],
1486
55.7k
            ps_inp->s_inp_props.s_raw_buf.au4_strd[0], ps_inp->s_inp_props.s_raw_buf.au4_strd[1],
1487
55.7k
            ps_inp->s_inp_props.s_raw_buf.au4_strd[2],
1488
55.7k
            ps_inp->as_layer_yuv_buf_props[u1_num_spatial_layers - 1]
1489
55.7k
                .as_component_bufs[0]
1490
55.7k
                .i4_data_stride,
1491
55.7k
            ps_inp->as_layer_yuv_buf_props[u1_num_spatial_layers - 1]
1492
55.7k
                .as_component_bufs[1]
1493
55.7k
                .i4_data_stride,
1494
55.7k
            0);
1495
55.7k
    }
1496
9.98k
    else
1497
9.98k
    {
1498
9.98k
        UWORD32 u4_wd, u4_ht;
1499
9.98k
        UWORD8 u1_comp;
1500
9.98k
        UWORD32 au4_arr_dims[4];
1501
9.98k
        UWORD8 *pu1_src, *pu1_dst;
1502
1503
9.98k
        au4_arr_dims[0] = ps_inp->s_inp_props.s_raw_buf.au4_wd[0];
1504
9.98k
        au4_arr_dims[1] = ps_inp->s_inp_props.s_raw_buf.au4_ht[0];
1505
9.98k
        au4_arr_dims[2] = ps_inp->s_inp_props.s_raw_buf.au4_wd[1];
1506
9.98k
        au4_arr_dims[3] = ps_inp->s_inp_props.s_raw_buf.au4_ht[1];
1507
1508
29.9k
        for(u1_comp = 0; u1_comp < u1_num_yuv_components_420sp; u1_comp++)
1509
19.9k
        {
1510
19.9k
            u4_wd = au4_arr_dims[u1_comp * 2];
1511
19.9k
            u4_ht = au4_arr_dims[(u1_comp * 2) + 1];
1512
1513
19.9k
            pu1_dst = (UWORD8 *) ps_inp->as_layer_yuv_buf_props[u1_num_spatial_layers - 1]
1514
19.9k
                          .as_component_bufs[u1_comp]
1515
19.9k
                          .pv_data;
1516
1517
19.9k
            pu1_dst +=
1518
19.9k
                ((u4_width_delta / 2) + (ps_inp->as_layer_yuv_buf_props[u1_num_spatial_layers - 1]
1519
19.9k
                                             .as_component_bufs[u1_comp]
1520
19.9k
                                             .i4_data_stride) *
1521
19.9k
                                            ((u4_height_delta / 2) / (u1_comp + 1)));
1522
1523
19.9k
            pu1_src = ps_inp->s_inp_props.s_raw_buf.apv_bufs[u1_comp];
1524
1525
19.9k
            ps_mem_fxns->pf_copy_2d(pu1_dst,
1526
19.9k
                                    ps_inp->as_layer_yuv_buf_props[u1_num_spatial_layers - 1]
1527
19.9k
                                        .as_component_bufs[u1_comp]
1528
19.9k
                                        .i4_data_stride,
1529
19.9k
                                    pu1_src, ps_inp->s_inp_props.s_raw_buf.au4_strd[u1_comp], u4_wd,
1530
19.9k
                                    u4_ht);
1531
19.9k
        }
1532
9.98k
    }
1533
1534
    /* Padding input to satisfy SVC constraints */
1535
65.7k
    isvce_pad_input_to_svc_compliant_dims(ps_codec, ps_inp);
1536
1537
    /* Downscaling */
1538
161k
    for(i = u1_num_spatial_layers - 1; i > 0; i--)
1539
95.3k
    {
1540
95.3k
        const UWORD32 u4_default_scaled_blk_wd =
1541
95.3k
            gu4_downscaler_blk_size / ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio + 0.5;
1542
95.3k
        const UWORD32 u4_default_scaled_blk_ht =
1543
95.3k
            gu4_downscaler_blk_size / ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio + 0.5;
1544
1545
95.3k
        isvce_pad_buf_for_filtering(ps_codec, ps_inp, i);
1546
1547
95.3k
        s_src_buf_props = ps_inp->as_layer_yuv_buf_props[i];
1548
95.3k
        s_dst_buf_props = ps_inp->as_layer_yuv_buf_props[i - 1];
1549
1550
95.3k
        u4_num_blocks_x =
1551
95.3k
            (s_src_buf_props.u4_width + (gu4_downscaler_blk_size - 1)) / gu4_downscaler_blk_size;
1552
1553
95.3k
        u4_num_blocks_y =
1554
95.3k
            (s_src_buf_props.u4_height + (gu4_downscaler_blk_size - 1)) / gu4_downscaler_blk_size;
1555
1556
95.3k
        pu1_src_luma = (UWORD8 *) s_src_buf_props.as_component_bufs[Y].pv_data;
1557
95.3k
        pu1_src_chroma = (UWORD8 *) s_src_buf_props.as_component_bufs[U].pv_data;
1558
95.3k
        pu1_dst_luma = (UWORD8 *) s_dst_buf_props.as_component_bufs[Y].pv_data;
1559
95.3k
        pu1_dst_chroma = (UWORD8 *) s_dst_buf_props.as_component_bufs[U].pv_data;
1560
1561
284k
        for(u4_blk_x = 0; u4_blk_x < u4_num_blocks_x; u4_blk_x++)
1562
188k
        {
1563
695k
            for(u4_blk_y = 0; u4_blk_y < u4_num_blocks_y; u4_blk_y++)
1564
507k
            {
1565
507k
                u4_blk_wd_luma = isvce_get_downscaler_blk_dims(s_src_buf_props.u4_width, u4_blk_x,
1566
507k
                                                               gu4_downscaler_blk_size);
1567
1568
507k
                u4_blk_ht_luma = isvce_get_downscaler_blk_dims(s_src_buf_props.u4_height, u4_blk_y,
1569
507k
                                                               gu4_downscaler_blk_size);
1570
1571
507k
                u4_scaled_block_wd = isvce_get_downscaler_blk_dims(
1572
507k
                    s_dst_buf_props.u4_width, u4_blk_x, u4_default_scaled_blk_wd);
1573
1574
507k
                u4_scaled_block_ht = isvce_get_downscaler_blk_dims(
1575
507k
                    s_dst_buf_props.u4_height, u4_blk_y, u4_default_scaled_blk_ht);
1576
1577
507k
                s_src_buf_props.as_component_bufs[Y].pv_data =
1578
507k
                    pu1_src_luma + (u4_blk_x * gu4_downscaler_blk_size +
1579
507k
                                    u4_blk_y * gu4_downscaler_blk_size *
1580
507k
                                        s_src_buf_props.as_component_bufs[Y].i4_data_stride);
1581
1582
507k
                s_src_buf_props.as_component_bufs[U].pv_data =
1583
507k
                    pu1_src_chroma + (u4_blk_x * gu4_downscaler_blk_size +
1584
507k
                                      u4_blk_y * (gu4_downscaler_blk_size / 2) *
1585
507k
                                          s_src_buf_props.as_component_bufs[U].i4_data_stride);
1586
1587
507k
                s_dst_buf_props.as_component_bufs[Y].pv_data =
1588
507k
                    pu1_dst_luma + (u4_blk_x * u4_default_scaled_blk_wd +
1589
507k
                                    u4_blk_y * u4_default_scaled_blk_ht *
1590
507k
                                        s_dst_buf_props.as_component_bufs[Y].i4_data_stride);
1591
1592
507k
                s_dst_buf_props.as_component_bufs[U].pv_data =
1593
507k
                    pu1_dst_chroma + (u4_blk_x * u4_default_scaled_blk_wd +
1594
507k
                                      u4_blk_y * (u4_default_scaled_blk_ht / 2) *
1595
507k
                                          s_dst_buf_props.as_component_bufs[U].i4_data_stride);
1596
1597
507k
                ASSERT(!(u4_scaled_block_wd & 1));
1598
507k
                ASSERT(!(u4_scaled_block_ht & 1));
1599
1600
507k
                isvce_process_downscaler(ps_scaler, &s_src_buf_props, &s_dst_buf_props,
1601
507k
                                         u4_blk_wd_luma, u4_blk_ht_luma);
1602
507k
            }
1603
188k
        }
1604
95.3k
    }
1605
1606
65.7k
    UNUSED(u4_scaled_block_wd);
1607
65.7k
    UNUSED(u4_scaled_block_ht);
1608
65.7k
}
1609
1610
/**
1611
*******************************************************************************
1612
*
1613
* @brief
1614
*  calculates the greatest common divisor between the two parameters.
1615
*
1616
*******************************************************************************
1617
*/
1618
1619
static DOUBLE isvce_get_GCD(DOUBLE a, DOUBLE b)
1620
22.0k
{
1621
22.0k
    if(b == 0)
1622
5.51k
    {
1623
5.51k
        return a;
1624
5.51k
    }
1625
1626
16.5k
    return isvce_get_GCD(b, fmod(a, b));
1627
22.0k
}
1628
1629
/**
1630
*******************************************************************************
1631
*
1632
* @brief
1633
*  calculates the least common multiple between the two parameters
1634
*
1635
*******************************************************************************
1636
*/
1637
1638
5.51k
static DOUBLE isvce_get_LCM(DOUBLE a, DOUBLE b) { return (a / isvce_get_GCD(a, b)) * b; }
1639
1640
/**
1641
*******************************************************************************
1642
*
1643
* @brief
1644
*  sets the width and height in config structure to SVC compliant width and
1645
*   height
1646
*
1647
* @param[in] ps_cfg
1648
*  Pointer to config struct
1649
*
1650
* @param[in] u4_app_wd
1651
*  width of the YUV as read by the app
1652
*
1653
* @param[in] u4_app_ht
1654
*  height of the YUV as read by the app
1655
*
1656
*******************************************************************************
1657
*/
1658
1659
void isvce_get_svc_compliant_dimensions(UWORD8 u1_num_spatial_layers, DOUBLE d_scaling_factor,
1660
                                        UWORD32 u4_wd, UWORD32 u4_ht, UWORD32 *pu4_svc_comp_wd,
1661
                                        UWORD32 *pu4_svc_comp_ht)
1662
22.7k
{
1663
22.7k
    DOUBLE d_scaling_factor_power_num_layers_minus1 = 0;
1664
22.7k
    UWORD32 u4_constraint_offset = 0;
1665
1666
22.7k
    d_scaling_factor_power_num_layers_minus1 = pow(d_scaling_factor, u1_num_spatial_layers - 1);
1667
1668
22.7k
    if(fmod(16, d_scaling_factor_power_num_layers_minus1))
1669
5.51k
    {
1670
5.51k
        u4_constraint_offset =
1671
5.51k
            (UWORD32) isvce_get_LCM(16, d_scaling_factor_power_num_layers_minus1);
1672
5.51k
    }
1673
17.2k
    else
1674
17.2k
    {
1675
17.2k
        u4_constraint_offset = (UWORD32) (16 * d_scaling_factor_power_num_layers_minus1);
1676
17.2k
    }
1677
1678
22.7k
    if(u4_wd % u4_constraint_offset)
1679
10.1k
    {
1680
10.1k
        *pu4_svc_comp_wd = u4_wd - ((u4_wd) % u4_constraint_offset) + u4_constraint_offset;
1681
10.1k
    }
1682
12.6k
    else
1683
12.6k
    {
1684
12.6k
        *pu4_svc_comp_wd = u4_wd;
1685
12.6k
    }
1686
1687
22.7k
    if(u4_ht % u4_constraint_offset)
1688
11.8k
    {
1689
11.8k
        *pu4_svc_comp_ht = u4_ht - ((u4_ht) % u4_constraint_offset) + u4_constraint_offset;
1690
11.8k
    }
1691
10.9k
    else
1692
10.9k
    {
1693
10.9k
        *pu4_svc_comp_ht = u4_ht;
1694
10.9k
    }
1695
22.7k
}
1696
1697
/**
1698
*******************************************************************************
1699
*
1700
* @brief
1701
*  Returns size of buffers for storing SVC layer nbr info
1702
*
1703
* @param[in] u1_num_spatial_layers
1704
*  Num Spatial Layers
1705
*
1706
* @param[in] d_spatial_res_ratio
1707
*  Resolution Ratio b/w spatial layers
1708
*
1709
* @param[in] u4_wd
1710
*  Input Width
1711
*
1712
* @returns  Size of buffers
1713
*
1714
*******************************************************************************
1715
*/
1716
UWORD32 isvce_get_svc_nbr_info_buf_size(UWORD8 u1_num_spatial_layers, DOUBLE d_spatial_res_ratio,
1717
                                        UWORD32 u4_wd, UWORD32 u4_ht)
1718
14.8k
{
1719
14.8k
    UWORD32 i;
1720
1721
14.8k
    UWORD32 u4_size = 0;
1722
1723
14.8k
    ASSERT(1 == MAX_CTXT_SETS);
1724
1725
14.8k
    u4_size += MAX_PROCESS_CTXT * u1_num_spatial_layers * sizeof(nbr_info_t);
1726
1727
49.0k
    for(i = 0; i < u1_num_spatial_layers; i++)
1728
34.2k
    {
1729
34.2k
        WORD32 i4_layer_luma_wd = ((DOUBLE) u4_wd / pow(d_spatial_res_ratio, i)) + 0.99;
1730
34.2k
        WORD32 i4_layer_luma_ht = ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, i)) + 0.99;
1731
34.2k
        WORD32 i4_num_mbs_in_row = i4_layer_luma_wd / MB_SIZE;
1732
34.2k
        WORD32 i4_num_mbs_in_col = i4_layer_luma_ht / MB_SIZE;
1733
1734
        /* ps_top_row_mb_info */
1735
34.2k
        u4_size += (i4_num_mbs_in_row + 1) * i4_num_mbs_in_col * sizeof(isvce_mb_info_t);
1736
1737
        /* ps_left_mb_info */
1738
34.2k
        u4_size += MAX_PROCESS_CTXT * sizeof(isvce_mb_info_t);
1739
1740
        /* ps_top_mb_intra_modes */
1741
34.2k
        u4_size += (i4_num_mbs_in_row + 1) * i4_num_mbs_in_col * sizeof(mb_intra_modes_t);
1742
1743
        /* ps_left_mb_intra_modes */
1744
34.2k
        u4_size += MAX_PROCESS_CTXT * sizeof(mb_intra_modes_t);
1745
34.2k
    }
1746
1747
14.8k
    return u4_size;
1748
14.8k
}
1749
1750
/**
1751
*******************************************************************************
1752
*
1753
* @brief
1754
*  Function to initialize svc nbr info buffers
1755
*
1756
* @param[in] ps_codec
1757
*  Pointer to codec context
1758
*
1759
* @param[in] ps_mem_rec
1760
*  Pointer to memory allocated for input buffers
1761
*
1762
*******************************************************************************
1763
*/
1764
void isvce_svc_nbr_info_buf_init(isvce_codec_t *ps_codec, iv_mem_rec_t *ps_mem_rec)
1765
4.93k
{
1766
4.93k
    WORD32 i, j;
1767
1768
4.93k
    DOUBLE d_spatial_res_ratio = ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio;
1769
4.93k
    UWORD8 u1_num_spatial_layers = ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers;
1770
4.93k
    UWORD32 u4_wd = ps_codec->s_cfg.u4_wd;
1771
4.93k
    UWORD32 u4_ht = ps_codec->s_cfg.u4_ht;
1772
1773
4.93k
    UWORD8 *pu1_buf = ps_mem_rec->pv_base;
1774
4.93k
    WORD64 i8_alloc_mem_size =
1775
4.93k
        isvce_get_svc_nbr_info_buf_size(u1_num_spatial_layers, d_spatial_res_ratio, u4_wd, u4_ht);
1776
1777
4.93k
    ASSERT(1 == MAX_CTXT_SETS);
1778
1779
44.4k
    for(i = 0; i < MAX_PROCESS_CTXT; i++)
1780
39.4k
    {
1781
39.4k
        ps_codec->as_process[i].s_nbr_info_base.ps_layer_nbr_info = (nbr_info_t *) pu1_buf;
1782
39.4k
        pu1_buf += u1_num_spatial_layers *
1783
39.4k
                   sizeof(ps_codec->as_process[i].s_nbr_info_base.ps_layer_nbr_info[0]);
1784
39.4k
        i8_alloc_mem_size -= u1_num_spatial_layers *
1785
39.4k
                             sizeof(ps_codec->as_process[i].s_nbr_info_base.ps_layer_nbr_info[0]);
1786
1787
130k
        for(j = u1_num_spatial_layers - 1; j >= 0; j--)
1788
91.2k
        {
1789
91.2k
            ps_codec->as_process[i].s_nbr_info_base.ps_layer_nbr_info[j].ps_left_mb_info =
1790
91.2k
                (isvce_mb_info_t *) pu1_buf;
1791
91.2k
            ps_codec->as_process[i].s_nbr_info.ps_left_mb_info = (isvce_mb_info_t *) pu1_buf;
1792
91.2k
            pu1_buf += sizeof(ps_codec->as_process[i].s_nbr_info.ps_left_mb_info[0]);
1793
91.2k
            i8_alloc_mem_size -= sizeof(ps_codec->as_process[i].s_nbr_info.ps_left_mb_info[0]);
1794
1795
91.2k
            ps_codec->as_process[i].s_nbr_info_base.ps_layer_nbr_info[j].ps_left_mb_intra_modes =
1796
91.2k
                (mb_intra_modes_t *) pu1_buf;
1797
91.2k
            ps_codec->as_process[i].s_nbr_info.ps_left_mb_intra_modes =
1798
91.2k
                (mb_intra_modes_t *) pu1_buf;
1799
91.2k
            pu1_buf += sizeof(ps_codec->as_process[i].s_nbr_info.ps_left_mb_intra_modes[0]);
1800
91.2k
            i8_alloc_mem_size -=
1801
91.2k
                sizeof(ps_codec->as_process[i].s_nbr_info.ps_left_mb_intra_modes[0]);
1802
91.2k
        }
1803
1804
39.4k
        ASSERT(i8_alloc_mem_size >= 0);
1805
39.4k
    }
1806
1807
16.3k
    for(i = u1_num_spatial_layers - 1; i >= 0; i--)
1808
11.4k
    {
1809
11.4k
        isvce_mb_info_t *ps_top_mb_info;
1810
11.4k
        mb_intra_modes_t *ps_top_intra_modes;
1811
1812
11.4k
        WORD32 i4_layer_luma_wd =
1813
11.4k
            ((DOUBLE) u4_wd / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) + 0.99;
1814
11.4k
        WORD32 i4_layer_luma_ht =
1815
11.4k
            ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) + 0.99;
1816
11.4k
        WORD32 i4_num_mbs_in_row = i4_layer_luma_wd / MB_SIZE;
1817
11.4k
        WORD32 i4_num_mbs_in_col = i4_layer_luma_ht / MB_SIZE;
1818
1819
11.4k
        ps_top_mb_info = (isvce_mb_info_t *) pu1_buf;
1820
11.4k
        pu1_buf += (i4_num_mbs_in_row + 1) * i4_num_mbs_in_col * sizeof(ps_top_mb_info[0]);
1821
11.4k
        i8_alloc_mem_size -=
1822
11.4k
            (i4_num_mbs_in_row + 1) * i4_num_mbs_in_col * sizeof(ps_top_mb_info[0]);
1823
1824
11.4k
        ps_top_intra_modes = (mb_intra_modes_t *) pu1_buf;
1825
11.4k
        pu1_buf += (i4_num_mbs_in_row + 1) * i4_num_mbs_in_col * sizeof(ps_top_intra_modes[0]);
1826
11.4k
        i8_alloc_mem_size -=
1827
11.4k
            (i4_num_mbs_in_row + 1) * i4_num_mbs_in_col * sizeof(ps_top_intra_modes[0]);
1828
1829
102k
        for(j = 0; j < MAX_PROCESS_CTXT; j++)
1830
91.2k
        {
1831
91.2k
            ps_codec->as_process[j].s_nbr_info_base.ps_layer_nbr_info[i].ps_top_row_mb_info =
1832
91.2k
                ps_top_mb_info;
1833
91.2k
            ps_codec->as_process[j].s_nbr_info.ps_top_row_mb_info = NULL;
1834
1835
91.2k
            ps_codec->as_process[j].s_nbr_info_base.ps_layer_nbr_info[i].ps_top_mb_intra_modes =
1836
91.2k
                ps_top_intra_modes;
1837
91.2k
            ps_codec->as_process[j].s_nbr_info.ps_top_mb_intra_modes = NULL;
1838
91.2k
        }
1839
1840
11.4k
        ASSERT(i8_alloc_mem_size >= 0);
1841
11.4k
    }
1842
4.93k
}
1843
1844
/**
1845
*******************************************************************************
1846
*
1847
* @brief
1848
*  isvce_codec_t and proc_t initialisations for an Access Unit
1849
*
1850
* @par Description:
1851
*  Before beginning to encode the frame, the current function initializes all
1852
*  the ctxts (proc, entropy, me, ...) basing on the input configured params.
1853
*  It locates space for storing recon in the encoder picture buffer set, fetches
1854
*  reference frame from encoder picture buffer set. Calls RC pre-enc to get
1855
*  qp and pic type for the current frame. Queues proc jobs so that
1856
*  the other threads can begin encoding. In brief, this function sets up the
1857
*  tone for the entire encoder.
1858
*
1859
* @param[in] ps_codec
1860
*  Pointer to codec context
1861
*
1862
* @param[in] ps_inp_buf
1863
*  Pointer to input buffer context
1864
*
1865
* @returns  error_status
1866
*
1867
* @remarks
1868
*
1869
*
1870
*******************************************************************************
1871
*/
1872
IH264E_ERROR_T isvce_svc_au_init(isvce_codec_t *ps_codec, isvce_inp_buf_t *ps_inp_buf)
1873
29.5k
{
1874
29.5k
    svc_au_buf_t *ps_cur_pic;
1875
1876
29.5k
    WORD32 cur_mv_bank_buf_id;
1877
29.5k
    WORD32 cur_pic_buf_id;
1878
29.5k
    WORD32 ref_set_id;
1879
29.5k
    WORD32 i, j;
1880
1881
29.5k
    svc_au_data_t *ps_mv_buf = NULL;
1882
29.5k
    svc_au_buf_t *aps_ref_pic[MAX_REF_PIC_CNT] = {NULL, NULL};
1883
29.5k
    svc_au_data_t *aps_mv_buf[MAX_REF_PIC_CNT] = {NULL, NULL};
1884
1885
29.5k
    IH264E_ERROR_T error_status = IH264E_SUCCESS;
1886
29.5k
    PIC_TYPE_T *pic_type = &ps_codec->pic_type;
1887
1888
29.5k
    UWORD32 u4_timestamp_high = ps_inp_buf->s_inp_props.u4_timestamp_high;
1889
29.5k
    UWORD32 u4_timestamp_low = ps_inp_buf->s_inp_props.u4_timestamp_low;
1890
29.5k
    WORD32 ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS;
1891
    /* Diamond search Iteration Max Cnt */
1892
29.5k
    UWORD32 u4_num_layers =
1893
29.5k
        (ps_codec->s_cfg.u4_enc_speed_preset == IVE_FASTEST) ? (NUM_LAYERS >> 2) : NUM_LAYERS;
1894
29.5k
    UWORD32 u4_enable_fast_sad = ps_codec->s_cfg.u4_enable_fast_sad;
1895
1896
29.5k
    if((PIC_I == *pic_type) || (PIC_IDR == *pic_type))
1897
10.4k
    {
1898
10.4k
        ps_codec->i4_slice_type = ISLICE;
1899
10.4k
    }
1900
19.1k
    else if(PIC_P == *pic_type)
1901
19.1k
    {
1902
19.1k
        ps_codec->i4_slice_type = PSLICE;
1903
19.1k
    }
1904
0
    else if(PIC_B == *pic_type)
1905
0
    {
1906
0
        ps_codec->i4_slice_type = BSLICE;
1907
0
    }
1908
1909
29.5k
    ps_codec->u4_is_curr_frm_ref = 0;
1910
29.5k
    ps_codec->u4_is_curr_frm_ref = (*pic_type != PIC_B);
1911
1912
29.5k
    if(ps_codec->s_cfg.u4_enable_alt_ref && (*pic_type == PIC_P) &&
1913
29.5k
       (ps_codec->i4_pic_cnt % (ps_codec->s_cfg.u4_enable_alt_ref + 1)))
1914
0
    {
1915
0
        ps_codec->u4_is_curr_frm_ref = 0;
1916
0
    }
1917
1918
29.5k
    ps_codec->u4_is_idr = 0;
1919
1920
29.5k
    if(PIC_IDR == *pic_type)
1921
8.51k
    {
1922
8.51k
        ps_codec->u4_is_idr = 1;
1923
1924
8.51k
        ps_codec->i4_frame_num = 0;
1925
1926
8.51k
        ps_codec->i4_idr_pic_id++;
1927
8.51k
    }
1928
1929
29.5k
    ps_codec->u4_disable_deblock_level = 1;
1930
1931
29.5k
    if(ps_codec->s_cfg.u4_disable_deblock_level == DISABLE_DEBLK_LEVEL_0)
1932
15.9k
    {
1933
15.9k
        ps_codec->u4_disable_deblock_level = 0;
1934
15.9k
    }
1935
13.5k
    else if(ps_codec->s_cfg.u4_disable_deblock_level == DISABLE_DEBLK_LEVEL_2)
1936
5.37k
    {
1937
5.37k
        if(ps_codec->u4_disable_deblock_level_cnt == DISABLE_DEBLOCK_INTERVAL ||
1938
5.37k
           ps_codec->i4_slice_type == ISLICE)
1939
2.08k
        {
1940
2.08k
            ps_codec->u4_disable_deblock_level = 0;
1941
2.08k
        }
1942
5.37k
    }
1943
8.22k
    else if(ps_codec->s_cfg.u4_disable_deblock_level == DISABLE_DEBLK_LEVEL_3)
1944
2.90k
    {
1945
2.90k
        if(ps_codec->i4_slice_type == ISLICE)
1946
1.30k
        {
1947
1.30k
            ps_codec->u4_disable_deblock_level = 0;
1948
1.30k
        }
1949
2.90k
    }
1950
1951
29.5k
    if(ps_codec->u4_disable_deblock_level)
1952
10.2k
    {
1953
10.2k
        ps_codec->u4_disable_deblock_level_cnt++;
1954
10.2k
    }
1955
19.3k
    else
1956
19.3k
    {
1957
19.3k
        ps_codec->u4_disable_deblock_level_cnt = 0;
1958
19.3k
    }
1959
1960
29.5k
    if(ps_codec->u4_disable_deblock_level == 0)
1961
19.3k
    {
1962
19.3k
        if(ps_codec->s_cfg.e_slice_mode != IVE_SLICE_MODE_NONE)
1963
0
        {
1964
0
            ps_codec->i4_error_code = IH264E_SLICE_TYPE_INPUT_INVALID;
1965
1966
0
            return IH264E_SLICE_TYPE_INPUT_INVALID;
1967
0
        }
1968
19.3k
    }
1969
1970
29.5k
    ps_codec->i4_error_code = IH264E_SUCCESS;
1971
1972
29.5k
    if(ps_codec->i4_gen_header)
1973
0
    {
1974
0
        sps_t *ps_sps = NULL;
1975
0
        pps_t *ps_pps = NULL;
1976
0
        subset_sps_t *ps_subset_sps = NULL;
1977
0
        UWORD8 u1_profile_idc = IH264_PROFILE_BASELINE;
1978
1979
0
        if(ps_codec->as_process[ctxt_sel * MAX_PROCESS_THREADS].u1_spatial_layer_id > 0)
1980
0
        {
1981
0
            u1_profile_idc = IH264_SCALABLE_BASELINE;
1982
0
        }
1983
1984
0
        ps_sps = ps_codec->ps_sps_base;
1985
0
        isvce_populate_sps(ps_codec, ps_sps, 0, u1_profile_idc, ps_inp_buf, 0);
1986
1987
0
        ps_pps = ps_codec->ps_pps_base;
1988
0
        isvce_populate_pps(ps_codec, ps_pps, 0, 0, 0);
1989
1990
0
        for(i = 1; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers; i++)
1991
0
        {
1992
0
            ps_subset_sps = ps_codec->ps_subset_sps_base + i;
1993
0
            isvce_populate_subset_sps(ps_codec, ps_subset_sps, i, ps_inp_buf, i);
1994
1995
            /* populate pps header */
1996
0
            ps_pps = ps_codec->ps_pps_base + i;
1997
0
            isvce_populate_pps(ps_codec, ps_pps, i, i, i);
1998
0
        }
1999
0
    }
2000
2001
29.5k
    if(IH264E_SUCCESS !=
2002
29.5k
       isvce_ref_list_refresh(ps_codec, aps_ref_pic, aps_mv_buf, &ref_set_id, pic_type[0]))
2003
1.30k
    {
2004
1.30k
        ps_codec->i4_error_code = IH264E_NO_FREE_PICBUF;
2005
2006
1.30k
        return IH264E_NO_FREE_PICBUF;
2007
1.30k
    }
2008
2009
28.2k
    {
2010
28.2k
        ps_mv_buf = (svc_au_data_t *) ih264_buf_mgr_get_next_free(
2011
28.2k
            (buf_mgr_t *) ps_codec->pv_svc_au_data_store_mgr, &cur_mv_bank_buf_id);
2012
2013
28.2k
        if(NULL == ps_mv_buf)
2014
99
        {
2015
99
            ps_codec->i4_error_code = IH264E_NO_FREE_MVBANK;
2016
2017
99
            return IH264E_NO_FREE_MVBANK;
2018
99
        }
2019
2020
28.1k
        if(ps_codec->u4_is_curr_frm_ref)
2021
28.1k
        {
2022
28.1k
            ih264_buf_mgr_set_status(ps_codec->pv_svc_au_data_store_mgr, cur_mv_bank_buf_id,
2023
28.1k
                                     BUF_MGR_REF);
2024
28.1k
        }
2025
2026
28.1k
        ps_mv_buf->i4_abs_poc = ps_codec->i4_abs_pic_order_cnt;
2027
28.1k
        ps_mv_buf->i4_buf_id = cur_mv_bank_buf_id;
2028
28.1k
    }
2029
2030
0
    {
2031
28.1k
        ps_cur_pic = (svc_au_buf_t *) ih264_buf_mgr_get_next_free(
2032
28.1k
            (buf_mgr_t *) ps_codec->pv_ref_buf_mgr, &cur_pic_buf_id);
2033
2034
28.1k
        if(NULL == ps_cur_pic)
2035
1
        {
2036
1
            ps_codec->i4_error_code = IH264E_NO_FREE_PICBUF;
2037
2038
1
            return IH264E_NO_FREE_PICBUF;
2039
1
        }
2040
2041
28.1k
        if(ps_codec->u4_is_curr_frm_ref)
2042
28.1k
        {
2043
28.1k
            ih264_buf_mgr_set_status(ps_codec->pv_ref_buf_mgr, cur_pic_buf_id, BUF_MGR_REF);
2044
28.1k
        }
2045
2046
28.1k
        if(1 == ps_codec->s_cfg.u4_enable_recon)
2047
5.03k
        {
2048
5.03k
            ih264_buf_mgr_set_status(ps_codec->pv_ref_buf_mgr, cur_pic_buf_id, BUF_MGR_IO);
2049
5.03k
        }
2050
2051
28.1k
        ps_cur_pic->u4_timestamp_high = ps_inp_buf->s_inp_props.u4_timestamp_high;
2052
28.1k
        ps_cur_pic->u4_timestamp_low = ps_inp_buf->s_inp_props.u4_timestamp_low;
2053
2054
28.1k
        ps_cur_pic->i4_abs_poc = ps_codec->i4_poc;
2055
28.1k
        ps_cur_pic->i4_poc_lsb = ps_codec->i4_pic_order_cnt_lsb;
2056
28.1k
        ps_cur_pic->i4_frame_num = ps_codec->i4_frame_num;
2057
2058
28.1k
        ps_cur_pic->i4_buf_id = cur_pic_buf_id;
2059
2060
28.1k
        ps_cur_pic->i1_temporal_id = isvce_svc_temporal_id_compute(
2061
28.1k
            ps_codec->i4_poc, ps_codec->s_cfg.s_svc_params.u1_num_temporal_layers, pic_type[0]);
2062
28.1k
    }
2063
2064
    /*
2065
     * Add the current picture to ref list independent of the fact that it is used
2066
     * as reference or not. This is because, now recon is not in sync with output
2067
     * hence we may need the current recon after some delay. By adding it to ref
2068
     * list we can retrieve the recon any time we want. The information that it is
2069
     * used for ref can still be found by checking the buffer status of pic buf.
2070
     */
2071
0
    ps_codec->as_ref_set[ref_set_id].i4_pic_cnt = ps_codec->i4_pic_cnt;
2072
28.1k
    ps_codec->as_ref_set[ref_set_id].i4_poc = ps_codec->i4_poc;
2073
28.1k
    ps_codec->as_ref_set[ref_set_id].ps_svc_au_data = ps_mv_buf;
2074
28.1k
    ps_codec->as_ref_set[ref_set_id].ps_pic_buf = ps_cur_pic;
2075
2076
28.1k
    ps_codec->s_svc_ilp_data.ps_svc_au_data = ps_mv_buf;
2077
2078
28.1k
    {
2079
28.1k
        isvce_process_ctxt_t *ps_proc = NULL;
2080
2081
28.1k
        j = ctxt_sel * MAX_PROCESS_THREADS;
2082
2083
253k
        for(i = j; i < (j + MAX_PROCESS_THREADS); i++)
2084
225k
        {
2085
225k
            ps_proc = &ps_codec->as_process[i];
2086
2087
225k
            ps_proc->s_svc_params = ps_codec->s_cfg.s_svc_params;
2088
2089
225k
            ps_proc->i4_frame_num = ps_codec->i4_frame_num;
2090
225k
            ps_proc->u4_is_idr = ps_codec->u4_is_idr;
2091
225k
            ps_proc->u4_idr_pic_id = ps_codec->i4_idr_pic_id;
2092
225k
            ps_proc->i4_slice_type = ps_codec->i4_slice_type;
2093
2094
225k
            ps_proc->u4_half_x_offset = 0;
2095
225k
            ps_proc->u4_half_y_offset = 0;
2096
225k
            ps_proc->u4_half_xy_offset = 0;
2097
2098
225k
            ps_proc->u4_disable_deblock_level = ps_codec->u4_disable_deblock_level;
2099
2100
225k
            ps_proc->i4_cur_mv_bank_buf_id = cur_mv_bank_buf_id;
2101
225k
            ps_proc->ps_cur_pic = ps_cur_pic;
2102
225k
            ps_proc->ps_cur_mv_buf = ps_mv_buf;
2103
2104
            /*
2105
             * pointer to ref picture
2106
             * 0    : Temporal back reference
2107
             * 1    : Temporal forward reference
2108
             */
2109
225k
            ps_proc->aps_ref_pic[L0] = aps_ref_pic[L0];
2110
225k
            ps_proc->aps_ref_pic[L1] = aps_ref_pic[L1];
2111
225k
            if(ps_codec->pic_type == PIC_B)
2112
0
            {
2113
0
                ps_proc->aps_mv_buf[L0] = aps_mv_buf[L0];
2114
0
                ps_proc->aps_mv_buf[L1] = aps_mv_buf[L1];
2115
0
            }
2116
225k
            else
2117
225k
            {
2118
                /*
2119
                 * Else is dummy since for non B pic we does not need this
2120
                 * But an assignment here will help in not having a segfault
2121
                 * when we calcualte colpic in P slices
2122
                 */
2123
225k
                ps_proc->aps_mv_buf[L0] = ps_mv_buf;
2124
225k
                ps_proc->aps_mv_buf[L1] = ps_mv_buf;
2125
225k
            }
2126
2127
225k
            ps_proc->s_inp_buf = ps_inp_buf[0];
2128
2129
225k
            ps_proc->i4_encode_api_call_cnt = ps_codec->i4_encode_api_call_cnt;
2130
2131
225k
            ps_proc->i4_pic_cnt = ps_codec->i4_pic_cnt;
2132
2133
225k
            ps_proc->i4_error_code = 0;
2134
2135
225k
            {
2136
225k
                isvce_entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
2137
2138
225k
                ps_entropy->i4_sof = 0;
2139
225k
                ps_entropy->i4_eof = 0;
2140
225k
                ps_entropy->ps_sps_base = ps_codec->ps_sps_base;
2141
225k
                ps_entropy->ps_pps_base = ps_codec->ps_pps_base;
2142
225k
                ps_entropy->pu1_slice_idx = ps_proc->pu1_slice_idx;
2143
225k
                ps_entropy->ps_svc_nalu_ext_base = ps_proc->ps_svc_nalu_ext_base;
2144
225k
                ps_entropy->ps_subset_sps_base = ps_proc->ps_subset_sps_base;
2145
225k
                ps_entropy->ps_slice_hdr_base = ps_proc->ps_slice_hdr_base;
2146
225k
                ps_entropy->ps_svc_slice_hdr_base = ps_proc->ps_svc_slice_hdr_base;
2147
225k
                ps_entropy->i4_abs_pic_order_cnt = ps_codec->i4_poc;
2148
2149
225k
                ps_entropy->i1_transform_8x8_mode_flag = 0;
2150
2151
225k
                ps_entropy->i4_error_code = IH264E_SUCCESS;
2152
225k
                ps_proc->s_entropy.u4_is_last = ps_inp_buf->s_inp_props.u4_is_last;
2153
225k
                ps_proc->s_entropy.i4_pic_cnt = ps_codec->i4_pic_cnt;
2154
2155
225k
                ps_entropy->u4_timestamp_low = u4_timestamp_low;
2156
225k
                ps_entropy->u4_timestamp_high = u4_timestamp_high;
2157
225k
            }
2158
2159
225k
            {
2160
225k
                isvce_me_ctxt_t *ps_me_ctxt = &ps_proc->s_me_ctxt;
2161
2162
225k
                ps_me_ctxt->ai2_srch_boundaries[0] = ps_codec->s_cfg.u4_srch_rng_x;
2163
225k
                ps_me_ctxt->ai2_srch_boundaries[1] = ps_codec->s_cfg.u4_srch_rng_y;
2164
2165
225k
                ps_me_ctxt->u4_half_x_offset = ps_proc->u4_half_x_offset;
2166
225k
                ps_me_ctxt->u4_half_y_offset = ps_proc->u4_half_y_offset;
2167
225k
                ps_me_ctxt->u4_half_xy_offset = ps_proc->u4_half_xy_offset;
2168
2169
225k
                ps_me_ctxt->u4_enable_fast_sad = u4_enable_fast_sad;
2170
225k
                ps_me_ctxt->u4_enable_hpel = ps_codec->s_cfg.u4_enable_hpel;
2171
225k
                ps_me_ctxt->u4_num_layers = u4_num_layers;
2172
225k
                ps_me_ctxt->u4_me_speed_preset = ps_codec->s_cfg.u4_me_speed_preset;
2173
2174
225k
                if((i == j) && (0 == ps_codec->i4_poc))
2175
4.95k
                {
2176
4.95k
                    isvce_init_mv_bits(ps_me_ctxt);
2177
4.95k
                }
2178
225k
            }
2179
2180
225k
            ps_proc->ps_ngbr_avbl = &(ps_proc->s_ngbr_avbl);
2181
225k
        }
2182
28.1k
    }
2183
2184
28.1k
    return error_status;
2185
28.1k
}
2186
2187
void isvce_init_quant_params(isvce_process_ctxt_t *ps_proc, WORD32 qp)
2188
853k
{
2189
853k
    isvce_codec_t *ps_codec = ps_proc->ps_codec;
2190
    /* quant params */
2191
853k
    quant_params_t *ps_qp_params;
2192
2193
    /* ptr to forward quant threshold matrix */
2194
853k
    const UWORD16 *pu2_thres_mat = NULL;
2195
2196
    /* ptr to forward scale matrix */
2197
853k
    const UWORD16 *pu2_scale_mat = gu2_quant_scale_matrix_4x4;
2198
2199
    /* ptr to inverse scale matrix */
2200
853k
    const UWORD16 *pu2_iscale_mat = gau2_ih264_iquant_scale_matrix_4x4;
2201
2202
    /* temp var */
2203
853k
    UWORD32 u4_qp[3], u4_qp_div6, u4_qp_mod6;
2204
853k
    COMPONENT_TYPE plane;
2205
853k
    WORD32 i;
2206
853k
    UWORD32 u4_satdq_t;
2207
853k
    const UWORD16 *pu2_smat;
2208
2209
    /********************************************************************/
2210
    /* init quant params for all planes Y, U and V                      */
2211
    /********************************************************************/
2212
    /* luma qp */
2213
853k
    u4_qp[Y] = qp;
2214
2215
    /* chroma qp
2216
     * TODO_LATER : just in case if the chroma planes use different qp's this
2217
     * needs to be corrected accordingly.
2218
     */
2219
853k
    u4_qp[U] = gu1_qpc_fqpi[qp];
2220
853k
    u4_qp[V] = gu1_qpc_fqpi[qp];
2221
2222
853k
    plane = Y;
2223
3.40M
    while(plane <= V)
2224
2.55M
    {
2225
2.55M
        u4_qp_div6 = (u4_qp[plane] / 6);
2226
2.55M
        u4_qp_mod6 = (u4_qp[plane] % 6);
2227
2228
2.55M
        ps_qp_params = ps_proc->ps_qp_params[plane];
2229
2230
        /* mb qp */
2231
2.55M
        ps_qp_params->u1_mb_qp = u4_qp[plane];
2232
2233
        /* mb qp / 6 */
2234
2.55M
        ps_qp_params->u1_qp_div = u4_qp_div6;
2235
2236
        /* mb qp % 6 */
2237
2.55M
        ps_qp_params->u1_qp_rem = u4_qp_mod6;
2238
2239
        /* QP bits */
2240
2.55M
        ps_qp_params->u1_qbits = QP_BITS_h264_4x4 + u4_qp_div6;
2241
2242
        /* forward scale matrix */
2243
2.55M
        ps_qp_params->pu2_scale_mat = pu2_scale_mat + (u4_qp_mod6 * 16);
2244
2245
        /* threshold matrix & weight for quantization */
2246
2.55M
        pu2_thres_mat = gu2_forward_quant_threshold_4x4 + (u4_qp_mod6 * 16);
2247
43.3M
        for(i = 0; i < 16; i++)
2248
40.7M
        {
2249
40.7M
            ps_qp_params->pu2_thres_mat[i] = pu2_thres_mat[i] >> (8 - u4_qp_div6);
2250
40.7M
            ps_qp_params->pu2_weigh_mat[i] = 16;
2251
40.7M
        }
2252
2253
        /* qp dependent rounding constant */
2254
2.55M
        ps_qp_params->u4_dead_zone = gu4_forward_quant_round_factor_4x4[u4_qp_div6];
2255
2256
        /* slice dependent rounding constant */
2257
2.55M
        if(ps_proc->i4_slice_type != ISLICE && ps_proc->i4_slice_type != SISLICE)
2258
1.19M
        {
2259
1.19M
            ps_qp_params->u4_dead_zone >>= 1;
2260
1.19M
        }
2261
2262
        /* SATQD threshold for zero block prediction */
2263
2.55M
        if(ps_codec->s_cfg.u4_enable_satqd)
2264
2.55M
        {
2265
2.55M
            pu2_smat = ps_qp_params->pu2_scale_mat;
2266
2267
2.55M
            u4_satdq_t = ((1 << (ps_qp_params->u1_qbits)) - ps_qp_params->u4_dead_zone);
2268
2269
2.55M
            ps_qp_params->pu2_sad_thrsh[0] = u4_satdq_t / MAX(pu2_smat[3], pu2_smat[11]);
2270
2.55M
            ps_qp_params->pu2_sad_thrsh[1] = u4_satdq_t / MAX(pu2_smat[1], pu2_smat[9]);
2271
2.55M
            ps_qp_params->pu2_sad_thrsh[2] = u4_satdq_t / pu2_smat[15];
2272
2.55M
            ps_qp_params->pu2_sad_thrsh[3] = u4_satdq_t / pu2_smat[7];
2273
2.55M
            ps_qp_params->pu2_sad_thrsh[4] = u4_satdq_t / MAX(pu2_smat[12], pu2_smat[14]);
2274
2.55M
            ps_qp_params->pu2_sad_thrsh[5] = u4_satdq_t / MAX(pu2_smat[4], pu2_smat[6]);
2275
2.55M
            ps_qp_params->pu2_sad_thrsh[6] = u4_satdq_t / pu2_smat[13];
2276
2.55M
            ps_qp_params->pu2_sad_thrsh[7] = u4_satdq_t / pu2_smat[5];
2277
2.55M
            ps_qp_params->pu2_sad_thrsh[8] =
2278
2.55M
                u4_satdq_t / MAX(MAX3(pu2_smat[0], pu2_smat[2], pu2_smat[8]), pu2_smat[10]);
2279
2.55M
        }
2280
2281
        /* inverse scale matrix */
2282
2.55M
        ps_qp_params->pu2_iscale_mat = pu2_iscale_mat + (u4_qp_mod6 * 16);
2283
2284
2.55M
        plane += 1;
2285
2.55M
    }
2286
853k
}
2287
2288
/**
2289
*******************************************************************************
2290
*
2291
* @brief
2292
*  isvce_codec_t and proc_t initialisations for an Access Unit
2293
*
2294
* @par Description:
2295
*  Before beginning to encode the frame, the current function initializes all
2296
*  the ctxts (proc, entropy, me, ...) basing on the input configured params.
2297
*  It locates space for storing recon in the encoder picture buffer set, fetches
2298
*  reference frame from encoder picture buffer set. Calls RC pre-enc to get
2299
*  qp and pic type for the current frame. Queues proc jobs so that
2300
*  the other threads can begin encoding. In brief, this function sets up the
2301
*  tone for the entire encoder.
2302
*
2303
* @param[in] ps_codec
2304
*  Pointer to codec context
2305
*
2306
* @param[in] ps_inp_buf
2307
*  Pointer to input buffer context
2308
*
2309
* @param[in] u1_spatial_layer_id
2310
*  Spatial Layer IDl 0 => Base layer
2311
*
2312
* @returns  error_status
2313
*
2314
* @remarks
2315
*
2316
*
2317
*******************************************************************************
2318
*/
2319
IH264E_ERROR_T isvce_svc_layer_pic_init(isvce_codec_t *ps_codec, isvce_inp_buf_t *ps_inp_buf,
2320
                                        UWORD8 u1_spatial_layer_id)
2321
61.1k
{
2322
61.1k
    WORD32 i;
2323
2324
61.1k
    IH264E_ERROR_T error_status = IH264E_SUCCESS;
2325
61.1k
    IH264_ERROR_T ret = IH264_SUCCESS;
2326
61.1k
    PIC_TYPE_T e_pic_type = ps_codec->pic_type;
2327
2328
61.1k
    ASSERT(MAX_CTXT_SETS == 1);
2329
2330
550k
    for(i = 0; i < MAX_PROCESS_THREADS; i++)
2331
489k
    {
2332
489k
        isvce_process_ctxt_t *ps_proc = &ps_codec->as_process[i];
2333
489k
        isvce_entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
2334
489k
        isvce_deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
2335
489k
        isvce_me_ctxt_t *ps_me_ctxt = &ps_proc->s_me_ctxt;
2336
489k
        svc_au_buf_t *ps_cur_pic = ps_proc->ps_cur_pic;
2337
489k
        svc_au_buf_t *aps_ref_pic[MAX_REF_PIC_CNT] = {ps_proc->aps_ref_pic[L0],
2338
489k
                                                      ps_proc->aps_ref_pic[L1]};
2339
2340
489k
        ps_proc->u1_spatial_layer_id = u1_spatial_layer_id;
2341
2342
489k
        ps_proc->s_src_pic_buf_props = ps_inp_buf->as_layer_yuv_buf_props[u1_spatial_layer_id];
2343
2344
489k
        ps_proc->s_rec_pic_buf_props = ps_cur_pic->ps_layer_yuv_buf_props[u1_spatial_layer_id];
2345
2346
489k
        ASSERT(0 == (ps_inp_buf->as_layer_yuv_buf_props[u1_spatial_layer_id].u4_width % MB_SIZE));
2347
489k
        ASSERT(0 == (ps_inp_buf->as_layer_yuv_buf_props[u1_spatial_layer_id].u4_height % MB_SIZE));
2348
2349
489k
        ps_proc->i4_wd_mbs =
2350
489k
            ps_inp_buf->as_layer_yuv_buf_props[u1_spatial_layer_id].u4_width / MB_SIZE;
2351
489k
        ps_proc->i4_ht_mbs =
2352
489k
            ps_inp_buf->as_layer_yuv_buf_props[u1_spatial_layer_id].u4_height / MB_SIZE;
2353
2354
489k
        ps_proc->u1_frame_qp = ps_codec->au4_frame_qp[u1_spatial_layer_id];
2355
2356
489k
        ps_proc->u1_mb_qp = ps_proc->u1_frame_qp;
2357
489k
        ps_entropy->ps_mb_qp_ctxt->u1_cur_mb_qp = ps_proc->u1_frame_qp;
2358
2359
489k
        isvce_init_quant_params(ps_proc, ps_proc->u1_frame_qp);
2360
2361
489k
        memset(&ps_proc->s_frame_info, 0, sizeof(frame_info_t));
2362
2363
        /* row '-1' */
2364
489k
        memset(ps_proc->pu1_proc_map - ps_proc->i4_wd_mbs, 1,
2365
489k
               ps_proc->i4_wd_mbs * sizeof(ps_proc->pu1_proc_map[0]));
2366
2367
        /* row 0 to ht in mbs */
2368
489k
        memset(ps_proc->pu1_proc_map, 0,
2369
489k
               ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs * sizeof(ps_proc->pu1_proc_map[0]));
2370
2371
        /* row '-1' */
2372
489k
        memset(ps_proc->pu1_deblk_map - ps_proc->i4_wd_mbs, 1,
2373
489k
               ps_proc->i4_wd_mbs * sizeof(ps_proc->pu1_deblk_map[0]));
2374
2375
        /* row 0 to ht in mbs */
2376
489k
        memset(ps_proc->pu1_deblk_map, 0,
2377
489k
               ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs * sizeof(ps_proc->pu1_deblk_map[0]));
2378
2379
        /* row '-1' */
2380
489k
        memset(ps_proc->pu1_me_map - ps_proc->i4_wd_mbs, 1,
2381
489k
               ps_proc->i4_wd_mbs * sizeof(ps_proc->pu1_me_map[0]));
2382
2383
        /* row 0 to ht in mbs */
2384
489k
        memset(ps_proc->pu1_me_map, 0,
2385
489k
               ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs * sizeof(ps_proc->pu1_me_map[0]));
2386
2387
489k
        if(IVE_AIR_MODE_NONE != ps_codec->s_cfg.e_air_mode)
2388
0
        {
2389
0
            ps_codec->i4_air_pic_cnt =
2390
0
                (ps_codec->i4_air_pic_cnt + 1) % ps_codec->s_cfg.u4_air_refresh_period;
2391
2392
0
            if(!ps_codec->i4_air_pic_cnt)
2393
0
            {
2394
0
                memset(ps_proc->pu1_is_intra_coded, 0,
2395
0
                       ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs *
2396
0
                           sizeof(ps_proc->pu1_is_intra_coded[0]));
2397
0
            }
2398
0
        }
2399
2400
489k
        if(ps_codec->s_cfg.e_slice_mode == IVE_SLICE_MODE_NONE)
2401
489k
        {
2402
489k
            memset(ps_proc->pu1_slice_idx, 0,
2403
489k
                   ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs * sizeof(ps_proc->pu1_slice_idx[0]));
2404
489k
        }
2405
0
        else if(ps_codec->s_cfg.e_slice_mode == IVE_SLICE_MODE_BLOCKS)
2406
0
        {
2407
0
            UWORD8 *pu1_slice_idx = ps_proc->pu1_slice_idx;
2408
0
            WORD32 i4_mb_y = 0, slice_idx = 0, cnt;
2409
2410
0
            while(i4_mb_y < ps_proc->i4_ht_mbs)
2411
0
            {
2412
0
                if(i4_mb_y + (WORD32) ps_codec->s_cfg.u4_slice_param < ps_proc->i4_ht_mbs)
2413
0
                {
2414
0
                    cnt = ps_codec->s_cfg.u4_slice_param * ps_proc->i4_wd_mbs;
2415
0
                    i4_mb_y += ps_codec->s_cfg.u4_slice_param;
2416
0
                }
2417
0
                else
2418
0
                {
2419
0
                    cnt = (ps_proc->i4_ht_mbs - i4_mb_y) * ps_proc->i4_wd_mbs;
2420
0
                    i4_mb_y += (ps_proc->i4_ht_mbs - i4_mb_y);
2421
0
                }
2422
2423
0
                memset(pu1_slice_idx, slice_idx, cnt * sizeof(pu1_slice_idx[0]));
2424
2425
0
                slice_idx++;
2426
0
                pu1_slice_idx += cnt;
2427
0
            }
2428
0
        }
2429
2430
489k
        if((e_pic_type != PIC_IDR) && (e_pic_type != PIC_I))
2431
322k
        {
2432
322k
            ps_proc->as_ref_pic_buf_props[L0] =
2433
322k
                aps_ref_pic[L0]->ps_layer_yuv_buf_props[u1_spatial_layer_id];
2434
322k
            ps_proc->as_ref_pic_buf_props[L1] =
2435
322k
                aps_ref_pic[L1]->ps_layer_yuv_buf_props[u1_spatial_layer_id];
2436
322k
        }
2437
2438
489k
        ps_entropy->i4_gen_header = ps_codec->i4_gen_header && (0 == u1_spatial_layer_id);
2439
489k
        ps_entropy->i4_gen_subset_sps =
2440
489k
            (ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers > 1) && ps_codec->i4_gen_header;
2441
2442
        /* row '-1' */
2443
489k
        memset(ps_entropy->pu1_entropy_map - ps_proc->i4_wd_mbs, 1,
2444
489k
               ps_proc->i4_wd_mbs * sizeof(ps_entropy->pu1_entropy_map[0]));
2445
2446
        /* row 0 to ht in mbs */
2447
489k
        memset(ps_entropy->pu1_entropy_map, 0,
2448
489k
               ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs * sizeof(ps_entropy->pu1_entropy_map[0]));
2449
2450
489k
        isvce_init_cabac_table(ps_entropy);
2451
2452
489k
        ps_entropy->i4_wd_mbs = ps_proc->i4_wd_mbs;
2453
489k
        ps_entropy->i4_ht_mbs = ps_proc->i4_ht_mbs;
2454
2455
489k
        ps_entropy->u1_entropy_coding_mode_flag =
2456
489k
            ((ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers > 1) && (0 == u1_spatial_layer_id))
2457
489k
                ? CAVLC
2458
489k
                : ps_codec->s_cfg.u4_entropy_coding_mode;
2459
2460
489k
        ps_proc->s_entropy.pi4_mb_skip_run[0] = 0;
2461
2462
489k
        ps_entropy->u4_header_bits[MB_TYPE_INTRA] = 0;
2463
489k
        ps_entropy->u4_header_bits[MB_TYPE_INTER] = 0;
2464
489k
        ps_entropy->u4_residue_bits[MB_TYPE_INTRA] = 0;
2465
489k
        ps_entropy->u4_residue_bits[MB_TYPE_INTER] = 0;
2466
2467
489k
        ps_entropy->u1_spatial_layer_id = ps_proc->u1_spatial_layer_id;
2468
2469
489k
        ps_deblk->pu1_slice_idx = ps_proc->pu1_slice_idx;
2470
2471
489k
        ps_me_ctxt->u1_mb_qp = ps_codec->au4_frame_qp[u1_spatial_layer_id];
2472
2473
489k
        {
2474
489k
            UWORD8 u1_min_qp;
2475
489k
            UWORD8 u1_max_qp;
2476
2477
489k
            svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt = ps_proc->ps_sub_pic_rc_ctxt;
2478
489k
            svc_sub_pic_rc_layer_variables_t *ps_layer_variables =
2479
489k
                &ps_sub_pic_rc_ctxt->s_sub_pic_rc_variables.s_layer_variables;
2480
2481
489k
            switch(ps_proc->i4_slice_type)
2482
489k
            {
2483
166k
                case ISLICE:
2484
166k
                {
2485
166k
                    u1_min_qp = ps_codec->s_cfg.au4_i_qp_min[u1_spatial_layer_id];
2486
166k
                    u1_max_qp = ps_codec->s_cfg.au4_i_qp_max[u1_spatial_layer_id];
2487
2488
166k
                    break;
2489
0
                }
2490
322k
                case PSLICE:
2491
322k
                {
2492
322k
                    u1_min_qp = ps_codec->s_cfg.au4_p_qp_min[u1_spatial_layer_id];
2493
322k
                    u1_max_qp = ps_codec->s_cfg.au4_p_qp_max[u1_spatial_layer_id];
2494
2495
322k
                    break;
2496
0
                }
2497
0
                default:
2498
0
                {
2499
0
                    u1_min_qp = ps_codec->s_cfg.au4_b_qp_min[u1_spatial_layer_id];
2500
0
                    u1_max_qp = ps_codec->s_cfg.au4_b_qp_max[u1_spatial_layer_id];
2501
2502
0
                    break;
2503
0
                }
2504
489k
            }
2505
2506
489k
            ps_layer_variables->i4_max_num_reference_frames = ps_codec->i4_max_num_reference_frames;
2507
489k
            ps_layer_variables->i4_slice_type = ps_proc->i4_slice_type;
2508
489k
            ps_layer_variables->i4_frame_num = ps_proc->i4_frame_num;
2509
489k
            ps_layer_variables->u1_frame_qp = ps_proc->u1_frame_qp;
2510
489k
            ps_layer_variables->u1_spatial_layer_id = u1_spatial_layer_id;
2511
489k
            ps_layer_variables->u1_min_qp = u1_min_qp;
2512
489k
            ps_layer_variables->u1_max_qp = u1_max_qp;
2513
2514
489k
            isvce_sub_pic_rc_ctxt_layer_init(ps_proc->ps_sub_pic_rc_ctxt);
2515
489k
        }
2516
489k
    }
2517
2518
61.1k
    {
2519
61.1k
        job_t s_job;
2520
2521
61.1k
        s_job.i4_cmd = CMD_PROCESS;
2522
61.1k
        s_job.i2_mb_cnt =
2523
61.1k
            ps_inp_buf->as_layer_yuv_buf_props[u1_spatial_layer_id].u4_width / MB_SIZE;
2524
61.1k
        s_job.i2_mb_x = 0;
2525
2526
343k
        for(i = 0; i < (WORD32) (ps_inp_buf->as_layer_yuv_buf_props[u1_spatial_layer_id].u4_height /
2527
343k
                                 MB_SIZE);
2528
282k
            i++)
2529
282k
        {
2530
282k
            s_job.i2_mb_y = i;
2531
2532
282k
            ret = ih264_list_queue(ps_codec->pv_proc_jobq, &s_job, 1);
2533
2534
282k
            if(ret != IH264_SUCCESS)
2535
0
            {
2536
0
                ps_codec->i4_error_code = ret;
2537
2538
0
                return IH264E_FAIL;
2539
0
            }
2540
282k
        }
2541
2542
        /* Once all the jobs are queued, terminate the queue */
2543
        /* Since the threads are created and deleted in each call, terminating
2544
        here is not an issue */
2545
61.1k
        ih264_list_terminate(ps_codec->pv_proc_jobq);
2546
61.1k
    }
2547
2548
0
    ps_codec->i4_gen_header = 0;
2549
2550
61.1k
    return error_status;
2551
61.1k
}
2552
2553
/**
2554
*******************************************************************************
2555
*
2556
* @brief   initialize process context.
2557
*
2558
* @par Description:
2559
*  Before dispatching the current job to process thread, the process context
2560
*  associated with the job is initialized. Usually every job aims to encode one
2561
*  row of mb's. Basing on the row indices provided by the job, the process
2562
*  context's buffer ptrs, slice indices and other elements that are necessary
2563
*  during core-coding are initialized.
2564
*
2565
* @param[in] ps_proc
2566
*  Pointer to the current process context
2567
*
2568
* @returns error status
2569
*
2570
* @remarks none
2571
*
2572
*******************************************************************************
2573
*/
2574
IH264E_ERROR_T isvce_init_layer_proc_ctxt(isvce_process_ctxt_t *ps_proc)
2575
277k
{
2576
277k
    WORD32 i4_mb_x, i4_mb_y;
2577
2578
277k
    isvce_codec_t *ps_codec = ps_proc->ps_codec;
2579
277k
    n_mb_process_ctxt_t *ps_n_mb_ctxt = &ps_proc->s_n_mb_ctxt;
2580
277k
    quant_params_t *ps_qp_params = ps_proc->ps_qp_params[0];
2581
277k
    isvce_deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
2582
277k
    isvce_bs_ctxt_t *ps_bs = &(ps_deblk->s_bs_ctxt);
2583
277k
    svc_au_data_t *ps_cur_mv_buf = ps_proc->ps_cur_mv_buf;
2584
2585
277k
    i4_mb_x = ps_proc->i4_mb_x;
2586
277k
    i4_mb_y = ps_proc->i4_mb_y;
2587
2588
277k
    ASSERT((ps_codec->s_cfg.u4_wd - ps_codec->s_cfg.u4_disp_wd) == 0);
2589
277k
    ASSERT((ps_codec->s_cfg.u4_ht - ps_codec->s_cfg.u4_disp_ht) == 0);
2590
2591
277k
    ps_proc->i4_nmb_ntrpy = ps_proc->i4_wd_mbs;
2592
277k
    ps_proc->u4_nmb_me = 1;
2593
2594
277k
    ps_proc->s_src_buf_props = ps_proc->s_src_pic_buf_props;
2595
277k
    ps_proc->s_rec_buf_props = ps_proc->s_rec_pic_buf_props;
2596
277k
    ps_proc->as_ref_buf_props[0] = ps_proc->as_ref_pic_buf_props[0];
2597
277k
    ps_proc->as_ref_buf_props[1] = ps_proc->as_ref_pic_buf_props[1];
2598
2599
277k
    ps_proc->s_src_buf_props.as_component_bufs[0].pv_data =
2600
277k
        ((UWORD8 *) ps_proc->s_src_buf_props.as_component_bufs[0].pv_data) + (i4_mb_x * MB_SIZE) +
2601
277k
        ps_proc->s_src_buf_props.as_component_bufs[0].i4_data_stride * (i4_mb_y * MB_SIZE);
2602
277k
    ps_proc->s_src_buf_props.as_component_bufs[1].pv_data =
2603
277k
        ((UWORD8 *) ps_proc->s_src_pic_buf_props.as_component_bufs[1].pv_data) +
2604
277k
        (i4_mb_x * MB_SIZE) +
2605
277k
        ps_proc->s_src_buf_props.as_component_bufs[1].i4_data_stride * (i4_mb_y * BLK8x8SIZE);
2606
2607
277k
    ps_proc->s_rec_buf_props.as_component_bufs[0].pv_data =
2608
277k
        ((UWORD8 *) ps_proc->s_rec_buf_props.as_component_bufs[0].pv_data) + (i4_mb_x * MB_SIZE) +
2609
277k
        ps_proc->s_rec_buf_props.as_component_bufs[0].i4_data_stride * (i4_mb_y * MB_SIZE);
2610
277k
    ps_proc->s_rec_buf_props.as_component_bufs[1].pv_data =
2611
277k
        ((UWORD8 *) ps_proc->s_rec_buf_props.as_component_bufs[1].pv_data) + (i4_mb_x * MB_SIZE) +
2612
277k
        ps_proc->s_rec_buf_props.as_component_bufs[1].i4_data_stride * (i4_mb_y * BLK8x8SIZE);
2613
2614
277k
    ps_proc->as_ref_buf_props[0].as_component_bufs[0].pv_data =
2615
277k
        ((UWORD8 *) ps_proc->as_ref_buf_props[0].as_component_bufs[0].pv_data) +
2616
277k
        (i4_mb_x * MB_SIZE) +
2617
277k
        ps_proc->as_ref_buf_props[0].as_component_bufs[0].i4_data_stride * (i4_mb_y * MB_SIZE);
2618
277k
    ps_proc->as_ref_buf_props[0].as_component_bufs[1].pv_data =
2619
277k
        ((UWORD8 *) ps_proc->as_ref_buf_props[0].as_component_bufs[1].pv_data) +
2620
277k
        (i4_mb_x * MB_SIZE) +
2621
277k
        ps_proc->as_ref_buf_props[0].as_component_bufs[1].i4_data_stride * (i4_mb_y * BLK8x8SIZE);
2622
2623
277k
    ps_proc->as_ref_buf_props[1].as_component_bufs[0].pv_data =
2624
277k
        ((UWORD8 *) ps_proc->as_ref_buf_props[1].as_component_bufs[0].pv_data) +
2625
277k
        (i4_mb_x * MB_SIZE) +
2626
277k
        ps_proc->as_ref_buf_props[1].as_component_bufs[0].i4_data_stride * (i4_mb_y * MB_SIZE);
2627
277k
    ps_proc->as_ref_buf_props[1].as_component_bufs[1].pv_data =
2628
277k
        ((UWORD8 *) ps_proc->as_ref_buf_props[1].as_component_bufs[1].pv_data) +
2629
277k
        (i4_mb_x * MB_SIZE) +
2630
277k
        ps_proc->as_ref_buf_props[1].as_component_bufs[1].i4_data_stride * (i4_mb_y * BLK8x8SIZE);
2631
2632
277k
    ps_proc->pv_mb_coeff_data =
2633
277k
        ((UWORD8 *) ps_proc->pv_pic_mb_coeff_data) + i4_mb_y * ps_codec->u4_size_coeff_data;
2634
2635
277k
    ps_proc->pv_mb_header_data =
2636
277k
        ((UWORD8 *) ps_proc->pv_pic_mb_header_data) + i4_mb_y * ps_codec->u4_size_header_data;
2637
2638
277k
    ps_proc->i4_cur_slice_idx = ps_proc->pu1_slice_idx[i4_mb_y * ps_proc->i4_wd_mbs + i4_mb_x];
2639
2640
277k
    ps_proc->ps_mb_info =
2641
277k
        ps_cur_mv_buf->ps_svc_layer_data[ps_proc->u1_spatial_layer_id].ps_mb_info +
2642
277k
        i4_mb_y * ps_proc->i4_wd_mbs;
2643
2644
277k
    ps_proc->ps_col_mb =
2645
277k
        ps_proc->aps_mv_buf[1]->ps_svc_layer_data[ps_proc->u1_spatial_layer_id].ps_mb_info +
2646
277k
        i4_mb_y * ps_proc->i4_wd_mbs;
2647
2648
277k
    {
2649
277k
        ps_proc->s_nbr_info.ps_top_row_mb_info =
2650
277k
            ps_proc->s_nbr_info_base.ps_layer_nbr_info[ps_proc->u1_spatial_layer_id]
2651
277k
                .ps_top_row_mb_info +
2652
277k
            (i4_mb_x + (i4_mb_y - 1) * ps_proc->i4_wd_mbs);
2653
2654
277k
        ps_proc->s_nbr_info.ps_top_mb_intra_modes =
2655
277k
            ps_proc->s_nbr_info_base.ps_layer_nbr_info[ps_proc->u1_spatial_layer_id]
2656
277k
                .ps_top_mb_intra_modes +
2657
277k
            (i4_mb_x + (i4_mb_y - 1) * ps_proc->i4_wd_mbs);
2658
277k
    }
2659
2660
277k
    ps_proc->pu4_mb_pu_cnt =
2661
277k
        ps_cur_mv_buf->ps_svc_layer_data[ps_proc->u1_spatial_layer_id].pu4_num_pus_in_mb +
2662
277k
        (i4_mb_y * ps_proc->i4_wd_mbs);
2663
2664
277k
    ps_proc->ps_mb_info->u2_mb_type = I16x16;
2665
2666
277k
    ps_proc->u4_lambda = gu1_qp0[ps_qp_params->u1_mb_qp];
2667
2668
277k
    ps_proc->i4_mb_distortion = SHRT_MAX;
2669
2670
277k
    if(i4_mb_x == 0)
2671
276k
    {
2672
276k
        ps_proc->s_nbr_info.ps_left_mb_info[0].i4_mb_distortion = 0;
2673
276k
    }
2674
2675
277k
    ps_proc->i4_mb_cost = INT_MAX;
2676
2677
277k
    ps_deblk->i4_mb_x = ps_proc->i4_mb_x;
2678
    /* deblk lags the current mb proc by 1 row */
2679
    /* NOTE: Intra prediction has to happen with non deblocked samples used as
2680
     * reference */
2681
    /* Hence to deblk MB 0 of row 0, you have wait till MB 0 of row 1 is encoded.
2682
     */
2683
    /* For simplicity, we chose to lag deblking by 1 Row wrt to proc */
2684
277k
    ps_deblk->i4_mb_y = ps_proc->i4_mb_y - 1;
2685
2686
277k
    ps_deblk->s_rec_pic_buf_props = ps_proc->s_rec_pic_buf_props;
2687
2688
277k
    ps_bs->i4_mb_x = ps_proc->i4_mb_x;
2689
277k
    ps_bs->i4_mb_y = ps_proc->i4_mb_y;
2690
2691
277k
    ps_n_mb_ctxt->i4_mb_x = 0;
2692
277k
    ps_n_mb_ctxt->i4_mb_y = ps_deblk->i4_mb_y;
2693
277k
    ps_n_mb_ctxt->i4_n_mbs = ps_proc->i4_nmb_ntrpy;
2694
2695
277k
    return IH264E_SUCCESS;
2696
277k
}
2697
2698
/**
2699
*******************************************************************************
2700
*
2701
* @brief
2702
*  Returns size of buffers for storing SVC ILP data
2703
*
2704
* @param[in] u1_num_spatial_layers
2705
*  Num Spatial Layers
2706
*
2707
* @param[in] d_spatial_res_ratio
2708
*  Resolution Ratio b/w spatial layers
2709
*
2710
* @param[in] u4_wd
2711
*  Input Width
2712
*
2713
* @param[in] u4_ht
2714
*  Input Height
2715
*
2716
* @returns  Size of buffers
2717
*
2718
*******************************************************************************
2719
*/
2720
UWORD32 isvce_get_svc_ilp_buf_size(UWORD8 u1_num_spatial_layers, DOUBLE d_spatial_res_ratio,
2721
                                   UWORD32 u4_wd, UWORD32 u4_ht)
2722
14.8k
{
2723
14.8k
    WORD32 i;
2724
2725
14.8k
    UWORD32 u4_size = 0;
2726
2727
14.8k
    if(u1_num_spatial_layers > 1)
2728
12.1k
    {
2729
        /* ps_intra_recon_bufs */
2730
12.1k
        u4_size += u1_num_spatial_layers * sizeof(yuv_buf_props_t);
2731
2732
        /* ps_residual_bufs */
2733
12.1k
        u4_size += u1_num_spatial_layers * sizeof(yuv_buf_props_t);
2734
2735
        /* aps_layer_resampler_props[Y] */
2736
12.1k
        u4_size += u1_num_spatial_layers * sizeof(layer_resampler_props_t);
2737
2738
        /* aps_layer_resampler_props[UV] */
2739
12.1k
        u4_size += u1_num_spatial_layers * sizeof(layer_resampler_props_t);
2740
2741
43.6k
        for(i = u1_num_spatial_layers - 1; i >= 0; i--)
2742
31.5k
        {
2743
31.5k
            WORD32 i4_layer_luma_wd =
2744
31.5k
                ((DOUBLE) u4_wd / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) + 0.99;
2745
31.5k
            WORD32 i4_layer_luma_ht =
2746
31.5k
                ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) + 0.99;
2747
31.5k
            WORD32 i4_layer_luma_samples =
2748
31.5k
                (ALIGN16(i4_layer_luma_wd) + PAD_WD) * (i4_layer_luma_ht + PAD_HT);
2749
31.5k
            WORD32 i4_layer_uv_wd = i4_layer_luma_wd;
2750
31.5k
            WORD32 i4_layer_uv_ht = i4_layer_luma_ht / 2.0 + 0.99;
2751
31.5k
            WORD32 i4_layer_uv_samples =
2752
31.5k
                (ALIGN16(i4_layer_uv_wd) + PAD_WD) * (i4_layer_uv_ht + PAD_HT);
2753
2754
            /* ps_intra_recon_bufs */
2755
31.5k
            u4_size += (i4_layer_luma_samples + i4_layer_uv_samples) * sizeof(UWORD8);
2756
2757
            /* ps_residual_bufs */
2758
31.5k
            u4_size += (i4_layer_luma_samples + i4_layer_uv_samples) * sizeof(WORD16);
2759
31.5k
        }
2760
12.1k
    }
2761
2.67k
    else
2762
2.67k
    {
2763
2.67k
        WORD32 i4_layer_luma_wd = u4_wd;
2764
2.67k
        WORD32 i4_layer_luma_ht = u4_ht;
2765
2.67k
        WORD32 i4_layer_luma_samples =
2766
2.67k
            (ALIGN16(i4_layer_luma_wd) + PAD_WD) * (i4_layer_luma_ht + PAD_HT);
2767
2.67k
        WORD32 i4_layer_uv_wd = i4_layer_luma_wd;
2768
2.67k
        WORD32 i4_layer_uv_ht = i4_layer_luma_ht / 2.0 + 0.99;
2769
2.67k
        WORD32 i4_layer_uv_samples = (ALIGN16(i4_layer_uv_wd) + PAD_WD) * (i4_layer_uv_ht + PAD_HT);
2770
2771
        /* ps_residual_bufs */
2772
2.67k
        u4_size += sizeof(yuv_buf_props_t);
2773
2774
        /* ps_residual_bufs */
2775
2.67k
        u4_size += (i4_layer_luma_samples + i4_layer_uv_samples) * sizeof(WORD16);
2776
2.67k
    }
2777
2778
14.8k
    return u4_size;
2779
14.8k
}
2780
2781
static void isvce_layer_resampler_props_init(layer_resampler_props_t *ps_layer_props,
2782
                                             DOUBLE d_spatial_res_ratio, UWORD32 u4_wd,
2783
                                             UWORD32 u4_ht, UWORD8 u1_level_idc,
2784
                                             UWORD8 u1_is_chroma)
2785
12.9k
{
2786
12.9k
    const UWORD8 u1_ref_layer_field_pic_flag = 0;
2787
12.9k
    const UWORD8 u1_field_pic_flag = 0;
2788
12.9k
    const UWORD8 u1_frame_mbs_only_flag = 1;
2789
12.9k
    const UWORD8 u1_ref_layer_frame_mbs_only_flag = 1;
2790
12.9k
    const UWORD8 u1_bot_field_flag = 0;
2791
12.9k
    const WORD32 i4_scaled_ref_layer_left_offset = 0;
2792
12.9k
    const WORD32 i4_scaled_ref_layer_top_offset = 0;
2793
12.9k
    const WORD32 i4_ref_layer_chroma_phase_x_plus1 = 1;
2794
12.9k
    const WORD32 i4_ref_layer_chroma_phase_y_plus1 = 1;
2795
12.9k
    const WORD32 i4_chroma_phase_x_plus1 = 1;
2796
12.9k
    const WORD32 i4_chroma_phase_y_plus1 = 1;
2797
12.9k
    const WORD32 i4_sub_wd_chroma = 2;
2798
12.9k
    const WORD32 i4_sub_ht_chroma = 2;
2799
12.9k
    UWORD32 u4_ref_wd = (u4_wd / d_spatial_res_ratio);
2800
12.9k
    UWORD32 u4_ref_ht = (u4_ht / d_spatial_res_ratio) * (1 + u1_ref_layer_field_pic_flag);
2801
12.9k
    UWORD32 u4_scaled_wd = u4_wd;
2802
12.9k
    UWORD32 u4_scaled_ht = u4_ht * (1 + u1_field_pic_flag);
2803
2804
12.9k
    u4_ref_wd = u4_ref_wd >> u1_is_chroma;
2805
12.9k
    u4_ref_ht = u4_ref_ht >> u1_is_chroma;
2806
12.9k
    u4_scaled_wd = u4_scaled_wd >> u1_is_chroma;
2807
12.9k
    u4_scaled_ht = u4_scaled_ht >> u1_is_chroma;
2808
2809
12.9k
    if(u1_is_chroma)
2810
6.47k
    {
2811
6.47k
        ps_layer_props->i4_refphase_x = i4_ref_layer_chroma_phase_x_plus1 - 1;
2812
6.47k
        ps_layer_props->i4_refphase_y = i4_ref_layer_chroma_phase_y_plus1 - 1;
2813
6.47k
        ps_layer_props->i4_phase_x = i4_chroma_phase_x_plus1 - 1;
2814
6.47k
        ps_layer_props->i4_phase_y = i4_chroma_phase_y_plus1 - 1;
2815
6.47k
        ps_layer_props->u4_sub_wd = i4_sub_wd_chroma;
2816
6.47k
        ps_layer_props->u4_sub_ht = i4_sub_ht_chroma;
2817
6.47k
        ps_layer_props->u4_mb_wd = MB_SIZE >> 1;
2818
6.47k
        ps_layer_props->u4_mb_ht = MB_SIZE >> 1;
2819
6.47k
    }
2820
6.47k
    else
2821
6.47k
    {
2822
6.47k
        ps_layer_props->i4_refphase_x = 0;
2823
6.47k
        ps_layer_props->i4_refphase_y = 0;
2824
6.47k
        ps_layer_props->i4_phase_x = 0;
2825
6.47k
        ps_layer_props->i4_phase_y = 0;
2826
6.47k
        ps_layer_props->u4_sub_wd = 1;
2827
6.47k
        ps_layer_props->u4_sub_ht = 1;
2828
6.47k
        ps_layer_props->u4_mb_wd = MB_SIZE;
2829
6.47k
        ps_layer_props->u4_mb_ht = MB_SIZE;
2830
6.47k
    }
2831
2832
12.9k
    if(u1_level_idc <= 30)
2833
7.71k
    {
2834
7.71k
        ps_layer_props->u4_shift_x = 16;
2835
7.71k
        ps_layer_props->u4_shift_y = 16;
2836
7.71k
    }
2837
5.24k
    else
2838
5.24k
    {
2839
5.24k
        ps_layer_props->u4_shift_x = 31 - isvcd_get_ceil_log2(u4_ref_wd);
2840
5.24k
        ps_layer_props->u4_shift_y = 31 - isvcd_get_ceil_log2(u4_ref_ht);
2841
5.24k
    }
2842
2843
12.9k
    if((0 == u1_frame_mbs_only_flag) || (0 == u1_ref_layer_frame_mbs_only_flag))
2844
0
    {
2845
0
        ps_layer_props->i4_phase_y = ps_layer_props->i4_phase_y + 4 * u1_bot_field_flag;
2846
2847
0
        if(1 == u1_ref_layer_frame_mbs_only_flag)
2848
0
        {
2849
0
            ps_layer_props->i4_refphase_y = (2 * ps_layer_props->i4_refphase_y) + 2;
2850
0
        }
2851
0
        else
2852
0
        {
2853
0
            ps_layer_props->i4_refphase_y = ps_layer_props->i4_refphase_y + (4 * u1_bot_field_flag);
2854
0
        }
2855
0
    }
2856
2857
12.9k
    ps_layer_props->u4_scale_x =
2858
12.9k
        ((u4_ref_wd << ps_layer_props->u4_shift_x) + (u4_scaled_wd >> 1)) / (u4_scaled_wd);
2859
12.9k
    ps_layer_props->u4_scale_y =
2860
12.9k
        ((u4_ref_ht << ps_layer_props->u4_shift_y) + (u4_scaled_ht >> 1)) / (u4_scaled_ht);
2861
2862
12.9k
    ps_layer_props->i4_offset_x = i4_scaled_ref_layer_left_offset / ps_layer_props->u4_sub_wd;
2863
12.9k
    ps_layer_props->i4_add_x =
2864
12.9k
        (((u4_ref_wd * (2 + ps_layer_props->i4_phase_x)) << (ps_layer_props->u4_shift_x - 2)) +
2865
12.9k
         (u4_scaled_wd >> 1)) /
2866
12.9k
            u4_scaled_wd +
2867
12.9k
        (1 << (ps_layer_props->u4_shift_x - 5));
2868
12.9k
    ps_layer_props->i4_delta_x = 4 * (2 + ps_layer_props->i4_refphase_x);
2869
2870
12.9k
    if((1 == u1_frame_mbs_only_flag) && (1 == u1_ref_layer_frame_mbs_only_flag))
2871
12.9k
    {
2872
12.9k
        ps_layer_props->i4_offset_y = i4_scaled_ref_layer_top_offset / ps_layer_props->u4_sub_ht;
2873
12.9k
        ps_layer_props->i4_add_y =
2874
12.9k
            (((u4_ref_ht * (2 + ps_layer_props->i4_phase_y)) << (ps_layer_props->u4_shift_y - 2)) +
2875
12.9k
             (u4_scaled_ht >> 1)) /
2876
12.9k
                u4_scaled_ht +
2877
12.9k
            (1 << (ps_layer_props->u4_shift_y - 5));
2878
12.9k
        ps_layer_props->i4_delta_y = 4 * (2 + ps_layer_props->i4_refphase_y);
2879
12.9k
    }
2880
0
    else
2881
0
    {
2882
0
        ps_layer_props->i4_offset_y =
2883
0
            i4_scaled_ref_layer_top_offset / (2 * ps_layer_props->u4_sub_ht);
2884
0
        ps_layer_props->i4_add_y =
2885
0
            (((u4_ref_ht * (2 + ps_layer_props->i4_phase_y)) << (ps_layer_props->u4_shift_y - 3)) +
2886
0
             (u4_scaled_ht >> 1)) /
2887
0
                u4_scaled_ht +
2888
0
            (1 << (ps_layer_props->u4_shift_y - 5));
2889
0
        ps_layer_props->i4_delta_y = 2 * (2 + ps_layer_props->i4_refphase_y);
2890
0
    }
2891
12.9k
}
2892
2893
/**
2894
*******************************************************************************
2895
*
2896
* @brief
2897
*  Function to initialize svc ilp buffers
2898
*
2899
* @param[in] ps_codec
2900
*  Pointer to codec context
2901
*
2902
* @param[in] ps_mem_rec
2903
*  Pointer to memory allocated for input buffers
2904
*
2905
*******************************************************************************
2906
*/
2907
void isvce_svc_ilp_buf_init(isvce_codec_t *ps_codec, iv_mem_rec_t *ps_mem_rec)
2908
4.93k
{
2909
4.93k
    UWORD8 u1_num_spatial_layers = ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers;
2910
4.93k
    DOUBLE d_spatial_res_ratio = ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio;
2911
4.93k
    UWORD32 u4_wd = ps_codec->s_cfg.u4_wd;
2912
4.93k
    UWORD32 u4_ht = ps_codec->s_cfg.u4_ht;
2913
4.93k
    UWORD8 *pu1_buf = ps_mem_rec->pv_base;
2914
4.93k
    WORD64 i8_alloc_mem_size =
2915
4.93k
        isvce_get_svc_ilp_buf_size(u1_num_spatial_layers, d_spatial_res_ratio, u4_wd, u4_ht);
2916
2917
4.93k
    if(u1_num_spatial_layers > 1)
2918
4.04k
    {
2919
4.04k
        WORD32 i, j;
2920
2921
4.04k
        ps_codec->s_svc_ilp_data.ps_intra_recon_bufs = (yuv_buf_props_t *) pu1_buf;
2922
4.04k
        pu1_buf += u1_num_spatial_layers * sizeof(ps_codec->s_svc_ilp_data.ps_intra_recon_bufs[0]);
2923
4.04k
        i8_alloc_mem_size -=
2924
4.04k
            u1_num_spatial_layers * sizeof(ps_codec->s_svc_ilp_data.ps_intra_recon_bufs[0]);
2925
2926
4.04k
        ps_codec->s_svc_ilp_data.ps_residual_bufs = (yuv_buf_props_t *) pu1_buf;
2927
4.04k
        pu1_buf += u1_num_spatial_layers * sizeof(ps_codec->s_svc_ilp_data.ps_residual_bufs[0]);
2928
4.04k
        i8_alloc_mem_size -=
2929
4.04k
            u1_num_spatial_layers * sizeof(ps_codec->s_svc_ilp_data.ps_residual_bufs[0]);
2930
2931
12.1k
        for(i = 0; i < NUM_SP_COMPONENTS; i++)
2932
8.08k
        {
2933
8.08k
            ps_codec->s_svc_ilp_data.aps_layer_resampler_props[i] =
2934
8.08k
                (layer_resampler_props_t *) pu1_buf;
2935
8.08k
            pu1_buf += u1_num_spatial_layers *
2936
8.08k
                       sizeof(ps_codec->s_svc_ilp_data.aps_layer_resampler_props[i][0]);
2937
8.08k
            i8_alloc_mem_size -= u1_num_spatial_layers *
2938
8.08k
                                 sizeof(ps_codec->s_svc_ilp_data.aps_layer_resampler_props[i][0]);
2939
8.08k
        }
2940
2941
4.04k
        ASSERT(i8_alloc_mem_size >= 0);
2942
2943
14.5k
        for(i = u1_num_spatial_layers - 1; i >= 0; i--)
2944
10.5k
        {
2945
10.5k
            WORD32 i4_stride;
2946
2947
10.5k
            WORD32 i4_layer_luma_wd =
2948
10.5k
                ((DOUBLE) u4_wd / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) + 0.99;
2949
10.5k
            WORD32 i4_layer_luma_ht =
2950
10.5k
                ((DOUBLE) u4_ht / pow(d_spatial_res_ratio, u1_num_spatial_layers - 1 - i)) + 0.99;
2951
10.5k
            WORD32 i4_layer_luma_samples =
2952
10.5k
                (ALIGN16(i4_layer_luma_wd) + PAD_WD) * (i4_layer_luma_ht + PAD_HT);
2953
10.5k
            WORD32 i4_layer_uv_wd = i4_layer_luma_wd;
2954
10.5k
            WORD32 i4_layer_uv_ht = i4_layer_luma_ht / 2.0 + 0.99;
2955
10.5k
            WORD32 i4_layer_uv_samples =
2956
10.5k
                (ALIGN16(i4_layer_uv_wd) + PAD_WD) * (i4_layer_uv_ht + PAD_HT);
2957
2958
10.5k
            ps_codec->s_svc_ilp_data.ps_intra_recon_bufs[i].u4_width = i4_layer_luma_wd;
2959
10.5k
            ps_codec->s_svc_ilp_data.ps_intra_recon_bufs[i].u4_height = i4_layer_luma_ht;
2960
10.5k
            ps_codec->s_svc_ilp_data.ps_intra_recon_bufs[i].e_color_format = IV_YUV_420SP_UV;
2961
10.5k
            ps_codec->s_svc_ilp_data.ps_intra_recon_bufs[i].u1_bit_depth = 8;
2962
2963
10.5k
            i4_stride = ALIGN16(i4_layer_luma_wd) + PAD_WD;
2964
10.5k
            ps_codec->s_svc_ilp_data.ps_intra_recon_bufs[i].as_component_bufs[Y].pv_data =
2965
10.5k
                pu1_buf + PAD_LEFT + PAD_TOP * i4_stride;
2966
10.5k
            ps_codec->s_svc_ilp_data.ps_intra_recon_bufs[i].as_component_bufs[Y].i4_data_stride =
2967
10.5k
                ALIGN16(i4_layer_luma_wd) + PAD_WD;
2968
10.5k
            pu1_buf += i4_layer_luma_samples * sizeof(UWORD8);
2969
10.5k
            i8_alloc_mem_size -= i4_layer_luma_samples * sizeof(UWORD8);
2970
2971
10.5k
            i4_stride = ALIGN16(i4_layer_uv_wd) + PAD_WD;
2972
10.5k
            ps_codec->s_svc_ilp_data.ps_intra_recon_bufs[i].as_component_bufs[UV].pv_data =
2973
10.5k
                pu1_buf + PAD_LEFT + PAD_TOP * i4_stride;
2974
10.5k
            ps_codec->s_svc_ilp_data.ps_intra_recon_bufs[i].as_component_bufs[UV].i4_data_stride =
2975
10.5k
                ALIGN16(i4_layer_uv_wd) + PAD_WD;
2976
10.5k
            pu1_buf += i4_layer_uv_samples * sizeof(UWORD8);
2977
10.5k
            i8_alloc_mem_size -= i4_layer_uv_samples * sizeof(UWORD8);
2978
2979
10.5k
            ps_codec->s_svc_ilp_data.ps_residual_bufs[i].u4_width = i4_layer_luma_wd;
2980
10.5k
            ps_codec->s_svc_ilp_data.ps_residual_bufs[i].u4_height = i4_layer_luma_ht;
2981
10.5k
            ps_codec->s_svc_ilp_data.ps_residual_bufs[i].e_color_format = IV_YUV_420SP_UV;
2982
10.5k
            ps_codec->s_svc_ilp_data.ps_residual_bufs[i].u1_bit_depth = 10;
2983
2984
10.5k
            i4_stride = ALIGN16(i4_layer_luma_wd) + PAD_WD;
2985
10.5k
            ps_codec->s_svc_ilp_data.ps_residual_bufs[i].as_component_bufs[Y].pv_data =
2986
10.5k
                pu1_buf + (PAD_LEFT + PAD_TOP * i4_stride) * (sizeof(WORD16) / sizeof(pu1_buf[0]));
2987
10.5k
            ps_codec->s_svc_ilp_data.ps_residual_bufs[i].as_component_bufs[Y].i4_data_stride =
2988
10.5k
                i4_stride;
2989
10.5k
            pu1_buf += i4_layer_luma_samples * sizeof(WORD16);
2990
10.5k
            i8_alloc_mem_size -= i4_layer_luma_samples * sizeof(WORD16);
2991
2992
10.5k
            i4_stride = ALIGN16(i4_layer_uv_wd) + PAD_WD;
2993
10.5k
            ps_codec->s_svc_ilp_data.ps_residual_bufs[i].as_component_bufs[UV].pv_data =
2994
10.5k
                pu1_buf + (PAD_LEFT + PAD_TOP * i4_stride) * (sizeof(WORD16) / sizeof(pu1_buf[0]));
2995
10.5k
            ps_codec->s_svc_ilp_data.ps_residual_bufs[i].as_component_bufs[UV].i4_data_stride =
2996
10.5k
                i4_stride;
2997
10.5k
            pu1_buf += i4_layer_uv_samples * sizeof(WORD16);
2998
10.5k
            i8_alloc_mem_size -= i4_layer_uv_samples * sizeof(WORD16);
2999
3000
10.5k
            ps_codec->s_svc_ilp_data.ps_residual_bufs[i].as_component_bufs[V].pv_data = NULL;
3001
3002
10.5k
            ASSERT(i8_alloc_mem_size >= 0);
3003
3004
10.5k
            if(i >= 1)
3005
6.47k
            {
3006
19.4k
                for(j = 0; j < NUM_SP_COMPONENTS; j++)
3007
12.9k
                {
3008
12.9k
                    isvce_layer_resampler_props_init(
3009
12.9k
                        &ps_codec->s_svc_ilp_data.aps_layer_resampler_props[j][i],
3010
12.9k
                        d_spatial_res_ratio, i4_layer_luma_wd, i4_layer_luma_ht,
3011
12.9k
                        ps_codec->s_cfg.u4_max_level, ((COMPONENT_TYPE) j) == UV);
3012
12.9k
                }
3013
6.47k
            }
3014
10.5k
        }
3015
4.04k
    }
3016
891
    else
3017
891
    {
3018
891
        WORD32 i4_stride;
3019
3020
891
        WORD32 i4_layer_luma_wd = u4_wd;
3021
891
        WORD32 i4_layer_luma_ht = u4_ht;
3022
891
        WORD32 i4_layer_luma_samples =
3023
891
            (ALIGN16(i4_layer_luma_wd) + PAD_WD) * (i4_layer_luma_ht + PAD_HT);
3024
891
        WORD32 i4_layer_uv_wd = i4_layer_luma_wd;
3025
891
        WORD32 i4_layer_uv_ht = i4_layer_luma_ht / 2.0 + 0.99;
3026
891
        WORD32 i4_layer_uv_samples = (ALIGN16(i4_layer_uv_wd) + PAD_WD) * (i4_layer_uv_ht + PAD_HT);
3027
3028
891
        ps_codec->s_svc_ilp_data.ps_residual_bufs = (yuv_buf_props_t *) pu1_buf;
3029
891
        pu1_buf += sizeof(ps_codec->s_svc_ilp_data.ps_residual_bufs[0]);
3030
891
        i8_alloc_mem_size -= sizeof(ps_codec->s_svc_ilp_data.ps_residual_bufs[0]);
3031
3032
891
        ASSERT(i8_alloc_mem_size >= 0);
3033
3034
891
        ps_codec->s_svc_ilp_data.ps_residual_bufs[0].u4_width = i4_layer_luma_wd;
3035
891
        ps_codec->s_svc_ilp_data.ps_residual_bufs[0].u4_height = i4_layer_luma_ht;
3036
891
        ps_codec->s_svc_ilp_data.ps_residual_bufs[0].e_color_format = IV_YUV_420SP_UV;
3037
891
        ps_codec->s_svc_ilp_data.ps_residual_bufs[0].u1_bit_depth = 10;
3038
3039
891
        i4_stride = ALIGN16(i4_layer_luma_wd) + PAD_WD;
3040
891
        ps_codec->s_svc_ilp_data.ps_residual_bufs[0].as_component_bufs[Y].pv_data =
3041
891
            pu1_buf + (PAD_LEFT + PAD_TOP * i4_stride) * (sizeof(WORD16) / sizeof(pu1_buf[0]));
3042
891
        ps_codec->s_svc_ilp_data.ps_residual_bufs[0].as_component_bufs[Y].i4_data_stride =
3043
891
            i4_stride;
3044
891
        pu1_buf += i4_layer_luma_samples * sizeof(WORD16);
3045
891
        i8_alloc_mem_size -= i4_layer_luma_samples * sizeof(WORD16);
3046
3047
891
        i4_stride = ALIGN16(i4_layer_uv_wd) + PAD_WD;
3048
891
        ps_codec->s_svc_ilp_data.ps_residual_bufs[0].as_component_bufs[UV].pv_data =
3049
891
            pu1_buf + (PAD_LEFT + PAD_TOP * i4_stride) * (sizeof(WORD16) / sizeof(pu1_buf[0]));
3050
891
        ps_codec->s_svc_ilp_data.ps_residual_bufs[0].as_component_bufs[UV].i4_data_stride =
3051
891
            i4_stride;
3052
891
        pu1_buf += i4_layer_uv_samples * sizeof(WORD16);
3053
891
        i8_alloc_mem_size -= i4_layer_uv_samples * sizeof(WORD16);
3054
3055
891
        ps_codec->s_svc_ilp_data.ps_residual_bufs[0].as_component_bufs[V].pv_data = NULL;
3056
3057
891
        ASSERT(i8_alloc_mem_size >= 0);
3058
891
    }
3059
4.93k
}
3060
3061
static FORCEINLINE UWORD32 isvce_get_residual_csbf(mem_fxns_t *ps_mem_fxns,
3062
                                                   buffer_container_t *ps_comp_buf)
3063
247k
{
3064
247k
    WORD32 i;
3065
3066
247k
    UWORD32 u4_csbf = 0;
3067
3068
4.18M
    for(i = 0; i < MAX_TU_IN_MB; i++)
3069
3.93M
    {
3070
3.93M
        UWORD8 u1_zscan_idx = gau1_raster_to_zscan_map[i];
3071
3.93M
        UWORD8 u1_offset_x = (i % MAX_TU_IN_MB_ROW) * MIN_TU_SIZE;
3072
3.93M
        UWORD8 u1_offset_y = (i / MAX_TU_IN_MB_ROW) * MIN_TU_SIZE;
3073
3.93M
        WORD16 *pi2_res = ((WORD16 *) ps_comp_buf->pv_data) + u1_offset_x +
3074
3.93M
                          u1_offset_y * ps_comp_buf->i4_data_stride;
3075
3.93M
        UWORD8 u1_cbf = ps_mem_fxns->pf_nonzero_checker(
3076
3.93M
            (UWORD8 *) pi2_res, ps_comp_buf->i4_data_stride * (sizeof(WORD16) / sizeof(UWORD8)),
3077
3.93M
            MIN_TU_SIZE * (sizeof(WORD16) / sizeof(UWORD8)), MIN_TU_SIZE);
3078
3079
3.93M
        u4_csbf |= (u1_cbf << u1_zscan_idx);
3080
3.93M
    }
3081
3082
247k
    return u4_csbf;
3083
247k
}
3084
3085
/**
3086
*******************************************************************************
3087
*
3088
* @brief
3089
*  Function to update svc ilp buffers after every MB
3090
*
3091
* @param[in] ps_proc
3092
*  Pointer to process context
3093
*
3094
*******************************************************************************
3095
*/
3096
void isvce_svc_ilp_buf_update(isvce_process_ctxt_t *ps_proc)
3097
7.19M
{
3098
7.19M
    isvce_codec_t *ps_codec = ps_proc->ps_codec;
3099
7.19M
    svc_params_t *ps_svc_params = &ps_codec->s_cfg.s_svc_params;
3100
3101
7.19M
    UWORD8 u1_spatial_layer_id = ps_proc->u1_spatial_layer_id;
3102
3103
7.19M
    if(ps_svc_params->u1_num_spatial_layers > 1)
3104
6.25M
    {
3105
6.25M
        buffer_container_t s_src;
3106
6.25M
        buffer_container_t s_dst;
3107
3108
6.25M
        WORD32 i;
3109
3110
6.25M
        svc_ilp_data_t *ps_svc_ilp_data = &ps_codec->s_svc_ilp_data;
3111
6.25M
        isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
3112
6.25M
        mem_fxns_t *ps_mem_fxns = &ps_isa_dependent_fxns->s_mem_fxns;
3113
6.25M
        yuv_buf_props_t *ps_residual_buf =
3114
6.25M
            &ps_codec->s_svc_ilp_data.ps_residual_bufs[u1_spatial_layer_id];
3115
3116
6.25M
        WORD32 i4_mb_x = ps_proc->i4_mb_x;
3117
6.25M
        WORD32 i4_mb_y = ps_proc->i4_mb_y;
3118
3119
6.25M
        ASSERT(ps_proc->s_rec_buf_props.e_color_format == IV_YUV_420SP_UV);
3120
3121
6.25M
        if(u1_spatial_layer_id < (ps_svc_params->u1_num_spatial_layers - 1))
3122
1.57M
        {
3123
1.57M
            if(ps_proc->ps_mb_info->u1_is_intra)
3124
1.37M
            {
3125
4.10M
                for(i = 0; i < NUM_SP_COMPONENTS; i++)
3126
2.72M
                {
3127
2.72M
                    UWORD8 u1_is_chroma = (Y != ((COMPONENT_TYPE) i));
3128
3129
2.72M
                    s_src = ps_proc->s_rec_buf_props.as_component_bufs[i];
3130
3131
2.72M
                    s_dst.i4_data_stride = ps_svc_ilp_data->ps_intra_recon_bufs[u1_spatial_layer_id]
3132
2.72M
                                               .as_component_bufs[i]
3133
2.72M
                                               .i4_data_stride;
3134
2.72M
                    s_dst.pv_data =
3135
2.72M
                        ((UWORD8 *) ps_svc_ilp_data->ps_intra_recon_bufs[u1_spatial_layer_id]
3136
2.72M
                             .as_component_bufs[i]
3137
2.72M
                             .pv_data) +
3138
2.72M
                        i4_mb_x * MB_SIZE +
3139
2.72M
                        i4_mb_y * (MB_SIZE >> u1_is_chroma) * s_dst.i4_data_stride;
3140
3141
2.72M
                    ps_mem_fxns->pf_copy_2d((UWORD8 *) s_dst.pv_data, s_dst.i4_data_stride,
3142
2.72M
                                            (UWORD8 *) s_src.pv_data, s_src.i4_data_stride, MB_SIZE,
3143
2.72M
                                            (MB_SIZE >> u1_is_chroma));
3144
2.72M
                }
3145
1.37M
            }
3146
204k
            else
3147
204k
            {
3148
612k
                for(i = 0; i < NUM_SP_COMPONENTS; i++)
3149
408k
                {
3150
408k
                    UWORD8 u1_is_chroma = (Y != ((COMPONENT_TYPE) i));
3151
3152
408k
                    s_dst.i4_data_stride = ps_svc_ilp_data->ps_intra_recon_bufs[u1_spatial_layer_id]
3153
408k
                                               .as_component_bufs[i]
3154
408k
                                               .i4_data_stride;
3155
408k
                    s_dst.pv_data =
3156
408k
                        ((UWORD8 *) ps_svc_ilp_data->ps_intra_recon_bufs[u1_spatial_layer_id]
3157
408k
                             .as_component_bufs[i]
3158
408k
                             .pv_data) +
3159
408k
                        i4_mb_x * MB_SIZE +
3160
408k
                        i4_mb_y * (MB_SIZE >> u1_is_chroma) * s_dst.i4_data_stride;
3161
3162
408k
                    ps_mem_fxns->pf_memset_2d((UWORD8 *) s_dst.pv_data, s_dst.i4_data_stride, 0,
3163
408k
                                              MB_SIZE, (MB_SIZE >> u1_is_chroma));
3164
408k
                }
3165
204k
            }
3166
1.57M
        }
3167
3168
6.25M
        if(ENABLE_RESIDUAL_PREDICTION && (ps_proc->i4_slice_type != ISLICE) &&
3169
6.25M
           (u1_spatial_layer_id < (ps_svc_params->u1_num_spatial_layers - 1)))
3170
243k
        {
3171
243k
            if(ps_proc->ps_mb_info->u1_is_intra || (ps_proc->ps_mb_info->u2_mb_type == PSKIP) ||
3172
243k
               (ps_proc->ps_mb_info->u2_mb_type == BSKIP))
3173
90.9k
            {
3174
272k
                for(i = 0; i < NUM_SP_COMPONENTS; i++)
3175
181k
                {
3176
181k
                    buffer_container_t *ps_comp_buf;
3177
3178
181k
                    WORD16 *pi2_res;
3179
3180
181k
                    UWORD8 u1_is_chroma = (Y != ((COMPONENT_TYPE) i));
3181
3182
181k
                    ps_comp_buf = &ps_residual_buf->as_component_bufs[u1_is_chroma ? UV : Y];
3183
181k
                    pi2_res =
3184
181k
                        ((WORD16 *) ps_comp_buf->pv_data) + ps_proc->i4_mb_x * MB_SIZE +
3185
181k
                        ps_proc->i4_mb_y * (MB_SIZE >> u1_is_chroma) * ps_comp_buf->i4_data_stride;
3186
3187
181k
                    ps_mem_fxns->pf_memset_2d(
3188
181k
                        (UWORD8 *) pi2_res,
3189
181k
                        ps_comp_buf->i4_data_stride * (sizeof(WORD16) / sizeof(UWORD8)), 0,
3190
181k
                        MB_SIZE * (sizeof(WORD16) / sizeof(UWORD8)), MB_SIZE >> u1_is_chroma);
3191
181k
                }
3192
90.9k
            }
3193
243k
        }
3194
3195
6.25M
        if(ENABLE_RESIDUAL_PREDICTION && (u1_spatial_layer_id > 0) &&
3196
6.25M
           !(ps_proc->ps_mb_info->u1_is_intra || (ps_proc->ps_mb_info->u2_mb_type == PSKIP) ||
3197
5.29M
             (ps_proc->ps_mb_info->u2_mb_type == BSKIP)))
3198
247k
        {
3199
247k
            s_src = ps_residual_buf->as_component_bufs[Y];
3200
247k
            s_src.pv_data = ((WORD16 *) s_src.pv_data) + ps_proc->i4_mb_x * MB_SIZE +
3201
247k
                            ps_proc->i4_mb_y * MB_SIZE * s_src.i4_data_stride;
3202
3203
247k
            ps_proc->ps_mb_info->u4_res_csbp = isvce_get_residual_csbf(ps_mem_fxns, &s_src);
3204
247k
        }
3205
6.01M
        else
3206
6.01M
        {
3207
6.01M
            ps_proc->ps_mb_info->u4_res_csbp = 0;
3208
6.01M
        }
3209
6.25M
    }
3210
936k
    else
3211
936k
    {
3212
936k
        ps_proc->ps_mb_info->u4_res_csbp = 0;
3213
936k
    }
3214
7.19M
}
3215
3216
/*
3217
 * Padding has a one MB row dependency on deblock  which
3218
 * in turn has a one MB row dependency on encode
3219
 */
3220
static IH264E_ERROR_T isvce_pad_frame(isvce_process_ctxt_t *ps_proc, yuv_buf_props_t *ps_pad_buf)
3221
163k
{
3222
    /* codec context */
3223
163k
    isvce_codec_t *ps_codec = ps_proc->ps_codec;
3224
3225
163k
    WORD32 i4_element_size = (ps_pad_buf->u1_bit_depth > 8) ? 2 : 1;
3226
3227
    /* src buffers luma */
3228
163k
    WORD32 i4_luma_stride = ps_pad_buf->as_component_bufs[0].i4_data_stride * i4_element_size;
3229
163k
    UWORD8 *pu1_curr_pic_luma = (UWORD8 *) (ps_pad_buf->as_component_bufs[0].pv_data);
3230
3231
    /* src buffers chroma */
3232
163k
    WORD32 i4_chroma_stride = ps_pad_buf->as_component_bufs[1].i4_data_stride * i4_element_size;
3233
163k
    UWORD8 *pu1_curr_pic_chroma = (UWORD8 *) (ps_pad_buf->as_component_bufs[1].pv_data);
3234
3235
163k
    WORD32 i4_bottom_offset_luma = ps_pad_buf->u4_height * i4_luma_stride;
3236
163k
    WORD32 i4_bottom_offset_chroma = (ps_pad_buf->u4_height >> 1) * i4_chroma_stride;
3237
3238
    /* Pad left */
3239
163k
    ps_codec->pf_pad_left_luma(pu1_curr_pic_luma, i4_luma_stride, ps_pad_buf->u4_height,
3240
163k
                               PAD_LEFT * i4_element_size);
3241
163k
    ps_codec->pf_pad_left_chroma(pu1_curr_pic_chroma, i4_chroma_stride, ps_pad_buf->u4_height >> 1,
3242
163k
                                 PAD_LEFT * i4_element_size);
3243
3244
    /* Pad right */
3245
163k
    ps_codec->pf_pad_right_luma(pu1_curr_pic_luma + ps_pad_buf->u4_width * i4_element_size,
3246
163k
                                i4_luma_stride, ps_pad_buf->u4_height, PAD_RIGHT * i4_element_size);
3247
163k
    ps_codec->pf_pad_right_chroma(pu1_curr_pic_chroma + ps_pad_buf->u4_width * i4_element_size,
3248
163k
                                  i4_chroma_stride, ps_pad_buf->u4_height >> 1,
3249
163k
                                  PAD_RIGHT * i4_element_size);
3250
3251
    /* Pad top */
3252
163k
    ps_codec->pf_pad_top(pu1_curr_pic_luma - (PAD_LEFT * i4_element_size), i4_luma_stride,
3253
163k
                         (ps_pad_buf->u4_width + PAD_WD) * i4_element_size, PAD_TOP);
3254
163k
    ps_codec->pf_pad_top(pu1_curr_pic_chroma - (PAD_LEFT * i4_element_size), i4_chroma_stride,
3255
163k
                         (ps_pad_buf->u4_width + PAD_WD) * i4_element_size, PAD_TOP >> 1);
3256
3257
    /* Pad bottom */
3258
163k
    ps_codec->pf_pad_bottom(
3259
163k
        pu1_curr_pic_luma + i4_bottom_offset_luma - (PAD_LEFT * i4_element_size), i4_luma_stride,
3260
163k
        (ps_pad_buf->u4_width + PAD_WD) * i4_element_size, PAD_BOT);
3261
163k
    ps_codec->pf_pad_bottom(
3262
163k
        pu1_curr_pic_chroma + i4_bottom_offset_chroma - (PAD_LEFT * i4_element_size),
3263
163k
        i4_chroma_stride, (ps_pad_buf->u4_width + PAD_WD) * i4_element_size, PAD_BOT >> 1);
3264
3265
163k
    return IH264E_SUCCESS;
3266
163k
}
3267
3268
void isvce_svc_pad_frame(isvce_process_ctxt_t *ps_proc)
3269
58.7k
{
3270
58.7k
    isvce_codec_t *ps_codec = ps_proc->ps_codec;
3271
3272
58.7k
    isvce_pad_frame(ps_proc, &(ps_proc->s_rec_pic_buf_props));
3273
3274
58.7k
    if(ps_proc->s_svc_params.u1_num_spatial_layers > 1)
3275
52.3k
    {
3276
52.3k
        isvce_pad_frame(
3277
52.3k
            ps_proc, &(ps_codec->s_svc_ilp_data.ps_intra_recon_bufs[ps_proc->u1_spatial_layer_id]));
3278
52.3k
        isvce_pad_frame(ps_proc,
3279
52.3k
                        &(ps_codec->s_svc_ilp_data.ps_residual_bufs[ps_proc->u1_spatial_layer_id]));
3280
52.3k
    }
3281
58.7k
}
3282
3283
/**
3284
*******************************************************************************
3285
*
3286
* @brief
3287
*  Initialize AIR mb frame Map
3288
*
3289
* @par Description:
3290
*  Initialize AIR mb frame map
3291
*  MB frame map indicates which frame an Mb should be coded as intra according
3292
*to AIR
3293
*
3294
* @param[in] ps_codec
3295
*  Pointer to codec context
3296
*
3297
* @returns  error_status
3298
*
3299
* @remarks
3300
*
3301
*
3302
*******************************************************************************
3303
*/
3304
IH264E_ERROR_T isvce_init_air_map(isvce_codec_t *ps_codec)
3305
9.84k
{
3306
    /* intra refresh map */
3307
9.84k
    UWORD16 *pu2_intr_rfrsh_map = ps_codec->pu2_intr_rfrsh_map;
3308
3309
    /* air mode */
3310
9.84k
    IVE_AIR_MODE_T air_mode = ps_codec->s_cfg.e_air_mode;
3311
3312
    /* refresh period */
3313
9.84k
    UWORD32 air_period = ps_codec->s_cfg.u4_air_refresh_period;
3314
3315
    /* mb cnt */
3316
9.84k
    UWORD32 u4_mb_cnt = ps_codec->s_cfg.i4_wd_mbs * ps_codec->s_cfg.i4_ht_mbs;
3317
3318
    /* temp var */
3319
9.84k
    UWORD32 curr_mb, seed_rand = 1;
3320
3321
9.84k
    switch(air_mode)
3322
9.84k
    {
3323
0
        case IVE_AIR_MODE_CYCLIC:
3324
3325
0
            for(curr_mb = 0; curr_mb < u4_mb_cnt; curr_mb++)
3326
0
            {
3327
0
                pu2_intr_rfrsh_map[curr_mb] = curr_mb % air_period;
3328
0
            }
3329
0
            break;
3330
3331
0
        case IVE_AIR_MODE_RANDOM:
3332
3333
0
            for(curr_mb = 0; curr_mb < u4_mb_cnt; curr_mb++)
3334
0
            {
3335
0
                seed_rand = (seed_rand * 32719 + 3) % 32749;
3336
0
                pu2_intr_rfrsh_map[curr_mb] = seed_rand % air_period;
3337
0
            }
3338
0
            break;
3339
3340
9.84k
        default:
3341
3342
9.84k
            break;
3343
9.84k
    }
3344
3345
9.84k
    return IH264E_SUCCESS;
3346
9.84k
}
3347
3348
/**
3349
******************************************************************************
3350
*
3351
* @brief
3352
*  derivation process for macroblock availability
3353
*
3354
* @par   Description
3355
*  Calculates the availability of the left, top, topright and topleft macroblocks.
3356
*
3357
* @param[in] ps_proc_ctxt
3358
*  pointer to proc context (handle)
3359
*
3360
* @remarks Based on section 6.4.5 in H264 spec
3361
*
3362
* @return  none
3363
*
3364
******************************************************************************
3365
*/
3366
void isvce_derive_nghbr_avbl_of_mbs(isvce_process_ctxt_t *ps_proc)
3367
8.07M
{
3368
8.07M
    UWORD8 *pu1_slice_idx_curr = ps_proc->pu1_slice_idx;
3369
8.07M
    UWORD8 *pu1_slice_idx_b;
3370
8.07M
    UWORD8 *pu1_slice_idx_a;
3371
8.07M
    UWORD8 *pu1_slice_idx_c;
3372
8.07M
    UWORD8 *pu1_slice_idx_d;
3373
8.07M
    block_neighbors_t *ps_ngbr_avbl;
3374
8.07M
    WORD32 i4_mb_x, i4_mb_y;
3375
8.07M
    WORD32 i4_wd_mbs;
3376
3377
8.07M
    i4_mb_x = ps_proc->i4_mb_x;
3378
8.07M
    i4_mb_y = ps_proc->i4_mb_y;
3379
3380
8.07M
    i4_wd_mbs = ps_proc->i4_wd_mbs;
3381
3382
8.07M
    pu1_slice_idx_curr += (i4_mb_y * i4_wd_mbs) + i4_mb_x;
3383
8.07M
    pu1_slice_idx_a = pu1_slice_idx_curr - 1;
3384
8.07M
    pu1_slice_idx_b = pu1_slice_idx_curr - i4_wd_mbs;
3385
8.07M
    pu1_slice_idx_c = pu1_slice_idx_b + 1;
3386
8.07M
    pu1_slice_idx_d = pu1_slice_idx_b - 1;
3387
8.07M
    ps_ngbr_avbl = ps_proc->ps_ngbr_avbl;
3388
3389
    /**********************************************************************/
3390
    /* The macroblock is marked as available, unless one of the following */
3391
    /* conditions is true in which case the macroblock shall be marked as */
3392
    /* not available.                                                     */
3393
    /* 1. mbAddr < 0                                                      */
3394
    /* 2  mbAddr > CurrMbAddr                                             */
3395
    /* 3. the macroblock with address mbAddr belongs to a different slice */
3396
    /* than the macroblock with address CurrMbAddr                        */
3397
    /**********************************************************************/
3398
3399
    /* left macroblock availability */
3400
8.07M
    if(i4_mb_x == 0)
3401
389k
    { /* macroblocks along first column */
3402
389k
        ps_ngbr_avbl->u1_mb_a = 0;
3403
389k
    }
3404
7.68M
    else
3405
7.68M
    { /* macroblocks belong to same slice? */
3406
7.68M
        if(*pu1_slice_idx_a != *pu1_slice_idx_curr)
3407
0
            ps_ngbr_avbl->u1_mb_a = 0;
3408
7.68M
        else
3409
7.68M
            ps_ngbr_avbl->u1_mb_a = 1;
3410
7.68M
    }
3411
3412
    /* top macroblock availability */
3413
8.07M
    if(i4_mb_y == 0)
3414
783k
    { /* macroblocks along first row */
3415
783k
        ps_ngbr_avbl->u1_mb_b = 0;
3416
783k
    }
3417
7.29M
    else
3418
7.29M
    { /* macroblocks belong to same slice? */
3419
7.29M
        if(*pu1_slice_idx_b != *pu1_slice_idx_curr)
3420
0
            ps_ngbr_avbl->u1_mb_b = 0;
3421
7.29M
        else
3422
7.29M
            ps_ngbr_avbl->u1_mb_b = 1;
3423
7.29M
    }
3424
3425
    /* top right macroblock availability */
3426
8.07M
    if(i4_mb_x == i4_wd_mbs - 1 || i4_mb_y == 0)
3427
1.07M
    { /* macroblocks along last column */
3428
1.07M
        ps_ngbr_avbl->u1_mb_c = 0;
3429
1.07M
    }
3430
7.00M
    else
3431
7.00M
    { /* macroblocks belong to same slice? */
3432
7.00M
        if(*pu1_slice_idx_c != *pu1_slice_idx_curr)
3433
0
            ps_ngbr_avbl->u1_mb_c = 0;
3434
7.00M
        else
3435
7.00M
            ps_ngbr_avbl->u1_mb_c = 1;
3436
7.00M
    }
3437
3438
    /* top left macroblock availability */
3439
8.07M
    if(i4_mb_x == 0 || i4_mb_y == 0)
3440
1.07M
    { /* macroblocks along first column */
3441
1.07M
        ps_ngbr_avbl->u1_mb_d = 0;
3442
1.07M
    }
3443
7.00M
    else
3444
7.00M
    { /* macroblocks belong to same slice? */
3445
7.00M
        if(*pu1_slice_idx_d != *pu1_slice_idx_curr)
3446
0
            ps_ngbr_avbl->u1_mb_d = 0;
3447
7.00M
        else
3448
7.00M
            ps_ngbr_avbl->u1_mb_d = 1;
3449
7.00M
    }
3450
8.07M
}
3451
3452
static IH264E_ERROR_T isvce_rc_init_wrapper(isvce_codec_t *ps_codec)
3453
13.1k
{
3454
13.1k
    WORD32 i;
3455
3456
13.1k
    isvce_cfg_params_t *ps_cfg = &ps_codec->s_cfg;
3457
3458
13.1k
    IH264E_ERROR_T err = isvce_svc_rc_params_validate(ps_cfg);
3459
3460
13.1k
    if(IH264E_SUCCESS != err)
3461
433
    {
3462
433
        return err;
3463
433
    }
3464
3465
25.4k
    for(i = 0; i < ps_cfg->s_svc_params.u1_num_spatial_layers; i++)
3466
12.7k
    {
3467
12.7k
        UWORD8 au1_init_qp[MAX_PIC_TYPE];
3468
12.7k
        UWORD8 au1_min_max_qp[2 * MAX_PIC_TYPE];
3469
3470
12.7k
        au1_init_qp[0] = gau1_h264_to_mpeg2_qmap[ps_cfg->au4_i_qp[i]];
3471
12.7k
        au1_init_qp[1] = gau1_h264_to_mpeg2_qmap[ps_cfg->au4_p_qp[i]];
3472
12.7k
        au1_init_qp[2] = gau1_h264_to_mpeg2_qmap[ps_cfg->au4_b_qp[i]];
3473
3474
12.7k
        au1_min_max_qp[2 * I_PIC] = gau1_h264_to_mpeg2_qmap[ps_cfg->au4_i_qp_min[i]];
3475
12.7k
        au1_min_max_qp[2 * I_PIC + 1] = gau1_h264_to_mpeg2_qmap[ps_cfg->au4_i_qp_max[i]];
3476
3477
12.7k
        au1_min_max_qp[2 * P_PIC] = gau1_h264_to_mpeg2_qmap[ps_cfg->au4_p_qp_min[i]];
3478
12.7k
        au1_min_max_qp[2 * P_PIC + 1] = gau1_h264_to_mpeg2_qmap[ps_cfg->au4_p_qp_max[i]];
3479
3480
12.7k
        au1_min_max_qp[2 * B_PIC] = gau1_h264_to_mpeg2_qmap[ps_cfg->au4_b_qp_min[i]];
3481
12.7k
        au1_min_max_qp[2 * B_PIC + 1] = gau1_h264_to_mpeg2_qmap[ps_cfg->au4_b_qp_max[i]];
3482
3483
12.7k
        switch(ps_cfg->e_rc_mode)
3484
12.7k
        {
3485
3.33k
            case IVE_RC_STORAGE:
3486
3.33k
            {
3487
3.33k
                ps_codec->s_rate_control.e_rc_type = VBR_STORAGE;
3488
3.33k
                break;
3489
0
            }
3490
6.18k
            case IVE_RC_CBR_NON_LOW_DELAY:
3491
6.18k
            {
3492
6.18k
                ps_codec->s_rate_control.e_rc_type = CBR_NLDRC;
3493
6.18k
                break;
3494
0
            }
3495
0
            case IVE_RC_CBR_LOW_DELAY:
3496
0
            {
3497
0
                ps_codec->s_rate_control.e_rc_type = CBR_LDRC;
3498
0
                break;
3499
0
            }
3500
3.20k
            case IVE_RC_NONE:
3501
3.20k
            {
3502
3.20k
                ps_codec->s_rate_control.e_rc_type = CONST_QP;
3503
3.20k
                break;
3504
0
            }
3505
0
            default:
3506
0
            {
3507
0
                break;
3508
0
            }
3509
12.7k
        }
3510
3511
50.9k
        for(i = 0; i < MAX_NUM_SPATIAL_LAYERS; i++)
3512
38.1k
        {
3513
38.1k
            isvce_rc_init(ps_codec->s_rate_control.apps_rate_control_api[i],
3514
38.1k
                          ps_codec->s_rate_control.pps_frame_time,
3515
38.1k
                          ps_codec->s_rate_control.pps_time_stamp,
3516
38.1k
                          ps_codec->s_rate_control.pps_pd_frm_rate, ps_cfg->u4_max_framerate,
3517
38.1k
                          ps_cfg->u4_src_frame_rate, ps_cfg->u4_tgt_frame_rate,
3518
38.1k
                          ps_codec->s_rate_control.e_rc_type, ps_cfg->au4_target_bitrate[i],
3519
38.1k
                          ps_cfg->au4_max_bitrate[i], ps_cfg->au4_vbv_buffer_delay[i],
3520
38.1k
                          ps_cfg->u4_i_frm_interval, ps_cfg->u4_num_bframes + 1, au1_init_qp,
3521
38.1k
                          ps_cfg->u4_num_bframes + 2, au1_min_max_qp, ps_cfg->u4_max_level);
3522
38.1k
        }
3523
12.7k
    }
3524
3525
12.7k
    return IH264E_SUCCESS;
3526
12.7k
}
3527
3528
/**
3529
*******************************************************************************
3530
*
3531
* @brief
3532
*  Codec level initializations
3533
*
3534
* @par Description:
3535
*  Initializes the codec with parameters that needs to be set before encoding
3536
*  first frame
3537
*
3538
* @param[in] ps_codec
3539
*  Pointer to codec context
3540
*
3541
* @param[in] ps_inp_buf
3542
*  Pointer to input buffer context
3543
*
3544
* @returns  error_status
3545
*
3546
* @remarks
3547
*
3548
*
3549
*******************************************************************************
3550
*/
3551
IH264E_ERROR_T isvce_codec_init(isvce_codec_t *ps_codec)
3552
9.84k
{
3553
9.84k
    isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
3554
9.84k
    enc_loop_fxns_t *ps_enc_loop_fxns = &ps_isa_dependent_fxns->s_enc_loop_fxns;
3555
9.84k
    WORD8 i;
3556
3557
    /********************************************************************
3558
     *                     INITIALIZE CODEC CONTEXT                     *
3559
     ********************************************************************/
3560
    /* encoder presets */
3561
9.84k
    if(ps_codec->s_cfg.u4_enc_speed_preset != IVE_CONFIG)
3562
8.11k
    {
3563
8.11k
        if(ps_codec->s_cfg.u4_enc_speed_preset == IVE_SLOWEST)
3564
809
        { /* high quality */
3565
            /* enable diamond search */
3566
809
            ps_codec->s_cfg.u4_me_speed_preset = DMND_SRCH;
3567
809
            ps_codec->s_cfg.u4_enable_fast_sad = 0;
3568
3569
            /* disable intra 4x4 */
3570
809
            ps_codec->s_cfg.u4_enable_intra_4x4 = 1;
3571
809
            if(!FORCE_FAST_INTRA4X4)
3572
809
            {
3573
809
                ps_enc_loop_fxns->apf_luma_energy_compaction[1] =
3574
809
                    isvce_code_luma_intra_macroblock_4x4_rdopt_on;
3575
809
            }
3576
3577
            /* sub pel off */
3578
809
            ps_codec->s_cfg.u4_enable_hpel = 1;
3579
3580
            /* disabled intra inter gating in Inter slices */
3581
809
            ps_codec->u4_inter_gate = 0;
3582
809
        }
3583
7.30k
        else if(ps_codec->s_cfg.u4_enc_speed_preset == IVE_NORMAL)
3584
924
        { /* normal */
3585
            /* enable diamond search */
3586
924
            ps_codec->s_cfg.u4_me_speed_preset = DMND_SRCH;
3587
924
            ps_codec->s_cfg.u4_enable_fast_sad = 0;
3588
3589
            /* disable intra 4x4 */
3590
924
            ps_codec->s_cfg.u4_enable_intra_4x4 = 1;
3591
3592
            /* sub pel off */
3593
924
            ps_codec->s_cfg.u4_enable_hpel = 1;
3594
3595
            /* disabled intra inter gating in Inter slices */
3596
924
            ps_codec->u4_inter_gate = 0;
3597
924
        }
3598
6.38k
        else if(ps_codec->s_cfg.u4_enc_speed_preset == IVE_FAST)
3599
692
        { /* normal */
3600
            /* enable diamond search */
3601
692
            ps_codec->s_cfg.u4_me_speed_preset = DMND_SRCH;
3602
692
            ps_codec->s_cfg.u4_enable_fast_sad = 0;
3603
3604
            /* disable intra 4x4 */
3605
692
            ps_codec->s_cfg.u4_enable_intra_4x4 = 0;
3606
3607
            /* sub pel off */
3608
692
            ps_codec->s_cfg.u4_enable_hpel = 1;
3609
3610
            /* disabled intra inter gating in Inter slices */
3611
692
            ps_codec->u4_inter_gate = 1;
3612
692
        }
3613
5.69k
        else if(ps_codec->s_cfg.u4_enc_speed_preset == IVE_HIGH_SPEED)
3614
364
        { /* fast */
3615
            /* enable diamond search */
3616
364
            ps_codec->s_cfg.u4_me_speed_preset = DMND_SRCH;
3617
364
            ps_codec->s_cfg.u4_enable_fast_sad = 0;
3618
3619
            /* disable intra 4x4 */
3620
364
            ps_codec->s_cfg.u4_enable_intra_4x4 = 0;
3621
3622
            /* sub pel off */
3623
364
            ps_codec->s_cfg.u4_enable_hpel = 0;
3624
3625
            /* disabled intra inter gating in Inter slices */
3626
364
            ps_codec->u4_inter_gate = 0;
3627
364
        }
3628
5.32k
        else if(ps_codec->s_cfg.u4_enc_speed_preset == IVE_FASTEST)
3629
5.32k
        { /* fastest */
3630
            /* enable diamond search */
3631
5.32k
            ps_codec->s_cfg.u4_me_speed_preset = DMND_SRCH;
3632
3633
            /* disable intra 4x4 */
3634
5.32k
            ps_codec->s_cfg.u4_enable_intra_4x4 = 0;
3635
3636
            /* sub pel off */
3637
5.32k
            ps_codec->s_cfg.u4_enable_hpel = 0;
3638
3639
            /* disabled intra inter gating in Inter slices */
3640
5.32k
            ps_codec->u4_inter_gate = 1;
3641
5.32k
        }
3642
8.11k
    }
3643
3644
    /*****************************************************************
3645
     * Initialize AIR inside codec
3646
     *****************************************************************/
3647
9.84k
    if(IVE_AIR_MODE_NONE != ps_codec->s_cfg.e_air_mode)
3648
0
    {
3649
0
        isvce_init_air_map(ps_codec);
3650
3651
0
        ps_codec->i4_air_pic_cnt = -1;
3652
0
    }
3653
3654
9.84k
    {
3655
9.84k
        WORD32 i4_err_code = isvce_rc_init_wrapper(ps_codec);
3656
3657
9.84k
        if(IH264E_SUCCESS != i4_err_code)
3658
63
        {
3659
63
            return i4_err_code;
3660
63
        }
3661
9.84k
    }
3662
3663
    /* recon stride */
3664
9.78k
    ps_codec->i4_rec_strd = ALIGN16(ps_codec->s_cfg.u4_max_wd) + PAD_WD;
3665
3666
    /* max ref and reorder cnt */
3667
9.78k
    ps_codec->i4_ref_buf_cnt = ps_codec->s_cfg.u4_max_ref_cnt + ps_codec->s_cfg.u4_max_reorder_cnt;
3668
9.78k
    ps_codec->i4_ref_buf_cnt += MAX_CTXT_SETS;
3669
9.78k
    ps_codec->i4_ref_buf_cnt += ps_codec->s_cfg.s_svc_params.u1_num_temporal_layers;
3670
3671
9.78k
    DEBUG_HISTOGRAM_INIT();
3672
3673
    /* Init dependecy vars */
3674
9.78k
    ps_codec->i4_last_inp_buff_received = 0;
3675
3676
    /* At codec start no IDR is pending */
3677
9.78k
    ps_codec->i4_pending_idr_flag = 0;
3678
3679
22.6k
    for(i = 0; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers - 1; i++)
3680
12.8k
    {
3681
12.8k
        ps_codec->au4_constrained_intra_pred[i] = 1;
3682
12.8k
    }
3683
3684
9.78k
    ps_codec->au4_constrained_intra_pred[ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers - 1] =
3685
9.78k
        0;
3686
3687
9.78k
    return IH264E_SUCCESS;
3688
9.84k
}
3689
3690
/**
3691
*******************************************************************************
3692
*
3693
* @brief update encoder configuration parameters
3694
*
3695
* @par Description:
3696
*  updates encoder configuration parameters from the given config set.
3697
*  Initialize/reinitialize codec parameters according to new configurations.
3698
*
3699
* @param[in] ps_codec
3700
*  Pointer to codec context
3701
*
3702
* @param[in] ps_cfg
3703
*  Pointer to config param set
3704
*
3705
* @remarks none
3706
*
3707
*******************************************************************************
3708
*/
3709
IH264E_ERROR_T isvce_codec_update_config(isvce_codec_t *ps_codec, isvce_cfg_params_t *ps_cfg)
3710
85.4k
{
3711
    /* config params */
3712
85.4k
    isvce_cfg_params_t *ps_curr_cfg = &ps_codec->s_cfg;
3713
3714
    /* error status */
3715
85.4k
    IH264E_ERROR_T err = IH264E_SUCCESS;
3716
3717
    /* temp var */
3718
85.4k
    UWORD32 u4_init_rc = 0;
3719
3720
85.4k
    WORD8 i;
3721
3722
    /***********************/
3723
    /* UPDATE CODEC CONFIG */
3724
    /***********************/
3725
85.4k
    if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_DIMENSIONS)
3726
1.52k
    {
3727
1.52k
        UWORD32 wd_aln = ALIGN16(ps_cfg->u4_wd);
3728
1.52k
        UWORD32 ht_aln = ALIGN16(ps_cfg->u4_ht);
3729
3730
1.52k
        if(ps_curr_cfg->u4_wd != wd_aln || ps_curr_cfg->u4_ht != ht_aln ||
3731
1.52k
           ps_curr_cfg->u4_disp_wd != ps_cfg->u4_disp_wd ||
3732
1.52k
           ps_curr_cfg->u4_disp_ht != ps_cfg->u4_disp_ht)
3733
0
        {
3734
0
            ps_curr_cfg->u4_wd = wd_aln;
3735
0
            ps_curr_cfg->u4_ht = ht_aln;
3736
3737
0
            ps_curr_cfg->u4_disp_wd = ps_cfg->u4_disp_wd;
3738
0
            ps_curr_cfg->u4_disp_ht = ps_cfg->u4_disp_ht;
3739
3740
0
            ps_curr_cfg->i4_wd_mbs = ps_curr_cfg->u4_wd >> 4;
3741
0
            ps_curr_cfg->i4_ht_mbs = ps_curr_cfg->u4_ht >> 4;
3742
3743
0
            ps_codec->i4_rec_strd = ALIGN16(ps_cfg->u4_wd) + PAD_WD;
3744
3745
            /* If number of MBs in a frame changes the air map also changes.
3746
             * Hence recompute air map also reset air pic cnt */
3747
0
            if(ps_codec->s_cfg.e_air_mode != IVE_AIR_MODE_NONE)
3748
0
            {
3749
                /* re-init the air map */
3750
0
                isvce_init_air_map(ps_codec);
3751
3752
                /* reset air counter */
3753
0
                ps_codec->i4_air_pic_cnt = -1;
3754
0
            }
3755
3756
            /* initialize mv bank buffer manager */
3757
0
            err = isvce_svc_au_data_mgr_add_bufs(ps_codec);
3758
0
            if(err != IH264E_SUCCESS) return err;
3759
3760
            /* initialize ref bank buffer manager */
3761
0
            err = isvce_svc_au_buf_mgr_add_bufs(ps_codec);
3762
0
            if(err != IH264E_SUCCESS) return err;
3763
3764
            /* since dimension changed, start new sequence by forcing IDR */
3765
0
            ps_codec->force_curr_frame_type = IV_IDR_FRAME;
3766
3767
            /* in case dimension changes, we need to reinitialize RC as the
3768
             * old model shall not fit further */
3769
0
            u4_init_rc = 1;
3770
3771
            /* when the dimension changes, the header needs to be regenerated */
3772
0
            ps_codec->i4_gen_header = 1;
3773
0
        }
3774
1.52k
    }
3775
83.8k
    else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_FRAMERATE)
3776
4.29k
    {
3777
4.29k
        UWORD32 u4_src_ticks, u4_tgt_ticks;
3778
3779
4.29k
        u4_src_ticks = ih264e_frame_time_get_src_ticks(ps_codec->s_rate_control.pps_frame_time);
3780
3781
4.29k
        u4_tgt_ticks = ih264e_frame_time_get_tgt_ticks(ps_codec->s_rate_control.pps_frame_time);
3782
3783
        /* Change frame rate */
3784
4.29k
        if(ps_codec->s_cfg.u4_src_frame_rate != ps_cfg->u4_src_frame_rate * 1000)
3785
4.27k
        {
3786
4.27k
            ps_codec->s_cfg.u4_src_frame_rate = ps_cfg->u4_src_frame_rate * 1000;
3787
3788
4.27k
            ih264e_frame_time_update_src_frame_rate(ps_codec->s_rate_control.pps_frame_time,
3789
4.27k
                                                    ps_codec->s_cfg.u4_src_frame_rate);
3790
3791
4.27k
            ih264_time_stamp_update_frame_rate(ps_codec->s_rate_control.pps_time_stamp,
3792
4.27k
                                               ps_codec->s_cfg.u4_src_frame_rate);
3793
3794
14.1k
            for(i = 0; i < ps_cfg->s_svc_params.u1_num_spatial_layers; i++)
3795
9.88k
            {
3796
9.88k
                irc_change_frame_rate(ps_codec->s_rate_control.apps_rate_control_api[i],
3797
9.88k
                                      ps_codec->s_cfg.u4_src_frame_rate, u4_src_ticks,
3798
9.88k
                                      u4_tgt_ticks);
3799
9.88k
            }
3800
4.27k
        }
3801
3802
4.29k
        if(ps_codec->s_cfg.u4_tgt_frame_rate != ps_cfg->u4_tgt_frame_rate * 1000)
3803
4.27k
        {
3804
4.27k
            ps_codec->s_cfg.u4_tgt_frame_rate = ps_cfg->u4_tgt_frame_rate * 1000;
3805
3806
4.27k
            ih264e_frame_time_update_tgt_frame_rate(ps_codec->s_rate_control.pps_frame_time,
3807
4.27k
                                                    ps_codec->s_cfg.u4_tgt_frame_rate);
3808
3809
14.1k
            for(i = 0; i < ps_cfg->s_svc_params.u1_num_spatial_layers; i++)
3810
9.88k
            {
3811
9.88k
                irc_change_frame_rate(ps_codec->s_rate_control.apps_rate_control_api[i],
3812
9.88k
                                      ps_codec->s_cfg.u4_src_frame_rate, u4_src_ticks,
3813
9.88k
                                      u4_tgt_ticks);
3814
3815
9.88k
                irc_change_frm_rate_for_bit_alloc(ps_codec->s_rate_control.apps_rate_control_api[i],
3816
9.88k
                                                  ps_codec->s_cfg.u4_tgt_frame_rate);
3817
9.88k
            }
3818
4.27k
        }
3819
4.29k
    }
3820
79.5k
    else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_BITRATE)
3821
4.83k
    {
3822
19.3k
        for(i = 0; i < MAX_NUM_SPATIAL_LAYERS; i++)
3823
14.4k
        {
3824
14.4k
            if(ps_curr_cfg->au4_target_bitrate[i] != ps_cfg->au4_target_bitrate[i])
3825
11.1k
            {
3826
11.1k
                if(IVE_RC_NONE != ps_curr_cfg->e_rc_mode)
3827
7.68k
                    irc_change_avg_bit_rate(ps_codec->s_rate_control.apps_rate_control_api[i],
3828
7.68k
                                            ps_cfg->au4_target_bitrate[i]);
3829
3830
11.1k
                ps_curr_cfg->au4_target_bitrate[i] = ps_cfg->au4_target_bitrate[i];
3831
11.1k
            }
3832
14.4k
        }
3833
4.83k
    }
3834
74.7k
    else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_FRAMETYPE)
3835
918
    {
3836
918
        switch(ps_cfg->e_frame_type)
3837
918
        {
3838
0
            case IV_I_FRAME:
3839
0
                ps_codec->force_curr_frame_type = IV_I_FRAME;
3840
0
                break;
3841
3842
918
            case IV_IDR_FRAME:
3843
918
                ps_codec->force_curr_frame_type = IV_IDR_FRAME;
3844
918
                break;
3845
3846
0
            case IV_P_FRAME:
3847
0
            default:
3848
0
                break;
3849
918
        }
3850
918
    }
3851
73.8k
    else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_ME_PARAMS)
3852
2.83k
    {
3853
2.83k
        if(ps_curr_cfg->u4_enc_speed_preset == IVE_CONFIG)
3854
1.13k
        {
3855
1.13k
            ps_codec->s_cfg.u4_enable_hpel = ps_cfg->u4_enable_hpel;
3856
1.13k
            ps_codec->s_cfg.u4_enable_fast_sad = ps_cfg->u4_enable_fast_sad;
3857
1.13k
            ps_codec->s_cfg.u4_me_speed_preset = ps_cfg->u4_me_speed_preset;
3858
1.13k
            ps_codec->s_cfg.u4_enable_qpel = ps_cfg->u4_enable_qpel;
3859
1.13k
        }
3860
1.69k
        else if(ps_curr_cfg->u4_enc_speed_preset == IVE_FASTEST)
3861
118
        {
3862
118
            ps_codec->s_cfg.u4_enable_fast_sad = ps_cfg->u4_enable_fast_sad;
3863
118
        }
3864
2.83k
        ps_codec->s_cfg.u4_srch_rng_x = ps_cfg->u4_srch_rng_x;
3865
2.83k
        ps_codec->s_cfg.u4_srch_rng_y = ps_cfg->u4_srch_rng_y;
3866
3867
2.83k
        if(ps_codec->s_cfg.u4_enable_alt_ref != ps_cfg->u4_enable_alt_ref)
3868
0
        {
3869
0
            ps_codec->s_cfg.u4_enable_alt_ref = ps_cfg->u4_enable_alt_ref;
3870
0
            ps_codec->u4_is_curr_frm_ref = 1;
3871
0
        }
3872
2.83k
    }
3873
71.0k
    else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_IPE_PARAMS)
3874
4.93k
    {
3875
4.93k
        ps_curr_cfg->u4_enc_speed_preset = ps_cfg->u4_enc_speed_preset;
3876
3877
4.93k
        if(ps_curr_cfg->u4_enc_speed_preset == IVE_SLOWEST)
3878
810
        {
3879
810
            isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
3880
810
            enc_loop_fxns_t *ps_enc_loop_fxns = &ps_isa_dependent_fxns->s_enc_loop_fxns;
3881
3882
            /* enable diamond search */
3883
810
            ps_curr_cfg->u4_me_speed_preset = DMND_SRCH;
3884
810
            ps_curr_cfg->u4_enable_fast_sad = 0;
3885
3886
            /* disable intra 4x4 */
3887
810
            ps_curr_cfg->u4_enable_intra_4x4 = 1;
3888
810
            ps_enc_loop_fxns->apf_luma_energy_compaction[1] =
3889
810
                isvce_code_luma_intra_macroblock_4x4_rdopt_on;
3890
3891
            /* sub pel off */
3892
810
            ps_curr_cfg->u4_enable_hpel = 1;
3893
3894
            /* disabled intra inter gating in Inter slices */
3895
810
            ps_codec->u4_inter_gate = 0;
3896
810
        }
3897
4.12k
        else if(ps_curr_cfg->u4_enc_speed_preset == IVE_NORMAL)
3898
924
        { /* normal */
3899
            /* enable diamond search */
3900
924
            ps_curr_cfg->u4_me_speed_preset = DMND_SRCH;
3901
924
            ps_curr_cfg->u4_enable_fast_sad = 0;
3902
3903
            /* disable intra 4x4 */
3904
924
            ps_curr_cfg->u4_enable_intra_4x4 = 1;
3905
3906
            /* sub pel off */
3907
924
            ps_curr_cfg->u4_enable_hpel = 1;
3908
3909
            /* disabled intra inter gating in Inter slices */
3910
924
            ps_codec->u4_inter_gate = 0;
3911
924
        }
3912
3.20k
        else if(ps_curr_cfg->u4_enc_speed_preset == IVE_FAST)
3913
693
        { /* normal */
3914
            /* enable diamond search */
3915
693
            ps_curr_cfg->u4_me_speed_preset = DMND_SRCH;
3916
693
            ps_curr_cfg->u4_enable_fast_sad = 0;
3917
3918
            /* disable intra 4x4 */
3919
693
            ps_curr_cfg->u4_enable_intra_4x4 = 0;
3920
3921
            /* sub pel off */
3922
693
            ps_curr_cfg->u4_enable_hpel = 1;
3923
3924
            /* disabled intra inter gating in Inter slices */
3925
693
            ps_codec->u4_inter_gate = 1;
3926
693
        }
3927
2.50k
        else if(ps_curr_cfg->u4_enc_speed_preset == IVE_HIGH_SPEED)
3928
366
        { /* fast */
3929
            /* enable diamond search */
3930
366
            ps_curr_cfg->u4_me_speed_preset = DMND_SRCH;
3931
366
            ps_curr_cfg->u4_enable_fast_sad = 0;
3932
3933
            /* disable intra 4x4 */
3934
366
            ps_curr_cfg->u4_enable_intra_4x4 = 0;
3935
3936
            /* sub pel off */
3937
366
            ps_curr_cfg->u4_enable_hpel = 0;
3938
3939
            /* disabled intra inter gating in Inter slices */
3940
366
            ps_codec->u4_inter_gate = 0;
3941
366
        }
3942
2.14k
        else if(ps_curr_cfg->u4_enc_speed_preset == IVE_FASTEST)
3943
397
        { /* fastest */
3944
            /* enable diamond search */
3945
397
            ps_curr_cfg->u4_me_speed_preset = DMND_SRCH;
3946
            // u4_num_layers = 4;
3947
3948
            /* disable intra 4x4 */
3949
397
            ps_curr_cfg->u4_enable_intra_4x4 = 0;
3950
3951
            /* sub pel off */
3952
397
            ps_curr_cfg->u4_enable_hpel = 0;
3953
3954
            /* disabled intra inter gating in Inter slices */
3955
397
            ps_codec->u4_inter_gate = 1;
3956
397
        }
3957
1.74k
        else if(ps_curr_cfg->u4_enc_speed_preset == IVE_CONFIG)
3958
1.74k
        {
3959
1.74k
            ps_curr_cfg->u4_enable_intra_4x4 = ps_cfg->u4_enable_intra_4x4;
3960
1.74k
        }
3961
4.93k
    }
3962
66.0k
    else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_GOP_PARAMS)
3963
4.93k
    {
3964
4.93k
        if(ps_curr_cfg->u4_i_frm_interval != ps_cfg->u4_i_frm_interval)
3965
4.92k
        {
3966
4.92k
            ps_curr_cfg->u4_i_frm_interval = ps_cfg->u4_i_frm_interval;
3967
3968
            /* reset air counter */
3969
4.92k
            ps_codec->i4_air_pic_cnt = -1;
3970
3971
            /* re-init air map */
3972
4.92k
            isvce_init_air_map(ps_codec);
3973
3974
            /*Effect intra frame interval change*/
3975
16.3k
            for(i = 0; i < ps_cfg->s_svc_params.u1_num_spatial_layers; i++)
3976
11.3k
            {
3977
11.3k
                irc_change_intra_frm_int_call(ps_codec->s_rate_control.apps_rate_control_api[i],
3978
11.3k
                                              ps_curr_cfg->u4_i_frm_interval);
3979
11.3k
            }
3980
4.92k
        }
3981
3982
4.93k
        ps_curr_cfg->u4_idr_frm_interval = ps_cfg->u4_idr_frm_interval;
3983
4.93k
    }
3984
61.1k
    else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_DEBLOCK_PARAMS)
3985
4.93k
    {
3986
4.93k
        ps_curr_cfg->u4_disable_deblock_level = ps_cfg->u4_disable_deblock_level;
3987
4.93k
    }
3988
56.2k
    else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_QP)
3989
1.92k
    {
3990
6.54k
        for(i = 0; i < ps_cfg->s_svc_params.u1_num_spatial_layers; i++)
3991
4.61k
        {
3992
4.61k
            UWORD8 au1_init_qp[MAX_PIC_TYPE];
3993
4.61k
            UWORD8 au1_min_max_qp[2 * MAX_PIC_TYPE];
3994
4.61k
            UWORD8 au1_min_max_avc_qp[2 * MAX_PIC_TYPE];
3995
3996
4.61k
            ps_codec->s_cfg.au4_i_qp_max[i] = ps_cfg->au4_i_qp_max[i];
3997
4.61k
            ps_codec->s_cfg.au4_i_qp_min[i] = ps_cfg->au4_i_qp_min[i];
3998
4.61k
            ps_codec->s_cfg.au4_i_qp[i] = ps_cfg->au4_i_qp[i];
3999
4000
4.61k
            ps_codec->s_cfg.au4_p_qp_max[i] = ps_cfg->au4_p_qp_max[i];
4001
4.61k
            ps_codec->s_cfg.au4_p_qp_min[i] = ps_cfg->au4_p_qp_min[i];
4002
4.61k
            ps_codec->s_cfg.au4_p_qp[i] = ps_cfg->au4_p_qp[i];
4003
4004
4.61k
            ps_codec->s_cfg.au4_b_qp_max[i] = ps_cfg->au4_b_qp_max[i];
4005
4.61k
            ps_codec->s_cfg.au4_b_qp_min[i] = ps_cfg->au4_b_qp_min[i];
4006
4.61k
            ps_codec->s_cfg.au4_b_qp[i] = ps_cfg->au4_b_qp[i];
4007
4008
            /* update rc lib with modified qp */
4009
4.61k
            au1_init_qp[0] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_i_qp[i]];
4010
4.61k
            au1_init_qp[1] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_p_qp[i]];
4011
4.61k
            au1_init_qp[2] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_b_qp[i]];
4012
4013
4.61k
            irc_change_init_qp(ps_codec->s_rate_control.apps_rate_control_api[i], au1_init_qp);
4014
4015
4.61k
            au1_min_max_qp[2 * I_PIC] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_i_qp_min[i]];
4016
4.61k
            au1_min_max_qp[2 * I_PIC + 1] =
4017
4.61k
                gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_i_qp_max[i]];
4018
4019
4.61k
            au1_min_max_qp[2 * P_PIC] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_p_qp_min[i]];
4020
4.61k
            au1_min_max_qp[2 * P_PIC + 1] =
4021
4.61k
                gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_p_qp_max[i]];
4022
4023
4.61k
            au1_min_max_qp[2 * B_PIC] = gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_b_qp_min[i]];
4024
4.61k
            au1_min_max_qp[2 * B_PIC + 1] =
4025
4.61k
                gau1_h264_to_mpeg2_qmap[ps_codec->s_cfg.au4_b_qp_max[i]];
4026
4027
4.61k
            au1_min_max_avc_qp[2 * I_PIC] = ps_codec->s_cfg.au4_i_qp_min[i];
4028
4.61k
            au1_min_max_avc_qp[2 * I_PIC + 1] = ps_codec->s_cfg.au4_i_qp_max[i];
4029
4030
4.61k
            au1_min_max_avc_qp[2 * P_PIC] = ps_codec->s_cfg.au4_p_qp_min[i];
4031
4.61k
            au1_min_max_avc_qp[2 * P_PIC + 1] = ps_codec->s_cfg.au4_p_qp_max[i];
4032
4033
4.61k
            au1_min_max_avc_qp[2 * B_PIC] = ps_codec->s_cfg.au4_b_qp_min[i];
4034
4.61k
            au1_min_max_avc_qp[2 * B_PIC + 1] = ps_codec->s_cfg.au4_b_qp_max[i];
4035
4036
4.61k
            irc_change_qp_constraints(ps_codec->s_rate_control.apps_rate_control_api[i],
4037
4.61k
                                      au1_min_max_qp, au1_min_max_avc_qp);
4038
4.61k
        }
4039
1.92k
    }
4040
54.2k
    else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_ENC_MODE)
4041
4.93k
    {
4042
4.93k
        ps_codec->s_cfg.e_enc_mode = ps_cfg->e_enc_mode;
4043
4044
4.93k
        if(ps_codec->s_cfg.e_enc_mode == IVE_ENC_MODE_HEADER)
4045
4.93k
        {
4046
4.93k
            ps_codec->i4_header_mode = 1;
4047
4.93k
            ps_codec->s_cfg.e_enc_mode = IVE_ENC_MODE_PICTURE;
4048
4.93k
        }
4049
0
        else
4050
0
        {
4051
0
            ps_codec->i4_header_mode = 0;
4052
0
        }
4053
4.93k
    }
4054
49.3k
    else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_VBV_PARAMS &&
4055
49.3k
            IVE_RC_NONE != ps_codec->s_cfg.e_rc_mode)
4056
3.31k
    {
4057
11.0k
        for(i = 0; i < ps_cfg->s_svc_params.u1_num_spatial_layers; i++)
4058
7.75k
        {
4059
7.75k
            ps_codec->s_cfg.au4_vbv_buffer_delay[i] = ps_cfg->au4_vbv_buffer_delay[i];
4060
7.75k
        }
4061
        // irc_change_buffer_delay(ps_codec->s_rate_control.pps_rate_control_api,
4062
        // ps_codec->s_cfg.u4_vbv_buffer_delay);
4063
4064
        // TODO: remove this when the support for changing buffer dynamically
4065
        // is yet to be added.
4066
3.31k
        u4_init_rc = 1;
4067
3.31k
    }
4068
46.0k
    else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_AIR_PARAMS)
4069
4.93k
    {
4070
4.93k
        if(ps_curr_cfg->e_air_mode != ps_cfg->e_air_mode ||
4071
4.93k
           ps_curr_cfg->u4_air_refresh_period != ps_cfg->u4_air_refresh_period)
4072
4.91k
        {
4073
4.91k
            ps_curr_cfg->e_air_mode = ps_cfg->e_air_mode;
4074
4.91k
            ps_curr_cfg->u4_air_refresh_period = ps_cfg->u4_air_refresh_period;
4075
4076
4.91k
            isvce_init_air_map(ps_codec);
4077
4078
            /* reset air counter */
4079
4.91k
            ps_codec->i4_air_pic_cnt = -1;
4080
4.91k
        }
4081
4.93k
    }
4082
41.0k
    else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_PROFILE_PARAMS)
4083
4.93k
    {
4084
4.93k
        ps_codec->s_cfg.e_profile = ps_cfg->e_profile;
4085
4.93k
        ps_codec->s_cfg.u4_entropy_coding_mode = ps_cfg->u4_entropy_coding_mode;
4086
4.93k
    }
4087
36.1k
    else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_NUM_CORES)
4088
4.93k
    {
4089
4.93k
        ps_codec->s_cfg.u4_num_cores = ps_cfg->u4_num_cores;
4090
4.93k
    }
4091
31.2k
    else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_VUI_PARAMS)
4092
4.93k
    {
4093
4.93k
        ps_codec->s_cfg.s_vui = ps_cfg->s_vui;
4094
4.93k
    }
4095
4096
26.2k
    else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_SEI_MDCV_PARAMS)
4097
4.93k
    {
4098
4.93k
        ps_codec->s_cfg.s_sei.u1_sei_mdcv_params_present_flag =
4099
4.93k
            ps_cfg->s_sei.u1_sei_mdcv_params_present_flag;
4100
4.93k
        ps_codec->s_cfg.s_sei.s_sei_mdcv_params = ps_cfg->s_sei.s_sei_mdcv_params;
4101
4.93k
    }
4102
21.3k
    else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_SEI_CLL_PARAMS)
4103
4.93k
    {
4104
4.93k
        ps_codec->s_cfg.s_sei.u1_sei_cll_params_present_flag =
4105
4.93k
            ps_cfg->s_sei.u1_sei_cll_params_present_flag;
4106
4.93k
        ps_codec->s_cfg.s_sei.s_sei_cll_params = ps_cfg->s_sei.s_sei_cll_params;
4107
4.93k
    }
4108
16.4k
    else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_SEI_AVE_PARAMS)
4109
4.93k
    {
4110
4.93k
        ps_codec->s_cfg.s_sei.u1_sei_ave_params_present_flag =
4111
4.93k
            ps_cfg->s_sei.u1_sei_ave_params_present_flag;
4112
4.93k
        ps_codec->s_cfg.s_sei.s_sei_ave_params = ps_cfg->s_sei.s_sei_ave_params;
4113
4.93k
    }
4114
11.4k
    else if(ps_cfg->e_cmd == ISVCE_CMD_CTL_SET_SEI_CCV_PARAMS)
4115
4.93k
    {
4116
4.93k
        ps_codec->s_cfg.s_sei.u1_sei_ccv_params_present_flag =
4117
4.93k
            ps_cfg->s_sei.u1_sei_ccv_params_present_flag;
4118
4.93k
        ps_codec->s_cfg.s_sei.s_sei_ccv_params = ps_cfg->s_sei.s_sei_ccv_params;
4119
4.93k
    }
4120
4121
    /* reset RC model */
4122
85.4k
    if(u4_init_rc)
4123
3.31k
    {
4124
3.31k
        err = isvce_rc_init_wrapper(ps_codec);
4125
3.31k
    }
4126
4127
85.4k
    return err;
4128
85.4k
}
4129
4130
static FORCEINLINE void isvce_change_rc_init_qp(void *pv_rate_control_api, UWORD8 u1_qp)
4131
0
{
4132
0
    UWORD8 au1_pic_qps[MAX_PIC_TYPE];
4133
0
    WORD32 i;
4134
4135
0
    for(i = 0; i < MAX_PIC_TYPE; i++)
4136
0
    {
4137
0
        au1_pic_qps[i] = gau1_h264_to_mpeg2_qmap[CLIP3(MIN_H264_QP, MAX_H264_QP, u1_qp + i)];
4138
0
    }
4139
4140
0
    irc_change_init_qp(pv_rate_control_api, au1_pic_qps);
4141
0
}
4142
4143
/**
4144
 *******************************************************************************
4145
 *
4146
 * @brief
4147
 *  Queues the current buffer, gets back a another buffer for encoding with
4148
 *corrent picture type
4149
 *
4150
 * @par Description:
4151
 *      This function performs 3 distinct but related functions.
4152
 *      1) Maintains an input queue [Note the the term queue donot imply a
4153
 *         first-in first-out logic here] that queues input and dequeues them so
4154
 *         that input frames can be encoded at any predetermined encoding order
4155
 *      2) Uses RC library to decide which frame must be encoded in current pass
4156
 *         and which picture type it must be encoded to.
4157
 *      3) Uses RC library to decide the QP at which current frame has to be
4158
 *         encoded
4159
 *      4) Determines if the current picture must be encoded or not based on
4160
 *         PRE-ENC skip
4161
 *
4162
 *     Input queue is used for storing input buffers till they are used for
4163
 *     encoding. This queue is maintained at ps_codec->as_inp_list. Whenever a
4164
 *     valid input comes, it is added to the end of queue. This same input is
4165
 *     added to RC queue using the identifier as ps_codec->i4_pic_cnt. Hence any
4166
 *     pic from RC can be located in the input queue easily.
4167
 *
4168
 *     The dequeue operation does not start till we have
4169
 *ps_codec->s_cfg.u4_max_num_bframes frames in the queue. THis is done in order
4170
 *to ensure that once output starts we will have a constant stream of output
4171
 *with no gaps.
4172
 *
4173
 *     THe output frame order is governed by RC library. When ever we dequeue a
4174
 *     buffer from RC library, it ensures that we will get them in encoding
4175
 *order With the output of RC library, we can use the picture id to dequeue the
4176
 *     corresponding buffer from input queue and encode it.
4177
 *
4178
 *     Condition at the end of stream.
4179
 *     -------------------------------
4180
 *      At the last valid buffer from the app, we will get ps_ive_ip->u4_is_last
4181
 *      to be set. This will the given to lib when appropriate input buffer is
4182
 *      given to encoding.
4183
 *
4184
 *      Since we have to output is not in sync with input, we will have frames
4185
 *to encode even after we recive the last vaild input buffer. Hence we have to
4186
 *      make sure that we donot queue any new buffers once we get the flag [It
4187
 *may mess up GOP ?]. This is acheived by setting
4188
 *ps_codec->i4_last_inp_buff_received to act as a permenent marker for last
4189
 *frame recived [This may not be needed, because in our current app, all buffers
4190
 *after the last are marked as last. But can we rely on that?] . Hence after
4191
 *this flgag is set no new buffers are queued.
4192
 *
4193
 * @param[in] ps_codec
4194
 *   Pointer to codec descriptor
4195
 *
4196
 * @param[in] ps_ive_ip
4197
 *   Current input buffer to the encoder
4198
 *
4199
 * @param[out] ps_inp
4200
 *   Buffer to be encoded in the current pass
4201
 *
4202
 * @returns
4203
 *   Flag indicating if we have a pre-enc skip or not
4204
 *
4205
 * @remarks
4206
 * TODO (bpic)
4207
 *  The check for null ans is last is redudent.
4208
 *  Need to see if we can remove it
4209
 *
4210
 *******************************************************************************
4211
 */
4212
WORD32 isvce_input_queue_update(isvce_codec_t *ps_codec, ive_video_encode_ip_t *ps_ive_ip,
4213
                                isvce_inp_buf_t *ps_enc_buff, WORD8 i1_layer_id)
4214
78.3k
{
4215
78.3k
    isvce_inp_buf_t *ps_inp_buf;
4216
78.3k
    picture_type_e e_pictype;
4217
78.3k
    WORD32 i4_skip;
4218
78.3k
    UWORD32 ctxt_sel, u4_pic_id, u4_pic_disp_id;
4219
78.3k
    UWORD8 u1_frame_qp = MAX_H264_QP;
4220
78.3k
    UWORD32 max_frame_bits = 0x7FFFFFFF;
4221
4222
78.3k
    WORD32 i;
4223
4224
    /*  Mark that the last input frame has been received */
4225
78.3k
    if(ps_ive_ip->u4_is_last == 1)
4226
12.4k
    {
4227
12.4k
        ps_codec->i4_last_inp_buff_received = 1;
4228
12.4k
    }
4229
4230
78.3k
    if(ps_ive_ip->s_inp_buf.apv_bufs[0] == NULL && !ps_codec->i4_last_inp_buff_received)
4231
0
    {
4232
0
        ps_enc_buff->s_inp_props.s_raw_buf.apv_bufs[0] = NULL;
4233
0
        ps_enc_buff->s_inp_props.u4_is_last = ps_ive_ip->u4_is_last;
4234
0
        return 0;
4235
0
    }
4236
4237
    /***************************************************************************
4238
     * Check for pre enc skip
4239
     *   When src and target frame rates donot match, we skip some frames to
4240
     *   maintain the relation ship between them
4241
     **************************************************************************/
4242
78.3k
    {
4243
78.3k
        WORD32 skip_src;
4244
4245
78.3k
        skip_src = isvce_update_rc_framerates(
4246
78.3k
            ps_codec->s_rate_control.apps_rate_control_api[i1_layer_id],
4247
78.3k
            ps_codec->s_rate_control.pps_pd_frm_rate, ps_codec->s_rate_control.pps_time_stamp,
4248
78.3k
            ps_codec->s_rate_control.pps_frame_time);
4249
4250
78.3k
        if(skip_src)
4251
141
        {
4252
141
            ps_enc_buff->s_inp_props.u4_is_last = ps_ive_ip->u4_is_last;
4253
141
            return 1;
4254
141
        }
4255
78.3k
    }
4256
4257
    /***************************************************************************
4258
     *Queue the input to the queue
4259
     **************************************************************************/
4260
78.2k
    ps_inp_buf = &(ps_codec->as_inp_list[ps_codec->i4_pic_cnt % SVC_MAX_NUM_INP_FRAMES]);
4261
4262
    /* copy input info. to internal structure */
4263
78.2k
    ps_inp_buf->s_inp_props.s_raw_buf = ps_ive_ip->s_inp_buf;
4264
78.2k
    ps_inp_buf->s_inp_props.u4_timestamp_low = ps_ive_ip->u4_timestamp_low;
4265
78.2k
    ps_inp_buf->s_inp_props.u4_timestamp_high = ps_ive_ip->u4_timestamp_high;
4266
78.2k
    ps_inp_buf->s_inp_props.u4_is_last = ps_ive_ip->u4_is_last;
4267
78.2k
    ps_inp_buf->s_inp_props.pv_mb_info = ps_ive_ip->pv_mb_info;
4268
78.2k
    ps_inp_buf->s_inp_props.u4_mb_info_type = ps_ive_ip->u4_mb_info_type;
4269
78.2k
    ps_inp_buf->s_inp_props.pv_pic_info = ps_ive_ip->pv_pic_info;
4270
78.2k
    ps_inp_buf->s_inp_props.u4_pic_info_type = ps_ive_ip->u4_pic_info_type;
4271
4272
78.2k
    ps_inp_buf->s_inp_props.u1_sei_ccv_params_present_flag =
4273
78.2k
        ps_codec->s_cfg.s_sei.u1_sei_ccv_params_present_flag;
4274
78.2k
    ps_inp_buf->s_inp_props.s_sei_ccv = ps_codec->s_cfg.s_sei.s_sei_ccv_params;
4275
4276
78.2k
    if(ps_inp_buf->s_inp_props.s_raw_buf.apv_bufs[0])
4277
65.7k
        isvce_svc_inp_buf_populate(ps_codec, ps_inp_buf);
4278
4279
    /***************************************************************************
4280
     * Now we should add the picture to RC stack here
4281
     **************************************************************************/
4282
    /*
4283
     * If an I frame has been requested, ask  RC to force it
4284
     * For IDR requests, we have to ask RC to force I and set IDR by our selves
4285
     * since RC Donot know about IDR. For forcing an IDR at dequeue stage we
4286
     * should record that an IDR has been requested some where. Hence we will
4287
     * store it in the u4_idr_inp_list at a position same as that of input frame
4288
     */
4289
78.2k
    {
4290
78.2k
        WORD32 i4_force_idr, i4_force_i;
4291
4292
78.2k
        i4_force_idr = (ps_codec->force_curr_frame_type == IV_IDR_FRAME);
4293
78.2k
        i4_force_idr |= !(ps_codec->i4_pic_cnt % ps_codec->s_cfg.u4_idr_frm_interval);
4294
4295
78.2k
        i4_force_i = (ps_codec->force_curr_frame_type == IV_I_FRAME);
4296
4297
78.2k
        ps_codec->i4_pending_idr_flag |= i4_force_idr;
4298
4299
78.2k
        if((ps_codec->i4_pic_cnt > 0) && (i4_force_idr || i4_force_i))
4300
9.51k
        {
4301
9.51k
            irc_force_I_frame(ps_codec->s_rate_control.apps_rate_control_api[i1_layer_id]);
4302
9.51k
        }
4303
4304
78.2k
        if(i1_layer_id == (ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers - 1))
4305
36.1k
        {
4306
36.1k
            ps_codec->force_curr_frame_type = IV_NA_FRAME;
4307
36.1k
        }
4308
78.2k
    }
4309
4310
78.2k
    irc_add_picture_to_stack(ps_codec->s_rate_control.apps_rate_control_api[i1_layer_id],
4311
78.2k
                             ps_codec->i4_pic_cnt);
4312
4313
    /* Delay */
4314
78.2k
    if(ps_codec->i4_encode_api_call_cnt < (WORD32) (ps_codec->s_cfg.u4_num_bframes))
4315
0
    {
4316
0
        ps_enc_buff->s_inp_props.s_raw_buf.apv_bufs[0] = NULL;
4317
0
        ps_enc_buff->s_inp_props.u4_is_last = 0;
4318
0
        return 0;
4319
0
    }
4320
4321
    /***************************************************************************
4322
     * Get a new pic to encode
4323
     **************************************************************************/
4324
    /* Query the picture_type */
4325
78.2k
    e_pictype =
4326
78.2k
        isvce_rc_get_picture_details(ps_codec->s_rate_control.apps_rate_control_api[i1_layer_id],
4327
78.2k
                                     (WORD32 *) (&u4_pic_id), (WORD32 *) (&u4_pic_disp_id));
4328
4329
78.2k
    switch(e_pictype)
4330
78.2k
    {
4331
26.3k
        case I_PIC:
4332
26.3k
            ps_codec->pic_type = PIC_I;
4333
26.3k
            break;
4334
51.8k
        case P_PIC:
4335
51.8k
            ps_codec->pic_type = PIC_P;
4336
51.8k
            break;
4337
0
        case B_PIC:
4338
0
            ps_codec->pic_type = PIC_B;
4339
0
            break;
4340
0
        default:
4341
0
            ps_codec->pic_type = PIC_NA;
4342
0
            ps_enc_buff->s_inp_props.s_raw_buf.apv_bufs[0] = NULL;
4343
0
            return 0;
4344
78.2k
    }
4345
4346
    /* Set IDR if it has been requested */
4347
78.2k
    if(ps_codec->pic_type == PIC_I)
4348
26.3k
    {
4349
26.3k
        ps_codec->pic_type = ps_codec->i4_pending_idr_flag ? PIC_IDR : ps_codec->pic_type;
4350
26.3k
        ps_codec->i4_pending_idr_flag = 0;
4351
26.3k
    }
4352
4353
78.2k
    if(ps_codec->s_rate_control.e_rc_type != CONST_QP && ps_codec->u1_enable_init_qp &&
4354
78.2k
       (u4_pic_id == 0 ||
4355
0
        irc_is_scenecut(ps_codec->s_rate_control.apps_rate_control_api[i1_layer_id])))
4356
0
    {
4357
0
        DOUBLE d_bpp;
4358
4359
0
        svc_rc_utils_ctxt_t *ps_svc_rc_utils = &ps_codec->s_rate_control.s_rc_utils;
4360
4361
0
        UWORD32 u4_src_fps = ps_codec->s_cfg.u4_src_frame_rate / 1000;
4362
0
        UWORD32 u4_wd = ps_inp_buf->as_layer_yuv_buf_props[i1_layer_id].u4_width;
4363
0
        UWORD32 u4_ht = ps_inp_buf->as_layer_yuv_buf_props[i1_layer_id].u4_height;
4364
0
        DOUBLE d_gpp =
4365
0
            isvce_compute_gpp(ps_svc_rc_utils, &ps_inp_buf->as_layer_yuv_buf_props[i1_layer_id]);
4366
4367
0
        d_bpp = ((DOUBLE) irc_get_vbv_buf_size(
4368
0
                     ps_codec->s_rate_control.apps_rate_control_api[i1_layer_id]) /
4369
0
                 10.) /
4370
0
                ((DOUBLE) (u4_src_fps * u4_wd * u4_ht));
4371
4372
0
        u1_frame_qp = (UWORD8) irc_get_frame_level_init_qp(
4373
0
            ps_codec->s_rate_control.apps_rate_control_api[i1_layer_id],
4374
0
            ps_codec->s_rate_control.e_rc_type, e_pictype, d_bpp, d_gpp);
4375
4376
0
        isvce_change_rc_init_qp(ps_codec->s_rate_control.apps_rate_control_api[i1_layer_id],
4377
0
                                u1_frame_qp);
4378
4379
0
        ps_codec->au4_frame_qp[i1_layer_id] = u1_frame_qp;
4380
0
    }
4381
78.2k
    else
4382
78.2k
    {
4383
        /* Get current frame Qp */
4384
78.2k
        u1_frame_qp = (UWORD8) irc_get_frame_level_qp(
4385
78.2k
            ps_codec->s_rate_control.apps_rate_control_api[i1_layer_id], e_pictype, max_frame_bits);
4386
78.2k
        ps_codec->au4_frame_qp[i1_layer_id] = gau1_mpeg2_to_h264_qmap[u1_frame_qp];
4387
78.2k
    }
4388
4389
    /*
4390
     * copy the pic id to poc because the display order is assumed to be same
4391
     * as input order
4392
     */
4393
78.2k
    ps_codec->i4_poc = u4_pic_id;
4394
4395
    /***************************************************************************
4396
     * Now retrieve the correct picture from the queue
4397
     **************************************************************************/
4398
4399
    /* Mark the skip flag   */
4400
78.2k
    i4_skip = 0;
4401
78.2k
    ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS;
4402
78.2k
    ps_codec->s_rate_control.pre_encode_skip[ctxt_sel] = i4_skip;
4403
4404
    /* Get a buffer to encode */
4405
78.2k
    ps_inp_buf = &(ps_codec->as_inp_list[u4_pic_id % SVC_MAX_NUM_INP_FRAMES]);
4406
4407
    /* copy dequeued input to output */
4408
78.2k
    ps_enc_buff[0] = ps_inp_buf[0];
4409
4410
    /* Special case for encoding trailing B frames
4411
     *
4412
     * In encoding streams with B frames it may happen that we have a B frame
4413
     * at the end without a P/I frame after it. Hence when we are dequeing from
4414
     * the RC, it will return the P frame [next in display order but before in
4415
     * encoding order] first. Since the dequeue happens for an invalid frame we
4416
     * will get a frame with null buff and set u4_is_last. Hence lib with return
4417
     * last frame flag at this point and will stop encoding.
4418
     *
4419
     * Since for the last B frame, we does not have the forward ref frame
4420
     * it makes sense to force it into P.
4421
     *
4422
     * To solve this, in case the current frame is P and if the last frame flag
4423
     * is set, we need to see if there is and pending B frames. If there are any,
4424
     * we should just encode that picture as the current P frame and set
4425
     * that B frame as the last frame. Hence the encoder will terminate naturally
4426
     * once that B-frame is encoded after all the in between frames.
4427
     *
4428
     * Since we cannot touch RC stack directly, the option of actually swapping
4429
     * frames in RC is ruled out. We have to modify the as_inp_list to simulate
4430
     * such a behavior by RC. We can do that by
4431
     *  1) Search through as_inp_list to locate the largest u4_timestamp_low less
4432
     *     than current u4_timestamp_low. This will give us the last B frame
4433
     * before the current P frame. Note that this will handle pre encode skip too
4434
     * since queue happens after pre enc skip. 2) Swap the position in
4435
     * as_inp_list. Hence now the last B frame is encoded as P frame. And the new
4436
     * last B frame will have u4_is_last set so that encoder will end naturally
4437
     * once we reached that B frame or any subsequent frame. Also the current GOP
4438
     * will have 1 less B frame Since we are swapping, the poc will also be
4439
     * in-order. 3) In case we have an IPP stream, the result of our search will
4440
     * be an I/P frame which is already encoded. Thus swap and encode will result
4441
     *     in encoding of duplicate frames. Hence to avoid this we will only
4442
     *     have this work around in case of u4_num_bframes > 0.
4443
     *
4444
     *     In case we have forced an I/IDR frame In between this P frame and
4445
     *     the last B frame -> This cannot happen as the current P frame is
4446
     *     supposed to have u4_is_last set. Thus forcing an I/ IDR after this
4447
     *     is illogical.
4448
     *
4449
     *     In cae if we have forced an I such that the frame just before last
4450
     * frame in is I/P -> This case will never arise. Since we have a closed GOP
4451
     * now, once we force an I, the gop gets reset, hence there will be a B
4452
     * between I/P and I/P.
4453
     */
4454
78.2k
    if(ps_enc_buff->s_inp_props.u4_is_last && (ps_codec->pic_type == PIC_P) &&
4455
78.2k
       ps_codec->s_cfg.u4_num_bframes)
4456
0
    {
4457
0
        WORD32 cntr;
4458
0
        WORD32 lst_bframe = -1;
4459
0
        UWORD32 u4_timestamp_low = 0;
4460
0
        UWORD32 u4_timestamp_high = 0;
4461
0
        isvce_inp_buf_t *ps_swap_buff, *ps_inp_list;
4462
4463
0
        ps_inp_list = &ps_codec->as_inp_list[0];
4464
4465
        /* Now search the inp list for highest timestamp */
4466
0
        for(cntr = 0; cntr < SVC_MAX_NUM_INP_FRAMES; cntr++)
4467
0
        {
4468
0
            if(ps_inp_list[cntr].s_inp_props.s_raw_buf.apv_bufs[0] != NULL)
4469
0
            {
4470
0
                if((ps_inp_list[cntr].s_inp_props.u4_timestamp_high > u4_timestamp_high) ||
4471
0
                   (ps_inp_list[cntr].s_inp_props.u4_timestamp_high == u4_timestamp_high &&
4472
0
                    ps_inp_list[cntr].s_inp_props.u4_timestamp_low > u4_timestamp_low))
4473
0
                {
4474
0
                    u4_timestamp_low = ps_inp_list[cntr].s_inp_props.u4_timestamp_low;
4475
0
                    u4_timestamp_high = ps_inp_list[cntr].s_inp_props.u4_timestamp_high;
4476
0
                    lst_bframe = cntr;
4477
0
                }
4478
0
            }
4479
0
        }
4480
4481
0
        if(lst_bframe != -1)
4482
0
        {
4483
0
            ps_swap_buff = &(ps_codec->as_inp_list[lst_bframe]);
4484
4485
            /* copy the last B buffer to output */
4486
0
            *ps_enc_buff = *ps_swap_buff;
4487
4488
            /* Store the current buf into the queue in place of last B buf */
4489
0
            *ps_swap_buff = *ps_inp_buf;
4490
0
        }
4491
0
    }
4492
4493
78.2k
    if(ps_enc_buff->s_inp_props.u4_is_last)
4494
11.7k
    {
4495
11.7k
        ps_codec->pic_type = PIC_NA;
4496
11.7k
    }
4497
4498
    /* The buffer in the queue is set to NULL to specify that encoding is done for
4499
     * that frame */
4500
312k
    for(i = 0; i < 3; i++)
4501
234k
    {
4502
234k
        ps_inp_buf->s_inp_props.s_raw_buf.apv_bufs[i] = NULL;
4503
234k
    }
4504
4505
    /* Return the buffer status */
4506
78.2k
    return (0);
4507
78.2k
}
4508
4509
/**
4510
******************************************************************************
4511
*
4512
* @brief
4513
*  This function joins all the spawned threads after successful completion of
4514
*  their tasks
4515
*
4516
* @par   Description
4517
*
4518
* @param[in] ps_codec
4519
*  pointer to codec context
4520
*
4521
* @returns  none
4522
*
4523
******************************************************************************
4524
*/
4525
void isvce_join_threads(isvce_codec_t *ps_codec)
4526
61.1k
{
4527
61.1k
    WORD32 i = 0;
4528
61.1k
    WORD32 ret = 0;
4529
4530
    /* join spawned threads */
4531
138k
    while(i < ps_codec->i4_proc_thread_cnt)
4532
77.6k
    {
4533
77.6k
        if(ps_codec->ai4_process_thread_created[i])
4534
77.6k
        {
4535
77.6k
            ret = ithread_join(ps_codec->apv_proc_thread_handle[i], NULL);
4536
4537
77.6k
            if(ret != 0)
4538
0
            {
4539
0
                ASSERT(0);
4540
0
            }
4541
4542
77.6k
            ps_codec->ai4_process_thread_created[i] = 0;
4543
77.6k
            i++;
4544
77.6k
        }
4545
77.6k
    }
4546
4547
61.1k
    ps_codec->i4_proc_thread_cnt = 0;
4548
61.1k
}
4549
4550
UWORD32 isvce_get_min_outbuf_size(UWORD32 u4_wd, UWORD32 u4_ht, UWORD8 u1_num_spatial_layers)
4551
44.7k
{
4552
44.7k
    return MAX((u4_wd * u4_ht * 3), MIN_STREAM_SIZE) * u1_num_spatial_layers;
4553
44.7k
}