Coverage Report

Created: 2026-05-16 06:30

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libavc/encoder/svc/isvce_process.c
Line
Count
Source
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
*  isvce_process.c
25
*
26
* @brief
27
*  Contains functions for codec thread
28
*
29
* @author
30
*  Harish
31
*
32
* @par List of Functions:
33
* - isvce_generate_sps_pps()
34
* - isvce_init_entropy_ctxt()
35
* - isvce_entropy()
36
* - isvce_pack_header_data()
37
* - isvce_update_proc_ctxt()
38
* - isvce_init_proc_ctxt()
39
* - isvce_pad_recon_buffer()
40
* - isvce_dblk_n_mbs()
41
* - isvce_process()
42
* - isvce_set_rc_pic_params()
43
* - isvce_update_rc_post_enc()
44
* - isvce_isvce_isvce_process_ctxt_thread()
45
*
46
* @remarks
47
*  None
48
*
49
*******************************************************************************
50
*/
51
52
#include <stdio.h>
53
#include <stddef.h>
54
#include <stdlib.h>
55
#include <string.h>
56
#include <limits.h>
57
#include <assert.h>
58
#include <math.h>
59
#include <stdbool.h>
60
61
#include "ih264_typedefs.h"
62
/* Dependencies of ih264_buf_mgr.h */
63
/* Dependencies of ih264_list.h */
64
#include "ih264_error.h"
65
/* Dependencies of ih264_common_tables.h */
66
#include "ih264_defs.h"
67
#include "ih264_structs.h"
68
#include "ih264_buf_mgr.h"
69
#include "ih264_common_tables.h"
70
#include "ih264_list.h"
71
#include "ih264_platform_macros.h"
72
#include "ih264_trans_data.h"
73
#include "ih264_size_defs.h"
74
/* Dependencies of ih264e_cabac_structs.h */
75
#include "ih264_cabac_tables.h"
76
/* Dependencies of ime_structs.h */
77
#include "ime_defs.h"
78
#include "ime_distortion_metrics.h"
79
/* Dependencies of ih264e_structs.h */
80
#include "iv2.h"
81
#include "ive2.h"
82
#include "ih264_defs.h"
83
#include "ih264_deblk_edge_filters.h"
84
#include "ih264_inter_pred_filters.h"
85
#include "ih264_structs.h"
86
#include "ih264_trans_quant_itrans_iquant.h"
87
/* Dependencies of ih264e_bitstream.h */
88
#include "ih264e_error.h"
89
#include "ih264e_bitstream.h"
90
#include "ih264e_cabac_structs.h"
91
#include "irc_cntrl_param.h"
92
#include "irc_frame_info_collector.h"
93
#include "ime_statistics.h"
94
#include "ime_structs.h"
95
/* Dependencies of 'ih264e_utils.h' */
96
#include "ih264e_defs.h"
97
#include "ih264e_structs.h"
98
#include "ih264e_utils.h"
99
#include "ime.h"
100
#include "isvce_cabac.h"
101
#include "isvce_cavlc.h"
102
#include "isvce_deblk.h"
103
#include "isvce_defs.h"
104
#include "isvce_downscaler.h"
105
#include "isvce_encode_header.h"
106
#include "isvce_ibl_eval.h"
107
#include "isvce_ilp_mv.h"
108
#include "isvce_intra_modes_eval.h"
109
#include "isvce_me.h"
110
#include "isvce_rate_control.h"
111
#include "isvce_residual_pred.h"
112
#include "isvce_sub_pic_rc.h"
113
#include "isvce_utils.h"
114
115
/*****************************************************************************/
116
/* Function Definitions                                                      */
117
/*****************************************************************************/
118
119
/**
120
******************************************************************************
121
*
122
*  @brief This function generates sps, pps set on request
123
*
124
*  @par   Description
125
*  When the encoder is set in header generation mode, the following function
126
*  is called. This generates sps and pps headers and returns the control back
127
*  to caller.
128
*
129
*  @param[in]    ps_codec
130
*  pointer to codec context
131
*
132
*  @return      success or failure error code
133
*
134
******************************************************************************
135
*/
136
IH264E_ERROR_T isvce_generate_sps_pps(isvce_codec_t *ps_codec, isvce_inp_buf_t *ps_inp_buf)
137
4.85k
{
138
4.85k
    sps_t *ps_sps;
139
4.85k
    pps_t *ps_pps;
140
4.85k
    subset_sps_t *ps_subset_sps;
141
142
4.85k
    WORD32 i;
143
144
4.85k
    isvce_process_ctxt_t *ps_proc = ps_codec->as_process;
145
4.85k
    isvce_entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
146
4.85k
    bitstrm_t *ps_bitstrm = ps_entropy->ps_bitstrm;
147
4.85k
    isvce_out_buf_t *ps_out_buf = ps_codec->as_out_buf;
148
149
4.85k
    UWORD8 u1_profile_idc = IH264_PROFILE_BASELINE;
150
151
4.85k
    ASSERT(1 == MAX_CTXT_SETS);
152
153
4.85k
    ih264e_bitstrm_init(ps_bitstrm, ps_out_buf->as_bits_buf[ps_proc->u1_spatial_layer_id].pv_buf,
154
4.85k
                        ps_out_buf->as_bits_buf[ps_proc->u1_spatial_layer_id].u4_bufsize);
155
156
4.85k
    ps_sps = ps_codec->ps_sps_base;
157
4.85k
    isvce_populate_sps(ps_codec, ps_sps, 0, u1_profile_idc, ps_inp_buf, 0);
158
159
4.85k
    ps_pps = ps_codec->ps_pps_base;
160
4.85k
    isvce_populate_pps(ps_codec, ps_pps, 0, 0, 0);
161
162
11.1k
    for(i = 1; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers; i++)
163
6.32k
    {
164
6.32k
        ps_subset_sps = ps_codec->ps_subset_sps_base + i;
165
6.32k
        isvce_populate_subset_sps(ps_codec, ps_subset_sps, i, ps_inp_buf, i);
166
167
6.32k
        ps_pps = ps_codec->ps_pps_base + i;
168
6.32k
        isvce_populate_pps(ps_codec, ps_pps, i, i, i);
169
6.32k
    }
170
171
4.85k
    ps_entropy->i4_error_code = IH264E_SUCCESS;
172
173
4.85k
    ps_entropy->i4_error_code = isvce_generate_sps(ps_bitstrm, ps_sps, NAL_SPS);
174
4.85k
    if(ps_entropy->i4_error_code != IH264E_SUCCESS)
175
0
    {
176
0
        return ps_entropy->i4_error_code;
177
0
    }
178
179
4.85k
    ps_pps = ps_codec->ps_pps_base;
180
4.85k
    ps_entropy->i4_error_code = isvce_generate_pps(ps_bitstrm, ps_pps, ps_sps);
181
182
11.1k
    for(i = 1; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers; i++)
183
6.32k
    {
184
6.32k
        ps_subset_sps = ps_codec->ps_subset_sps_base + i;
185
6.32k
        isvce_generate_subset_sps(ps_bitstrm, ps_subset_sps);
186
187
        /* populate pps header */
188
6.32k
        ps_pps = ps_codec->ps_pps_base + i;
189
6.32k
        isvce_generate_pps(ps_bitstrm, ps_pps, &ps_subset_sps->s_sps);
190
6.32k
    }
191
192
    /* queue output buffer */
193
4.85k
    ps_out_buf->as_bits_buf[ps_proc->u1_spatial_layer_id].u4_bytes = ps_bitstrm->u4_strm_buf_offset;
194
195
4.85k
    return ps_entropy->i4_error_code;
196
4.85k
}
197
198
/**
199
*******************************************************************************
200
*
201
* @brief   initialize entropy context.
202
*
203
* @par Description:
204
*  Before invoking the call to perform to entropy coding the entropy context
205
*  associated with the job needs to be initialized. This involves the start
206
*  mb address, end mb address, slice index and the pointer to location at
207
*  which the mb residue info and mb header info are packed.
208
*
209
* @param[in] ps_proc
210
*  Pointer to the current process context
211
*
212
* @returns error status
213
*
214
* @remarks none
215
*
216
*******************************************************************************
217
*/
218
IH264E_ERROR_T isvce_init_entropy_ctxt(isvce_process_ctxt_t *ps_proc)
219
322k
{
220
    /* codec context */
221
322k
    isvce_codec_t *ps_codec = ps_proc->ps_codec;
222
223
    /* entropy ctxt */
224
322k
    isvce_entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
225
226
    /* start address */
227
322k
    ps_entropy->i4_mb_start_add = ps_entropy->i4_mb_y * ps_entropy->i4_wd_mbs + ps_entropy->i4_mb_x;
228
229
    /* end address */
230
322k
    ps_entropy->i4_mb_end_add = ps_entropy->i4_mb_start_add + ps_entropy->i4_mb_cnt;
231
232
    /* slice index */
233
322k
    ps_entropy->i4_cur_slice_idx = ps_proc->pu1_slice_idx[ps_entropy->i4_mb_start_add];
234
235
    /* sof */
236
    /* @ start of frame or start of a new slice, set sof flag */
237
322k
    if(ps_entropy->i4_mb_start_add == 0)
238
61.5k
    {
239
61.5k
        ps_entropy->i4_sof = 1;
240
61.5k
    }
241
242
322k
    if(ps_entropy->i4_mb_x == 0)
243
322k
    {
244
        /* packed mb coeff data */
245
322k
        ps_entropy->pv_mb_coeff_data = ((UWORD8 *) ps_entropy->pv_pic_mb_coeff_data) +
246
322k
                                       ps_entropy->i4_mb_y * ps_codec->u4_size_coeff_data;
247
248
        /* packed mb header data */
249
322k
        ps_entropy->pv_mb_header_data = ((UWORD8 *) ps_entropy->pv_pic_mb_header_data) +
250
322k
                                        ps_entropy->i4_mb_y * ps_codec->u4_size_header_data;
251
322k
    }
252
253
322k
    return IH264E_SUCCESS;
254
322k
}
255
256
/**
257
*******************************************************************************
258
*
259
* @brief
260
*  Function to update rc context after encoding
261
*
262
* @par   Description
263
*  This function updates the rate control context after the frame is encoded.
264
*  Number of bits consumed by the current frame, frame distortion, frame cost,
265
*  number of intra/inter mb's, ... are passed on to rate control context for
266
*  updating the rc model.
267
*
268
* @param[in] ps_codec
269
*  Handle to codec context
270
*
271
* @param[in] ctxt_sel
272
*  frame context selector
273
*
274
* @param[in] pic_cnt
275
*  pic count
276
*
277
* @returns i4_stuffing_byte
278
*  number of stuffing bytes (if necessary)
279
*
280
* @remarks
281
*
282
*******************************************************************************
283
*/
284
WORD32 isvce_update_rc_post_enc(isvce_codec_t *ps_codec, WORD32 ctxt_sel, WORD32 i4_is_first_frm)
285
61.1k
{
286
61.1k
    WORD32 i4_proc_ctxt_sel_base = ctxt_sel ? (MAX_PROCESS_CTXT / 2) : 0;
287
288
61.1k
    isvce_process_ctxt_t *ps_proc = &ps_codec->as_process[i4_proc_ctxt_sel_base];
289
290
61.1k
#if ENABLE_RE_ENC_AS_SKIP
291
61.1k
    isvce_entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
292
293
61.1k
    UWORD8 u1_is_post_enc_skip = 0;
294
61.1k
#endif
295
296
    /* frame qp */
297
61.1k
    UWORD8 u1_frame_qp = ps_codec->au4_frame_qp[ps_proc->u1_spatial_layer_id];
298
299
    /* cbr rc return status */
300
61.1k
    WORD32 i4_stuffing_byte = 0;
301
302
    /* current frame stats */
303
61.1k
    frame_info_t s_frame_info;
304
61.1k
    picture_type_e rc_pic_type = I_PIC;
305
306
    /* temp var */
307
61.1k
    WORD32 i, j;
308
309
    /********************************************************************/
310
    /*                            BEGIN INIT                            */
311
    /********************************************************************/
312
313
    /* init frame info */
314
61.1k
    irc_init_frame_info(&s_frame_info);
315
316
    /* get frame info */
317
218k
    for(i = 0; i < (WORD32) ps_codec->s_cfg.u4_num_cores; i++)
318
156k
    {
319
        /*****************************************************************/
320
        /* One frame can be encoded by max of u4_num_cores threads       */
321
        /* Accumulating the num mbs, sad, qp and intra_mb_cost from      */
322
        /* u4_num_cores threads                                          */
323
        /*****************************************************************/
324
470k
        for(j = 0; j < MAX_MB_TYPE; j++)
325
313k
        {
326
313k
            s_frame_info.num_mbs[j] += ps_proc[i].s_frame_info.num_mbs[j];
327
328
313k
            s_frame_info.tot_mb_sad[j] += ps_proc[i].s_frame_info.tot_mb_sad[j];
329
330
313k
            s_frame_info.qp_sum[j] += ps_proc[i].s_frame_info.qp_sum[j];
331
313k
        }
332
333
156k
        s_frame_info.intra_mb_cost_sum += ps_proc[i].s_frame_info.intra_mb_cost_sum;
334
335
156k
        s_frame_info.activity_sum += ps_proc[i].s_frame_info.activity_sum;
336
337
        /*****************************************************************/
338
        /* gather number of residue and header bits consumed by the frame*/
339
        /*****************************************************************/
340
156k
        isvce_update_rc_bits_info(&s_frame_info, &ps_proc[i].s_entropy);
341
156k
    }
342
343
    /* get pic type */
344
61.1k
    switch(ps_codec->pic_type)
345
61.1k
    {
346
2.15k
        case PIC_I:
347
18.5k
        case PIC_IDR:
348
18.5k
            rc_pic_type = I_PIC;
349
18.5k
            break;
350
42.6k
        case PIC_P:
351
42.6k
            rc_pic_type = P_PIC;
352
42.6k
            break;
353
0
        case PIC_B:
354
0
            rc_pic_type = B_PIC;
355
0
            break;
356
0
        default:
357
0
            assert(0);
358
0
            break;
359
61.1k
    }
360
361
    /* update rc lib with current frame stats */
362
61.1k
    i4_stuffing_byte = isvce_rc_post_enc(
363
61.1k
        ps_codec->s_rate_control.apps_rate_control_api[ps_proc->u1_spatial_layer_id],
364
61.1k
        &(s_frame_info), ps_codec->s_rate_control.pps_pd_frm_rate,
365
61.1k
        ps_codec->s_rate_control.pps_time_stamp, ps_codec->s_rate_control.pps_frame_time,
366
61.1k
        (ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs), &rc_pic_type, i4_is_first_frm,
367
61.1k
        &ps_codec->s_rate_control.post_encode_skip[ctxt_sel], u1_frame_qp,
368
61.1k
        &ps_codec->s_rate_control.ai4_num_intra_in_prev_frame[ps_proc->u1_spatial_layer_id],
369
61.1k
        &ps_codec->s_rate_control.ai4_avg_activity[ps_proc->u1_spatial_layer_id]
370
61.1k
#if ENABLE_RE_ENC_AS_SKIP
371
61.1k
        ,
372
61.1k
        &u1_is_post_enc_skip
373
61.1k
#endif
374
61.1k
    );
375
376
61.1k
#if ENABLE_RE_ENC_AS_SKIP
377
61.1k
    if(u1_is_post_enc_skip)
378
15.0k
    {
379
15.0k
        buffer_container_t s_dst;
380
381
15.0k
        WORD32 i;
382
383
15.0k
        isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
384
15.0k
        mem_fxns_t *ps_mem_fxns = &ps_isa_dependent_fxns->s_mem_fxns;
385
15.0k
        svc_ilp_data_t *ps_svc_ilp_data = &ps_codec->s_svc_ilp_data;
386
387
15.0k
        UWORD8 u1_spatial_layer_id = ps_proc->u1_spatial_layer_id;
388
15.0k
        UWORD8 u1_num_spatial_layers = ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers;
389
390
15.0k
        UWORD32 u4_wd = ps_codec->s_cfg.u4_wd;
391
15.0k
        UWORD32 u4_ht = ps_codec->s_cfg.u4_ht;
392
15.0k
        DOUBLE d_spatial_res_ratio = ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio;
393
394
15.0k
        WORD32 i4_layer_luma_wd =
395
15.0k
            (WORD32) (((DOUBLE) u4_wd /
396
15.0k
                       pow(d_spatial_res_ratio, u1_num_spatial_layers - u1_spatial_layer_id - 1)) +
397
15.0k
                      0.99);
398
15.0k
        WORD32 i4_layer_luma_ht =
399
15.0k
            (WORD32) (((DOUBLE) u4_ht /
400
15.0k
                       pow(d_spatial_res_ratio, u1_num_spatial_layers - u1_spatial_layer_id - 1)) +
401
15.0k
                      0.99);
402
403
15.0k
        if(CABAC == ps_entropy->u1_entropy_coding_mode_flag)
404
2.22k
        {
405
2.22k
            isvce_reencode_as_skip_frame_cabac(ps_entropy);
406
2.22k
        }
407
12.8k
        else
408
12.8k
        {
409
12.8k
            isvce_reencode_as_skip_frame_cavlc(ps_entropy);
410
12.8k
        }
411
412
15.0k
        if(u1_num_spatial_layers > 1)
413
13.2k
        {
414
46.5k
            for(i = 0; i < ps_proc->i4_ht_mbs; i++)
415
33.3k
            {
416
171k
                for(j = 0; j < ps_proc->i4_wd_mbs; j++)
417
138k
                {
418
138k
                    isvce_update_ibl_info(ps_proc->ps_intra_pred_ctxt, u1_num_spatial_layers,
419
138k
                                          u1_spatial_layer_id, PSKIP, j, i, 0);
420
138k
                }
421
33.3k
            }
422
423
13.2k
            if(ENABLE_ILP_MV)
424
13.2k
            {
425
13.2k
                svc_layer_data_t *ps_layer_data;
426
427
13.2k
                svc_au_data_t *ps_svc_au_data = ps_svc_ilp_data->ps_svc_au_data;
428
429
13.2k
                WORD32 i4_num_mbs = ps_proc->i4_ht_mbs * ps_proc->i4_wd_mbs;
430
431
13.2k
                ps_layer_data = &ps_svc_au_data->ps_svc_layer_data[ps_entropy->u1_spatial_layer_id];
432
433
13.2k
                memset(ps_layer_data->ps_mb_info, 0,
434
13.2k
                       i4_num_mbs * sizeof(ps_layer_data->ps_mb_info[0]));
435
436
151k
                for(i = 0; i < i4_num_mbs; i++)
437
138k
                {
438
138k
                    ps_layer_data->pu4_num_pus_in_mb[i] = 1;
439
138k
                }
440
13.2k
            }
441
13.2k
        }
442
443
45.2k
        for(i = 0; i < NUM_SP_COMPONENTS; i++)
444
30.1k
        {
445
30.1k
            UWORD8 u1_is_chroma = (Y != ((COMPONENT_TYPE) i));
446
30.1k
            WORD32 i4_src_strd = ps_proc->aps_ref_pic[0]
447
30.1k
                                     ->ps_layer_yuv_buf_props[u1_spatial_layer_id]
448
30.1k
                                     .as_component_bufs[i]
449
30.1k
                                     .i4_data_stride;
450
30.1k
            WORD32 i4_dst_strd = ps_proc->ps_cur_pic->ps_layer_yuv_buf_props[u1_spatial_layer_id]
451
30.1k
                                     .as_component_bufs[i]
452
30.1k
                                     .i4_data_stride;
453
454
30.1k
            if(u1_spatial_layer_id < (u1_num_spatial_layers - 1))
455
16.4k
            {
456
16.4k
                s_dst.i4_data_stride = ps_svc_ilp_data->ps_intra_recon_bufs[u1_spatial_layer_id]
457
16.4k
                                           .as_component_bufs[i]
458
16.4k
                                           .i4_data_stride;
459
16.4k
                s_dst.pv_data =
460
16.4k
                    ((UWORD8 *) ps_svc_ilp_data->ps_intra_recon_bufs[u1_spatial_layer_id]
461
16.4k
                         .as_component_bufs[i]
462
16.4k
                         .pv_data);
463
464
16.4k
                ps_mem_fxns->pf_memset_2d((UWORD8 *) s_dst.pv_data, s_dst.i4_data_stride, 0,
465
16.4k
                                          i4_layer_luma_wd, (i4_layer_luma_ht >> u1_is_chroma));
466
467
16.4k
                if(ENABLE_RESIDUAL_PREDICTION)
468
16.4k
                {
469
16.4k
                    WORD16 *pi2_res;
470
16.4k
                    yuv_buf_props_t *ps_residual_buf =
471
16.4k
                        &ps_codec->s_svc_ilp_data.ps_residual_bufs[u1_spatial_layer_id];
472
473
16.4k
                    pi2_res = ps_residual_buf->as_component_bufs[u1_is_chroma].pv_data;
474
475
16.4k
                    ps_mem_fxns->pf_memset_2d(
476
16.4k
                        (UWORD8 *) pi2_res,
477
16.4k
                        ps_residual_buf->as_component_bufs[u1_is_chroma].i4_data_stride *
478
16.4k
                            (sizeof(WORD16) / sizeof(UWORD8)),
479
16.4k
                        0,
480
16.4k
                        ps_residual_buf->as_component_bufs[u1_is_chroma].i4_data_stride *
481
16.4k
                            (sizeof(WORD16) / sizeof(UWORD8)),
482
16.4k
                        i4_layer_luma_ht >> u1_is_chroma);
483
16.4k
                }
484
16.4k
            }
485
486
30.1k
            ps_mem_fxns->pf_copy_2d(
487
30.1k
                (UWORD8 *) (ps_proc->ps_cur_pic->ps_layer_yuv_buf_props[u1_spatial_layer_id]
488
30.1k
                                .as_component_bufs[i]
489
30.1k
                                .pv_data) -
490
30.1k
                    PAD_LEFT - (PAD_TOP * i4_dst_strd),
491
30.1k
                i4_dst_strd,
492
30.1k
                (UWORD8 *) (ps_proc->aps_ref_pic[0]
493
30.1k
                                ->ps_layer_yuv_buf_props[u1_spatial_layer_id]
494
30.1k
                                .as_component_bufs[i]
495
30.1k
                                .pv_data) -
496
30.1k
                    PAD_LEFT - (PAD_TOP * i4_src_strd),
497
30.1k
                i4_src_strd, (i4_layer_luma_wd + PAD_WD),
498
30.1k
                (i4_layer_luma_ht >> u1_is_chroma) + PAD_HT);
499
30.1k
        }
500
501
15.0k
        RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
502
15.0k
    }
503
504
61.1k
#endif
505
61.1k
    return i4_stuffing_byte;
506
61.1k
}
507
508
/**
509
*******************************************************************************
510
*
511
* @brief entry point for entropy coding
512
*
513
* @par Description
514
*  This function calls lower level functions to perform entropy coding for a
515
*  group (n rows) of mb's. After encoding 1 row of mb's,  the function takes
516
*  back the control, updates the ctxt and calls lower level functions again.
517
*  This process is repeated till all the rows or group of mb's (which ever is
518
*  minimum) are coded
519
*
520
* @param[in] ps_proc
521
*  process context
522
*
523
* @returns  error status
524
*
525
* @remarks
526
*
527
*******************************************************************************
528
*/
529
IH264E_ERROR_T isvce_entropy(isvce_process_ctxt_t *ps_proc)
530
322k
{
531
322k
    svc_nalu_ext_t *aps_svc_nalu_ext[2];
532
322k
    isvce_out_buf_t s_out_buf;
533
322k
    sei_params_t s_sei;
534
322k
    nalu_info_t *ps_slice_nalu_info;
535
322k
    nalu_info_t *ps_non_vcl_nalu_info;
536
537
322k
    UWORD8 *pu1_proc_map;
538
322k
    UWORD8 *pu1_entropy_map_curr;
539
322k
    WORD32 i4_wd_mbs, i4_ht_mbs;
540
322k
    UWORD32 u4_mb_cnt, u4_mb_idx, u4_mb_end_idx, u4_insert_per_idr;
541
322k
    WORD32 bitstream_start_offset, bitstream_end_offset;
542
543
322k
    isvce_codec_t *ps_codec = ps_proc->ps_codec;
544
322k
    isvce_entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
545
322k
    isvce_cabac_ctxt_t *ps_cabac_ctxt = ps_entropy->ps_cabac;
546
322k
    sps_t *ps_sps = ps_entropy->ps_sps_base;
547
322k
    subset_sps_t *ps_subset_sps = ps_entropy->ps_subset_sps_base;
548
322k
    pps_t *ps_pps = ps_entropy->ps_pps_base;
549
322k
    slice_header_t *ps_slice_hdr =
550
322k
        ps_entropy->ps_slice_hdr_base + (ps_entropy->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
551
322k
    svc_slice_header_t *ps_svc_slice_hdr = NULL;
552
322k
    bitstrm_t *ps_bitstrm = ps_entropy->ps_bitstrm;
553
322k
#if ENABLE_RE_ENC_AS_SKIP
554
322k
    bitstrm_t *ps_bitstrm_after_slice_hdr = ps_entropy->ps_bitstrm_after_slice_hdr;
555
322k
#endif
556
322k
    nalu_descriptors_t *ps_nalu_descriptor =
557
322k
        &ps_codec->as_nalu_descriptors[ps_proc->u1_spatial_layer_id];
558
559
322k
    WORD32 i4_slice_type = ps_proc->i4_slice_type;
560
322k
    WORD32 ctxt_sel = ps_proc->i4_encode_api_call_cnt % MAX_CTXT_SETS;
561
562
322k
    aps_svc_nalu_ext[0] =
563
322k
        ps_entropy->ps_svc_nalu_ext_base + (ps_entropy->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
564
322k
    aps_svc_nalu_ext[1] = ps_entropy->ps_svc_nalu_ext_base + 1 +
565
322k
                          (ps_entropy->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
566
567
    /********************************************************************/
568
    /*                            BEGIN INIT                            */
569
    /********************************************************************/
570
571
    /* entropy encode start address */
572
322k
    u4_mb_idx = ps_entropy->i4_mb_start_add;
573
574
    /* entropy encode end address */
575
322k
    u4_mb_end_idx = ps_entropy->i4_mb_end_add;
576
577
    /* width in mbs */
578
322k
    i4_wd_mbs = ps_entropy->i4_wd_mbs;
579
580
    /* height in mbs */
581
322k
    i4_ht_mbs = ps_entropy->i4_ht_mbs;
582
583
    /* total mb cnt */
584
322k
    u4_mb_cnt = i4_wd_mbs * i4_ht_mbs;
585
586
    /* proc map */
587
322k
    pu1_proc_map = ps_proc->pu1_proc_map + ps_entropy->i4_mb_y * i4_wd_mbs;
588
589
    /* entropy map */
590
322k
    pu1_entropy_map_curr = ps_entropy->pu1_entropy_map + ps_entropy->i4_mb_y * i4_wd_mbs;
591
592
    /********************************************************************/
593
    /* @ start of frame / slice,                                        */
594
    /*      initialize the output buffer,                               */
595
    /*      initialize the bit stream buffer,                           */
596
    /*      check if sps and pps headers have to be generated,          */
597
    /*      populate and generate slice header                          */
598
    /********************************************************************/
599
322k
    if(ps_entropy->i4_sof)
600
61.5k
    {
601
        /********************************************************************/
602
        /*      initialize the output buffer                                */
603
        /********************************************************************/
604
61.5k
        s_out_buf = ps_codec->as_out_buf[ctxt_sel];
605
606
        /* is last frame to encode */
607
61.5k
        s_out_buf.u4_is_last = ps_entropy->u4_is_last;
608
609
        /* frame idx */
610
61.5k
        s_out_buf.u4_timestamp_high = ps_entropy->u4_timestamp_high;
611
61.5k
        s_out_buf.u4_timestamp_low = ps_entropy->u4_timestamp_low;
612
613
        /********************************************************************/
614
        /*      initialize the bit stream buffer                            */
615
        /********************************************************************/
616
61.5k
        ih264e_bitstrm_init(ps_bitstrm, s_out_buf.as_bits_buf[ps_proc->u1_spatial_layer_id].pv_buf,
617
61.5k
                            s_out_buf.as_bits_buf[ps_proc->u1_spatial_layer_id].u4_bufsize);
618
619
        /********************************************************************/
620
        /*                    BEGIN HEADER GENERATION                       */
621
        /********************************************************************/
622
61.5k
        if(1 == ps_entropy->i4_gen_header)
623
0
        {
624
0
            WORD32 i;
625
626
0
            ps_non_vcl_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
627
0
            isvce_nalu_info_buf_init(ps_non_vcl_nalu_info,
628
0
                                     -((WORD32) isvce_get_num_bits(ps_bitstrm)), NAL_SPS,
629
0
                                     ps_proc->u1_spatial_layer_id,
630
0
                                     ps_proc->ps_cur_pic->i1_temporal_id, 1, !!ps_proc->u4_is_idr);
631
632
0
            ps_entropy->i4_error_code = isvce_generate_sps(ps_bitstrm, ps_sps, NAL_SPS);
633
0
            RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
634
635
0
            ps_non_vcl_nalu_info->i8_num_bits += isvce_get_num_bits(ps_bitstrm);
636
0
            isvce_update_nalu_count(ps_nalu_descriptor);
637
638
0
            for(i = 1; i < ps_proc->s_svc_params.u1_num_spatial_layers; i++)
639
0
            {
640
0
                ps_subset_sps = ps_entropy->ps_subset_sps_base + i;
641
642
0
                ps_non_vcl_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
643
0
                isvce_nalu_info_buf_init(
644
0
                    ps_non_vcl_nalu_info, -((WORD32) isvce_get_num_bits(ps_bitstrm)),
645
0
                    NAL_SUBSET_SPS, ps_proc->u1_spatial_layer_id,
646
0
                    ps_proc->ps_cur_pic->i1_temporal_id, 1, !!ps_proc->u4_is_idr);
647
648
0
                ps_entropy->i4_error_code = isvce_generate_subset_sps(ps_bitstrm, ps_subset_sps);
649
650
0
                ps_non_vcl_nalu_info->i8_num_bits += isvce_get_num_bits(ps_bitstrm);
651
0
                isvce_update_nalu_count(ps_nalu_descriptor);
652
0
            }
653
654
0
            ps_non_vcl_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
655
0
            isvce_nalu_info_buf_init(ps_non_vcl_nalu_info,
656
0
                                     -((WORD32) isvce_get_num_bits(ps_bitstrm)), NAL_PPS,
657
0
                                     ps_proc->u1_spatial_layer_id,
658
0
                                     ps_proc->ps_cur_pic->i1_temporal_id, 1, !!ps_proc->u4_is_idr);
659
660
0
            ps_entropy->i4_error_code = isvce_generate_pps(ps_bitstrm, ps_pps, ps_sps);
661
0
            RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
662
663
0
            ps_non_vcl_nalu_info->i8_num_bits += isvce_get_num_bits(ps_bitstrm);
664
0
            isvce_update_nalu_count(ps_nalu_descriptor);
665
666
0
            for(i = 1; i < ps_proc->s_svc_params.u1_num_spatial_layers; i++)
667
0
            {
668
0
                ps_pps = ps_entropy->ps_pps_base + i;
669
0
                ps_subset_sps = ps_entropy->ps_subset_sps_base + i;
670
671
0
                ps_non_vcl_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
672
0
                isvce_nalu_info_buf_init(
673
0
                    ps_non_vcl_nalu_info, -((WORD32) isvce_get_num_bits(ps_bitstrm)), NAL_PPS,
674
0
                    ps_proc->u1_spatial_layer_id, ps_proc->ps_cur_pic->i1_temporal_id, 1,
675
0
                    !!ps_proc->u4_is_idr);
676
677
0
                ps_entropy->i4_error_code =
678
0
                    isvce_generate_pps(ps_bitstrm, ps_pps, &ps_subset_sps->s_sps);
679
680
0
                RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
681
682
0
                ps_non_vcl_nalu_info->i8_num_bits += isvce_get_num_bits(ps_bitstrm);
683
0
                isvce_update_nalu_count(ps_nalu_descriptor);
684
0
            }
685
686
0
            ps_entropy->i4_gen_header = 0;
687
0
        }
688
689
61.5k
        ps_svc_slice_hdr = ps_entropy->ps_svc_slice_hdr_base +
690
61.5k
                           (ps_entropy->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
691
692
61.5k
        if((ps_codec->s_cfg.s_svc_params.u1_num_temporal_layers > 1) ||
693
27.5k
           (ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers > 1))
694
58.2k
        {
695
58.2k
            isvce_populate_svc_nalu_extension(ps_proc, aps_svc_nalu_ext[0], NAL_PREFIX,
696
58.2k
                                              ps_proc->u4_is_idr);
697
698
58.2k
            if(ps_proc->u1_spatial_layer_id > 0)
699
32.9k
            {
700
32.9k
                isvce_populate_svc_nalu_extension(ps_proc, aps_svc_nalu_ext[1],
701
32.9k
                                                  NAL_CODED_SLICE_EXTENSION, ps_proc->u4_is_idr);
702
32.9k
            }
703
58.2k
        }
704
3.26k
        else
705
3.26k
        {
706
3.26k
            isvce_populate_svc_nalu_extension(ps_proc, aps_svc_nalu_ext[0], NAL_PREFIX,
707
3.26k
                                              ps_proc->u4_is_idr);
708
3.26k
        }
709
710
61.5k
        if(ps_proc->u1_spatial_layer_id > 0)
711
32.9k
        {
712
32.9k
            ps_subset_sps = ps_entropy->ps_subset_sps_base + ps_proc->u1_spatial_layer_id;
713
32.9k
            ps_pps = ps_entropy->ps_pps_base + ps_proc->u1_spatial_layer_id;
714
715
32.9k
            ps_entropy->i4_error_code = isvce_populate_svc_slice(
716
32.9k
                ps_proc, ps_svc_slice_hdr, ps_pps, ps_subset_sps, aps_svc_nalu_ext[1]);
717
718
32.9k
            RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
719
720
32.9k
            ps_slice_hdr = &ps_svc_slice_hdr->s_slice_header;
721
32.9k
        }
722
28.5k
        else
723
28.5k
        {
724
28.5k
            ps_pps = ps_entropy->ps_pps_base;
725
28.5k
            ps_sps = ps_entropy->ps_sps_base;
726
727
28.5k
            ps_entropy->i4_error_code = isvce_populate_slice_header(
728
28.5k
                ps_proc, ps_slice_hdr, ps_pps, ps_sps, aps_svc_nalu_ext[0]->u1_idr_flag);
729
730
28.5k
            RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
731
28.5k
        }
732
733
        /* generate sei */
734
61.5k
        u4_insert_per_idr = (NAL_SLICE_IDR == ps_slice_hdr->i1_nal_unit_type);
735
736
61.5k
        memset(&s_sei, 0, sizeof(sei_params_t));
737
61.5k
        s_sei.u1_sei_mdcv_params_present_flag =
738
61.5k
            ps_codec->s_cfg.s_sei.u1_sei_mdcv_params_present_flag;
739
61.5k
        s_sei.s_sei_mdcv_params = ps_codec->s_cfg.s_sei.s_sei_mdcv_params;
740
61.5k
        s_sei.u1_sei_cll_params_present_flag = ps_codec->s_cfg.s_sei.u1_sei_cll_params_present_flag;
741
61.5k
        s_sei.s_sei_cll_params = ps_codec->s_cfg.s_sei.s_sei_cll_params;
742
61.5k
        s_sei.u1_sei_ave_params_present_flag = ps_codec->s_cfg.s_sei.u1_sei_ave_params_present_flag;
743
61.5k
        s_sei.s_sei_ave_params = ps_codec->s_cfg.s_sei.s_sei_ave_params;
744
61.5k
        s_sei.u1_sei_ccv_params_present_flag = 0;
745
61.5k
        s_sei.s_sei_ccv_params =
746
61.5k
            ps_codec->as_inp_list[ps_codec->i4_poc % SVC_MAX_NUM_INP_FRAMES].s_inp_props.s_sei_ccv;
747
748
61.5k
        if((1 == ps_sps->i1_vui_parameters_present_flag) &&
749
0
           (1 == ps_codec->s_cfg.s_vui.u1_video_signal_type_present_flag) &&
750
0
           (1 == ps_codec->s_cfg.s_vui.u1_colour_description_present_flag) &&
751
0
           (2 != ps_codec->s_cfg.s_vui.u1_colour_primaries) &&
752
0
           (2 != ps_codec->s_cfg.s_vui.u1_matrix_coefficients) &&
753
0
           (2 != ps_codec->s_cfg.s_vui.u1_transfer_characteristics) &&
754
0
           (4 != ps_codec->s_cfg.s_vui.u1_transfer_characteristics) &&
755
0
           (5 != ps_codec->s_cfg.s_vui.u1_transfer_characteristics))
756
0
        {
757
0
            s_sei.u1_sei_ccv_params_present_flag =
758
0
                ps_codec->as_inp_list[ps_codec->i4_poc % SVC_MAX_NUM_INP_FRAMES]
759
0
                    .s_inp_props.u1_sei_ccv_params_present_flag;
760
0
        }
761
762
61.5k
        if((1 == s_sei.u1_sei_mdcv_params_present_flag && u4_insert_per_idr) ||
763
58.0k
           (1 == s_sei.u1_sei_cll_params_present_flag && u4_insert_per_idr) ||
764
56.5k
           (1 == s_sei.u1_sei_ave_params_present_flag && u4_insert_per_idr) ||
765
55.5k
           (1 == s_sei.u1_sei_ccv_params_present_flag))
766
6.03k
        {
767
6.03k
            ps_non_vcl_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
768
6.03k
            isvce_nalu_info_buf_init(ps_non_vcl_nalu_info,
769
6.03k
                                     -((WORD32) isvce_get_num_bits(ps_bitstrm)), NAL_SEI,
770
6.03k
                                     ps_proc->u1_spatial_layer_id,
771
6.03k
                                     ps_proc->ps_cur_pic->i1_temporal_id, 1, !!ps_proc->u4_is_idr);
772
773
6.03k
            ps_entropy->i4_error_code = ih264e_generate_sei(ps_bitstrm, &s_sei, u4_insert_per_idr);
774
6.03k
            RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
775
776
6.03k
            ps_non_vcl_nalu_info->i8_num_bits += isvce_get_num_bits(ps_bitstrm);
777
6.03k
            isvce_update_nalu_count(ps_nalu_descriptor);
778
6.03k
        }
779
780
61.5k
        ps_codec->as_inp_list[ps_codec->i4_poc % SVC_MAX_NUM_INP_FRAMES]
781
61.5k
            .s_inp_props.u1_sei_ccv_params_present_flag = 0;
782
783
61.5k
        if((ps_proc->u1_spatial_layer_id == 0) &&
784
28.5k
           (ps_codec->s_cfg.s_svc_params.u1_num_temporal_layers > 1 ||
785
12.3k
            ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers > 1))
786
25.2k
        {
787
25.2k
            ps_non_vcl_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
788
25.2k
            isvce_nalu_info_buf_init(ps_non_vcl_nalu_info,
789
25.2k
                                     -((WORD32) isvce_get_num_bits(ps_bitstrm)), NAL_PREFIX,
790
25.2k
                                     ps_proc->u1_spatial_layer_id,
791
25.2k
                                     ps_proc->ps_cur_pic->i1_temporal_id, 1, !!ps_proc->u4_is_idr);
792
793
25.2k
            ps_entropy->i4_error_code =
794
25.2k
                isvce_generate_svc_nalu_extension(ps_bitstrm, aps_svc_nalu_ext[0], NAL_PREFIX);
795
796
25.2k
            ps_entropy->i4_error_code = isvce_generate_prefix_nal(
797
25.2k
                ps_bitstrm, aps_svc_nalu_ext[0], ps_slice_hdr, ps_sps->u1_max_num_ref_frames,
798
25.2k
                ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers);
799
25.2k
            RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
800
801
25.2k
            ps_non_vcl_nalu_info->i8_num_bits += isvce_get_num_bits(ps_bitstrm);
802
25.2k
            isvce_update_nalu_count(ps_nalu_descriptor);
803
25.2k
        }
804
805
61.5k
        ps_slice_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
806
61.5k
        isvce_nalu_info_buf_init(ps_slice_nalu_info, -((WORD32) isvce_get_num_bits(ps_bitstrm)),
807
61.5k
                                 ps_slice_hdr->i1_nal_unit_type, ps_proc->u1_spatial_layer_id,
808
61.5k
                                 ps_proc->ps_cur_pic->i1_temporal_id, 1, !!ps_proc->u4_is_idr);
809
810
61.5k
        if(ps_proc->u1_spatial_layer_id > 0)
811
32.9k
        {
812
32.9k
            ps_subset_sps = ps_entropy->ps_subset_sps_base + ps_proc->u1_spatial_layer_id;
813
32.9k
            ps_pps = ps_entropy->ps_pps_base + ps_proc->u1_spatial_layer_id;
814
815
32.9k
            ps_entropy->i4_error_code = isvce_generate_svc_nalu_extension(
816
32.9k
                ps_bitstrm, aps_svc_nalu_ext[1], NAL_CODED_SLICE_EXTENSION);
817
818
32.9k
            ps_entropy->i4_error_code = isvce_generate_slice_header_svc(
819
32.9k
                ps_bitstrm, ps_pps, aps_svc_nalu_ext[1], ps_svc_slice_hdr, ps_subset_sps);
820
821
32.9k
            RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
822
32.9k
        }
823
28.5k
        else
824
28.5k
        {
825
            /* generate slice header */
826
28.5k
            ps_entropy->i4_error_code = isvce_generate_slice_header(
827
28.5k
                ps_bitstrm, ps_slice_hdr, ps_pps, ps_sps, aps_svc_nalu_ext[0]->u1_idr_flag);
828
829
28.5k
            RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
830
28.5k
        }
831
832
        /* once start of frame / slice is done, you can reset it */
833
        /* it is the responsibility of the caller to set this flag */
834
61.5k
        ps_entropy->i4_sof = 0;
835
836
61.5k
        if(CABAC == ps_entropy->u1_entropy_coding_mode_flag)
837
9.37k
        {
838
9.37k
            BITSTREAM_BYTE_ALIGN(ps_bitstrm);
839
9.37k
            BITSTREAM_FLUSH(ps_bitstrm, ps_entropy->i4_error_code);
840
9.37k
            isvce_init_cabac_ctxt(ps_entropy, ps_slice_hdr);
841
9.37k
        }
842
843
61.5k
#if ENABLE_RE_ENC_AS_SKIP
844
61.5k
        ps_bitstrm_after_slice_hdr[0] = ps_bitstrm[0];
845
61.5k
#endif
846
61.5k
    }
847
848
    /* begin entropy coding for the mb set */
849
9.71M
    while(u4_mb_idx < u4_mb_end_idx)
850
9.39M
    {
851
9.39M
        mb_bits_info_t s_mb_bits = {
852
9.39M
            .i8_header_bits = -((WORD64) ps_entropy->u4_header_bits[i4_slice_type == PSLICE]),
853
9.39M
            .i8_texture_bits = -((WORD64) ps_entropy->u4_residue_bits[i4_slice_type == PSLICE])};
854
855
        /* init ptrs/indices */
856
9.39M
        if(ps_entropy->i4_mb_x == i4_wd_mbs)
857
0
        {
858
0
            ps_entropy->i4_mb_y++;
859
0
            ps_entropy->i4_mb_x = 0;
860
861
            /* packed mb coeff data */
862
0
            ps_entropy->pv_mb_coeff_data = ((UWORD8 *) ps_entropy->pv_pic_mb_coeff_data) +
863
0
                                           ps_entropy->i4_mb_y * ps_codec->u4_size_coeff_data;
864
865
            /* packed mb header data */
866
0
            ps_entropy->pv_mb_header_data = ((UWORD8 *) ps_entropy->pv_pic_mb_header_data) +
867
0
                                            ps_entropy->i4_mb_y * ps_codec->u4_size_header_data;
868
869
            /* proc map */
870
0
            pu1_proc_map = ps_proc->pu1_proc_map + ps_entropy->i4_mb_y * i4_wd_mbs;
871
872
            /* entropy map */
873
0
            pu1_entropy_map_curr = ps_entropy->pu1_entropy_map + ps_entropy->i4_mb_y * i4_wd_mbs;
874
0
        }
875
876
9.39M
        DEBUG("\nmb indices x, y %d, %d", ps_entropy->i4_mb_x, ps_entropy->i4_mb_y);
877
9.39M
        ENTROPY_TRACE("mb index x %d", ps_entropy->i4_mb_x);
878
9.39M
        ENTROPY_TRACE("mb index y %d", ps_entropy->i4_mb_y);
879
880
        /* wait until the curr mb is core coded */
881
        /* The wait for curr mb to be core coded is essential when entropy is
882
         * launched as a separate job
883
         */
884
9.39M
        while(1)
885
9.39M
        {
886
9.39M
            volatile UWORD8 *pu1_buf1;
887
9.39M
            WORD32 idx = ps_entropy->i4_mb_x;
888
889
9.39M
            pu1_buf1 = pu1_proc_map + idx;
890
9.39M
            if(*pu1_buf1) break;
891
17
            ithread_yield();
892
17
        }
893
894
        /* write mb layer */
895
9.39M
        ps_entropy->i4_error_code =
896
9.39M
            ps_codec->pf_write_mb_syntax_layer[ps_entropy->u1_entropy_coding_mode_flag]
897
9.39M
                                              [i4_slice_type](ps_entropy);
898
9.39M
        RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
899
900
        /* Starting bitstream offset for header in bits */
901
9.39M
        bitstream_start_offset = isvce_get_num_bits(ps_bitstrm);
902
903
        /* set entropy map */
904
9.39M
        pu1_entropy_map_curr[ps_entropy->i4_mb_x] = 1;
905
9.39M
        ASSERT(ps_entropy->i4_mb_x < i4_wd_mbs);
906
907
9.39M
        u4_mb_idx++;
908
9.39M
        ps_entropy->i4_mb_x++;
909
        /* check for eof */
910
9.39M
        if(CABAC == ps_entropy->u1_entropy_coding_mode_flag)
911
4.40M
        {
912
4.40M
            if(ps_entropy->i4_mb_x < i4_wd_mbs)
913
4.31M
            {
914
4.31M
                isvce_cabac_encode_terminate(ps_cabac_ctxt, 0);
915
4.31M
            }
916
4.40M
        }
917
918
9.39M
        if(ps_entropy->i4_mb_x == i4_wd_mbs)
919
322k
        {
920
            /* if slices are enabled */
921
322k
            if(ps_codec->s_cfg.e_slice_mode == IVE_SLICE_MODE_BLOCKS)
922
0
            {
923
                /* current slice index */
924
0
                WORD32 i4_curr_slice_idx = ps_entropy->i4_cur_slice_idx;
925
926
                /* slice map */
927
0
                UWORD8 *pu1_slice_idx = ps_entropy->pu1_slice_idx;
928
929
                /* No need to open a slice at end of frame. The current slice can be
930
                 * closed at the time of signaling eof flag.
931
                 */
932
0
                if((u4_mb_idx != u4_mb_cnt) && (i4_curr_slice_idx != pu1_slice_idx[u4_mb_idx]))
933
0
                {
934
0
                    if(CAVLC == ps_entropy->u1_entropy_coding_mode_flag)
935
0
                    { /* mb skip run */
936
0
                        if((i4_slice_type != ISLICE) && *ps_entropy->pi4_mb_skip_run)
937
0
                        {
938
0
                            if(*ps_entropy->pi4_mb_skip_run)
939
0
                            {
940
0
                                PUT_BITS_UEV(ps_bitstrm, *ps_entropy->pi4_mb_skip_run,
941
0
                                             ps_entropy->i4_error_code, "mb skip run");
942
0
                                *ps_entropy->pi4_mb_skip_run = 0;
943
0
                                RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
944
0
                            }
945
0
                        }
946
                        /* put rbsp trailing bits for the previous slice */
947
0
                        ps_entropy->i4_error_code = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
948
0
                        RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
949
0
                    }
950
0
                    else
951
0
                    {
952
0
                        isvce_cabac_encode_terminate(ps_cabac_ctxt, 1);
953
0
                    }
954
955
                    /* update slice header pointer */
956
0
                    i4_curr_slice_idx = pu1_slice_idx[u4_mb_idx];
957
0
                    ps_entropy->i4_cur_slice_idx = i4_curr_slice_idx;
958
0
                    ps_slice_hdr =
959
0
                        ps_entropy->ps_slice_hdr_base + (i4_curr_slice_idx % SVC_MAX_SLICE_HDR_CNT);
960
961
0
                    ps_entropy->u1_spatial_layer_id = ps_proc->u1_spatial_layer_id;
962
963
                    /* populate slice header */
964
0
                    ps_entropy->i4_mb_start_add = u4_mb_idx;
965
966
                    /* generate slice header */
967
0
                    if(ps_proc->u1_spatial_layer_id > 0)
968
0
                    {
969
0
                        ps_entropy->i4_error_code =
970
0
                            isvce_generate_slice_header_svc(ps_bitstrm, ps_pps, aps_svc_nalu_ext[1],
971
0
                                                            ps_svc_slice_hdr, ps_subset_sps);
972
973
0
                        RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
974
975
0
                        ps_slice_hdr = &ps_svc_slice_hdr->s_slice_header;
976
0
                    }
977
0
                    else
978
0
                    {
979
0
                        ps_entropy->i4_error_code =
980
0
                            isvce_populate_slice_header(ps_proc, ps_slice_hdr, ps_pps, ps_sps,
981
0
                                                        aps_svc_nalu_ext[0]->u1_idr_flag);
982
983
0
                        RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
984
985
0
                        ps_entropy->i4_error_code =
986
0
                            isvce_generate_slice_header(ps_bitstrm, ps_slice_hdr, ps_pps, ps_sps,
987
0
                                                        aps_svc_nalu_ext[0]->u1_idr_flag);
988
989
0
                        RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
990
0
                    }
991
992
0
                    if(CABAC == ps_entropy->u1_entropy_coding_mode_flag)
993
0
                    {
994
0
                        BITSTREAM_BYTE_ALIGN(ps_bitstrm);
995
0
                        BITSTREAM_FLUSH(ps_bitstrm, ps_entropy->i4_error_code);
996
0
                        isvce_init_cabac_ctxt(ps_entropy, ps_slice_hdr);
997
0
                    }
998
0
                }
999
0
                else
1000
0
                {
1001
0
                    if(CABAC == ps_entropy->u1_entropy_coding_mode_flag && u4_mb_idx != u4_mb_cnt)
1002
0
                    {
1003
0
                        isvce_cabac_encode_terminate(ps_cabac_ctxt, 0);
1004
0
                    }
1005
0
                }
1006
0
            }
1007
322k
        }
1008
1009
        /* Ending bitstream offset for header in bits */
1010
9.39M
        bitstream_end_offset = isvce_get_num_bits(ps_bitstrm);
1011
9.39M
        ps_entropy->u4_header_bits[i4_slice_type == PSLICE] +=
1012
9.39M
            bitstream_end_offset - bitstream_start_offset;
1013
1014
9.39M
        {
1015
9.39M
            svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt = ps_proc->ps_sub_pic_rc_ctxt;
1016
9.39M
            svc_sub_pic_rc_entropy_variables_t *ps_sub_pic_rc_variables =
1017
9.39M
                &ps_sub_pic_rc_ctxt->s_sub_pic_rc_entropy_variables;
1018
1019
9.39M
            s_mb_bits.i8_header_bits += ps_entropy->u4_header_bits[i4_slice_type == PSLICE];
1020
9.39M
            s_mb_bits.i8_texture_bits += ps_entropy->u4_residue_bits[i4_slice_type == PSLICE];
1021
1022
9.39M
            ps_sub_pic_rc_variables->s_mb_bits = s_mb_bits;
1023
9.39M
            ps_sub_pic_rc_variables->u1_spatial_layer_id = ps_proc->u1_spatial_layer_id;
1024
9.39M
            ps_sub_pic_rc_variables->s_mb_pos.i4_abscissa = ps_entropy->i4_mb_x - 1;
1025
9.39M
            ps_sub_pic_rc_variables->s_mb_pos.i4_ordinate = ps_entropy->i4_mb_y;
1026
1027
9.39M
            isvce_sub_pic_rc_get_entropy_data(ps_proc->ps_sub_pic_rc_ctxt);
1028
9.39M
        }
1029
9.39M
    }
1030
1031
    /* check for eof */
1032
322k
    if(u4_mb_idx == u4_mb_cnt)
1033
61.1k
    {
1034
        /* set end of frame flag */
1035
61.1k
        ps_entropy->i4_eof = 1;
1036
61.1k
    }
1037
260k
    else
1038
260k
    {
1039
260k
        if(CABAC == ps_entropy->u1_entropy_coding_mode_flag &&
1040
81.3k
           ps_codec->s_cfg.e_slice_mode != IVE_SLICE_MODE_BLOCKS)
1041
81.3k
        {
1042
81.3k
            isvce_cabac_encode_terminate(ps_cabac_ctxt, 0);
1043
81.3k
        }
1044
260k
    }
1045
1046
322k
    if(ps_entropy->i4_eof)
1047
61.1k
    {
1048
61.1k
        if(CAVLC == ps_entropy->u1_entropy_coding_mode_flag)
1049
51.9k
        {
1050
            /* mb skip run */
1051
51.9k
            if((i4_slice_type != ISLICE) && *ps_entropy->pi4_mb_skip_run)
1052
5.61k
            {
1053
5.61k
                if(*ps_entropy->pi4_mb_skip_run)
1054
5.61k
                {
1055
5.61k
                    PUT_BITS_UEV(ps_bitstrm, *ps_entropy->pi4_mb_skip_run,
1056
5.61k
                                 ps_entropy->i4_error_code, "mb skip run");
1057
5.61k
                    *ps_entropy->pi4_mb_skip_run = 0;
1058
5.61k
                    RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
1059
5.61k
                }
1060
5.61k
            }
1061
            /* put rbsp trailing bits */
1062
51.9k
            ps_entropy->i4_error_code = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
1063
51.9k
            RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
1064
51.9k
        }
1065
9.22k
        else
1066
9.22k
        {
1067
9.22k
            isvce_cabac_encode_terminate(ps_cabac_ctxt, 1);
1068
9.22k
        }
1069
1070
        /* update current frame stats to rc library */
1071
        /* number of bytes to stuff */
1072
61.1k
        {
1073
61.1k
            WORD32 i4_stuff_bytes;
1074
1075
            /* update */
1076
61.1k
            i4_stuff_bytes = isvce_update_rc_post_enc(ps_codec, ctxt_sel, (ps_codec->i4_poc == 0));
1077
1078
61.1k
            if(ps_proc->u1_spatial_layer_id == (ps_proc->s_svc_params.u1_num_spatial_layers - 1))
1079
28.1k
            {
1080
                /* cbr rc - house keeping */
1081
28.1k
                if(ps_codec->s_rate_control.post_encode_skip[ctxt_sel])
1082
0
                {
1083
0
                    ps_entropy->ps_bitstrm->u4_strm_buf_offset = 0;
1084
0
                }
1085
28.1k
                else if(i4_stuff_bytes > 0)
1086
1.90k
                {
1087
                    /* add filler nal units */
1088
1.90k
                    ps_entropy->i4_error_code =
1089
1.90k
                        ih264e_add_filler_nal_unit(ps_bitstrm, i4_stuff_bytes);
1090
1.90k
                    RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
1091
1.65k
                }
1092
28.1k
            }
1093
61.1k
        }
1094
1095
        /*
1096
         *Frame number is to be incremented only if the current frame is a
1097
         * reference frame. After each successful frame encode, we increment
1098
         * frame number by 1
1099
         */
1100
60.8k
        if(!ps_codec->s_rate_control.post_encode_skip[ctxt_sel] && ps_codec->u4_is_curr_frm_ref &&
1101
60.8k
           (ps_proc->u1_spatial_layer_id == ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers - 1))
1102
27.8k
        {
1103
27.8k
            ps_codec->i4_frame_num++;
1104
27.8k
        }
1105
1106
        /********************************************************************/
1107
        /*      signal the output                                           */
1108
        /********************************************************************/
1109
60.8k
        ps_codec->as_out_buf[ctxt_sel].as_bits_buf[ps_entropy->u1_spatial_layer_id].u4_bytes =
1110
60.8k
            ps_bitstrm->u4_strm_buf_offset;
1111
1112
60.8k
        ps_slice_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
1113
60.8k
        ps_slice_nalu_info->i8_num_bits += isvce_get_num_bits(ps_bitstrm);
1114
60.8k
        isvce_update_nalu_count(ps_nalu_descriptor);
1115
1116
60.8k
        DEBUG("entropy status %x", ps_entropy->i4_error_code);
1117
60.8k
        ps_entropy->i4_eof = 0;
1118
60.8k
    }
1119
1120
    /* Dont execute any further instructions until store synchronization took
1121
     * place */
1122
321k
    DATA_SYNC();
1123
1124
    /* allow threads to dequeue entropy jobs */
1125
321k
    ps_codec->ae_entropy_thread_exit_state[ctxt_sel] = INACTIVE;
1126
1127
321k
    return ps_entropy->i4_error_code;
1128
322k
}
1129
1130
/**
1131
*******************************************************************************
1132
*
1133
* @brief Packs header information of a mb in to a buffer
1134
*
1135
* @par Description:
1136
*  After the deciding the mode info of a macroblock, the syntax elements
1137
*  associated with the mb are packed and stored. The entropy thread unpacks
1138
*  this buffer and generates the end bit stream.
1139
*
1140
* @param[in] ps_proc
1141
*  Pointer to the current process context
1142
*
1143
* @returns error status
1144
*
1145
* @remarks none
1146
*
1147
*******************************************************************************
1148
*/
1149
IH264E_ERROR_T isvce_pack_header_data(isvce_process_ctxt_t *ps_proc)
1150
9.29M
{
1151
    /* curr mb type */
1152
9.29M
    UWORD32 u4_mb_type = ps_proc->ps_mb_info->u2_mb_type;
1153
1154
    /* pack mb syntax layer of curr mb (used for entropy coding) */
1155
9.29M
    if(u4_mb_type == I4x4)
1156
549k
    {
1157
        /* pointer to mb header storage space */
1158
549k
        UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
1159
549k
        isvce_mb_hdr_i4x4_t *ps_mb_hdr = (isvce_mb_hdr_i4x4_t *) ps_proc->pv_mb_header_data;
1160
1161
        /* temp var */
1162
549k
        WORD32 i4, byte;
1163
1164
        /* mb type plus mode */
1165
549k
        ps_mb_hdr->common.u1_mb_type_mode = (ps_proc->u1_c_i8_mode << 6) + u4_mb_type;
1166
1167
        /* cbp */
1168
549k
        ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
1169
1170
        /* mb qp delta */
1171
549k
        ps_mb_hdr->common.u1_mb_qp = ps_proc->u1_mb_qp;
1172
1173
549k
        ps_mb_hdr->common.u1_residual_prediction_flag =
1174
549k
            ps_proc->ps_mb_info->u1_residual_prediction_flag;
1175
1176
549k
        ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
1177
1178
        /* sub mb modes */
1179
4.93M
        for(i4 = 0; i4 < 16; i4++)
1180
4.38M
        {
1181
4.38M
            byte = 0;
1182
1183
4.38M
            if(ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i4] ==
1184
4.38M
               ps_proc->au1_intra_luma_mb_4x4_modes[i4])
1185
3.70M
            {
1186
3.70M
                byte |= 1;
1187
3.70M
            }
1188
675k
            else
1189
675k
            {
1190
675k
                if(ps_proc->au1_intra_luma_mb_4x4_modes[i4] <
1191
675k
                   ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i4])
1192
252k
                {
1193
252k
                    byte |= (ps_proc->au1_intra_luma_mb_4x4_modes[i4] << 1);
1194
252k
                }
1195
422k
                else
1196
422k
                {
1197
422k
                    byte |= (ps_proc->au1_intra_luma_mb_4x4_modes[i4] - 1) << 1;
1198
422k
                }
1199
675k
            }
1200
1201
4.38M
            i4++;
1202
1203
4.38M
            if(ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i4] ==
1204
4.38M
               ps_proc->au1_intra_luma_mb_4x4_modes[i4])
1205
3.75M
            {
1206
3.75M
                byte |= 16;
1207
3.75M
            }
1208
627k
            else
1209
627k
            {
1210
627k
                if(ps_proc->au1_intra_luma_mb_4x4_modes[i4] <
1211
627k
                   ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i4])
1212
197k
                {
1213
197k
                    byte |= (ps_proc->au1_intra_luma_mb_4x4_modes[i4] << 5);
1214
197k
                }
1215
430k
                else
1216
430k
                {
1217
430k
                    byte |= (ps_proc->au1_intra_luma_mb_4x4_modes[i4] - 1) << 5;
1218
430k
                }
1219
627k
            }
1220
1221
4.38M
            ps_mb_hdr->au1_sub_blk_modes[i4 >> 1] = byte;
1222
4.38M
        }
1223
1224
        /* end of mb layer */
1225
549k
        pu1_ptr += sizeof(isvce_mb_hdr_i4x4_t);
1226
549k
        ps_proc->pv_mb_header_data = pu1_ptr;
1227
549k
    }
1228
8.74M
    else if(u4_mb_type == I16x16)
1229
5.11M
    {
1230
        /* pointer to mb header storage space */
1231
5.11M
        UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
1232
5.11M
        isvce_mb_hdr_i16x16_t *ps_mb_hdr = (isvce_mb_hdr_i16x16_t *) ps_proc->pv_mb_header_data;
1233
1234
        /* mb type plus mode */
1235
5.11M
        ps_mb_hdr->common.u1_mb_type_mode =
1236
5.11M
            (ps_proc->u1_c_i8_mode << 6) + (ps_proc->u1_l_i16_mode << 4) + u4_mb_type;
1237
1238
        /* cbp */
1239
5.11M
        ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
1240
1241
        /* mb qp delta */
1242
5.11M
        ps_mb_hdr->common.u1_mb_qp = ps_proc->u1_mb_qp;
1243
1244
5.11M
        ps_mb_hdr->common.u1_residual_prediction_flag =
1245
5.11M
            ps_proc->ps_mb_info->u1_residual_prediction_flag;
1246
1247
5.11M
        ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
1248
1249
        /* end of mb layer */
1250
5.11M
        pu1_ptr += sizeof(isvce_mb_hdr_i16x16_t);
1251
5.11M
        ps_proc->pv_mb_header_data = pu1_ptr;
1252
5.11M
    }
1253
3.63M
    else if(u4_mb_type == P16x16)
1254
518k
    {
1255
        /* pointer to mb header storage space */
1256
518k
        UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
1257
518k
        isvce_mb_hdr_p16x16_t *ps_mb_hdr = (isvce_mb_hdr_p16x16_t *) ps_proc->pv_mb_header_data;
1258
1259
        /* mb type */
1260
518k
        ps_mb_hdr->common.u1_mb_type_mode = u4_mb_type;
1261
1262
        /* cbp */
1263
518k
        ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
1264
1265
        /* mb qp delta */
1266
518k
        ps_mb_hdr->common.u1_mb_qp = ps_proc->u1_mb_qp;
1267
1268
518k
        ps_mb_hdr->common.u1_residual_prediction_flag =
1269
518k
            ps_proc->ps_mb_info->u1_residual_prediction_flag;
1270
1271
518k
        ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
1272
1273
518k
        ps_mb_hdr->u1_mvp_idx = ps_proc->ps_mb_info->as_pu->au1_mvp_idx[L0];
1274
1275
518k
        if(0 == ps_proc->ps_mb_info->as_pu->au1_mvp_idx[L0])
1276
479k
        {
1277
479k
            ps_mb_hdr->ai2_mvd[0] = ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvx -
1278
479k
                                    ps_proc->ps_pred_mv[L0].s_mv.i2_mvx;
1279
479k
            ps_mb_hdr->ai2_mvd[1] = ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvy -
1280
479k
                                    ps_proc->ps_pred_mv[L0].s_mv.i2_mvy;
1281
479k
        }
1282
38.7k
        else
1283
38.7k
        {
1284
38.7k
            ps_mb_hdr->ai2_mvd[0] = ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvx -
1285
38.7k
                                    ps_proc->ps_ilp_mv->as_mv[0][L0].s_mv.i2_mvx;
1286
38.7k
            ps_mb_hdr->ai2_mvd[1] = ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvy -
1287
38.7k
                                    ps_proc->ps_ilp_mv->as_mv[0][L0].s_mv.i2_mvy;
1288
38.7k
        }
1289
1290
        /* end of mb layer */
1291
518k
        pu1_ptr += sizeof(isvce_mb_hdr_p16x16_t);
1292
518k
        ps_proc->pv_mb_header_data = pu1_ptr;
1293
518k
    }
1294
3.11M
    else if(u4_mb_type == PSKIP)
1295
368k
    {
1296
        /* pointer to mb header storage space */
1297
368k
        UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
1298
368k
        isvce_mb_hdr_pskip_t *ps_mb_hdr = (isvce_mb_hdr_pskip_t *) ps_proc->pv_mb_header_data;
1299
1300
        /* mb type */
1301
368k
        ps_mb_hdr->common.u1_mb_type_mode = u4_mb_type;
1302
1303
368k
        ps_mb_hdr->common.u1_residual_prediction_flag =
1304
368k
            ps_proc->ps_mb_info->u1_residual_prediction_flag;
1305
1306
368k
        ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
1307
1308
        /* end of mb layer */
1309
368k
        pu1_ptr += sizeof(isvce_mb_hdr_pskip_t);
1310
368k
        ps_proc->pv_mb_header_data = pu1_ptr;
1311
368k
    }
1312
2.74M
    else if(u4_mb_type == B16x16)
1313
0
    {
1314
0
        WORD32 i;
1315
1316
        /* pointer to mb header storage space */
1317
0
        UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
1318
0
        isvce_mb_hdr_b16x16_t *ps_mb_hdr = (isvce_mb_hdr_b16x16_t *) ps_proc->pv_mb_header_data;
1319
1320
0
        UWORD32 u4_pred_mode = ps_proc->ps_mb_info->as_pu->u1_pred_mode;
1321
1322
        /* mb type plus mode */
1323
0
        ps_mb_hdr->common.u1_mb_type_mode = (u4_pred_mode << 4) + u4_mb_type;
1324
1325
        /* cbp */
1326
0
        ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
1327
1328
        /* mb qp delta */
1329
0
        ps_mb_hdr->common.u1_mb_qp = ps_proc->u1_mb_qp;
1330
1331
0
        ps_mb_hdr->common.u1_residual_prediction_flag =
1332
0
            ps_proc->ps_mb_info->u1_residual_prediction_flag;
1333
1334
0
        ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
1335
1336
0
        for(i = 0; i < NUM_PRED_DIRS; i++)
1337
0
        {
1338
0
            PRED_MODE_T e_pred_mode = (PRED_MODE_T) i;
1339
0
            PRED_MODE_T e_cmpl_pred_mode = (e_pred_mode == L0) ? L1 : L0;
1340
1341
0
            if(u4_pred_mode != e_pred_mode)
1342
0
            {
1343
0
                ps_mb_hdr->au1_mvp_idx[e_cmpl_pred_mode] =
1344
0
                    ps_proc->ps_mb_info->as_pu->au1_mvp_idx[e_cmpl_pred_mode];
1345
1346
0
                if(0 == ps_proc->ps_mb_info->as_pu->au1_mvp_idx[e_cmpl_pred_mode])
1347
0
                {
1348
0
                    ps_mb_hdr->ai2_mvd[e_cmpl_pred_mode][0] =
1349
0
                        ps_proc->ps_mb_info->as_pu->as_me_info[e_cmpl_pred_mode].s_mv.i2_mvx -
1350
0
                        ps_proc->ps_pred_mv[e_cmpl_pred_mode].s_mv.i2_mvx;
1351
0
                    ps_mb_hdr->ai2_mvd[e_cmpl_pred_mode][1] =
1352
0
                        ps_proc->ps_mb_info->as_pu->as_me_info[e_cmpl_pred_mode].s_mv.i2_mvy -
1353
0
                        ps_proc->ps_pred_mv[e_cmpl_pred_mode].s_mv.i2_mvy;
1354
0
                }
1355
0
                else
1356
0
                {
1357
0
                    ps_mb_hdr->ai2_mvd[e_cmpl_pred_mode][0] =
1358
0
                        ps_proc->ps_mb_info->as_pu->as_me_info[e_cmpl_pred_mode].s_mv.i2_mvx -
1359
0
                        ps_proc->ps_ilp_mv->as_mv[0][e_cmpl_pred_mode].s_mv.i2_mvx;
1360
0
                    ps_mb_hdr->ai2_mvd[e_cmpl_pred_mode][1] =
1361
0
                        ps_proc->ps_mb_info->as_pu->as_me_info[e_cmpl_pred_mode].s_mv.i2_mvy -
1362
0
                        ps_proc->ps_ilp_mv->as_mv[0][e_cmpl_pred_mode].s_mv.i2_mvy;
1363
0
                }
1364
0
            }
1365
0
        }
1366
1367
        /* end of mb layer */
1368
0
        pu1_ptr += sizeof(isvce_mb_hdr_b16x16_t);
1369
0
        ps_proc->pv_mb_header_data = pu1_ptr;
1370
0
    }
1371
2.74M
    else if(u4_mb_type == BDIRECT)
1372
0
    {
1373
        /* pointer to mb header storage space */
1374
0
        UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
1375
0
        isvce_mb_hdr_bdirect_t *ps_mb_hdr = (isvce_mb_hdr_bdirect_t *) ps_proc->pv_mb_header_data;
1376
1377
        /* mb type plus mode */
1378
0
        ps_mb_hdr->common.u1_mb_type_mode = u4_mb_type;
1379
1380
        /* cbp */
1381
0
        ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
1382
1383
        /* mb qp delta */
1384
0
        ps_mb_hdr->common.u1_mb_qp = ps_proc->u1_mb_qp;
1385
1386
0
        ps_mb_hdr->common.u1_residual_prediction_flag =
1387
0
            ps_proc->ps_mb_info->u1_residual_prediction_flag;
1388
1389
0
        ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
1390
1391
        /* end of mb layer */
1392
0
        pu1_ptr += sizeof(isvce_mb_hdr_bdirect_t);
1393
0
        ps_proc->pv_mb_header_data = pu1_ptr;
1394
0
    }
1395
2.74M
    else if(u4_mb_type == BSKIP)
1396
0
    {
1397
0
        UWORD32 u4_pred_mode = ps_proc->ps_mb_info->as_pu->u1_pred_mode;
1398
1399
        /* pointer to mb header storage space */
1400
0
        UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
1401
0
        isvce_mb_hdr_bskip_t *ps_mb_hdr = (isvce_mb_hdr_bskip_t *) ps_proc->pv_mb_header_data;
1402
1403
        /* mb type plus mode */
1404
0
        ps_mb_hdr->common.u1_mb_type_mode = (u4_pred_mode << 4) + u4_mb_type;
1405
1406
0
        ps_mb_hdr->common.u1_residual_prediction_flag =
1407
0
            ps_proc->ps_mb_info->u1_residual_prediction_flag;
1408
1409
0
        ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
1410
1411
        /* end of mb layer */
1412
0
        pu1_ptr += sizeof(isvce_mb_hdr_bskip_t);
1413
0
        ps_proc->pv_mb_header_data = pu1_ptr;
1414
0
    }
1415
2.74M
    else if(u4_mb_type == BASE_MODE)
1416
2.75M
    {
1417
2.75M
        isvce_mb_hdr_base_mode_t *ps_mb_hdr =
1418
2.75M
            (isvce_mb_hdr_base_mode_t *) ps_proc->pv_mb_header_data;
1419
1420
2.75M
        UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
1421
1422
2.75M
        ASSERT(ps_proc->ps_mb_info->u1_base_mode_flag == 1);
1423
1424
2.75M
        ps_mb_hdr->common.u1_mb_type_mode = u4_mb_type;
1425
1426
2.75M
        ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
1427
1428
2.75M
        ps_mb_hdr->common.u1_mb_qp = ps_proc->u1_mb_qp;
1429
1430
2.75M
        ps_mb_hdr->common.u1_residual_prediction_flag =
1431
2.75M
            ps_proc->ps_mb_info->u1_residual_prediction_flag;
1432
1433
2.75M
        ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
1434
1435
2.75M
        pu1_ptr += sizeof(isvce_mb_hdr_base_mode_t);
1436
2.75M
        ps_proc->pv_mb_header_data = pu1_ptr;
1437
2.75M
    }
1438
1439
9.30M
    return IH264E_SUCCESS;
1440
9.29M
}
1441
1442
/**
1443
*******************************************************************************
1444
*
1445
* @brief   update process context after encoding an mb. This involves preserving
1446
* the current mb information for later use, initialize the proc ctxt elements to
1447
* encode next mb.
1448
*
1449
* @par Description:
1450
*  This function performs house keeping tasks after encoding an mb.
1451
*  After encoding an mb, various elements of the process context needs to be
1452
*  updated to encode the next mb. For instance, the source, recon and reference
1453
*  pointers, mb indices have to be adjusted to the next mb. The slice index of
1454
*  the current mb needs to be updated. If mb qp modulation is enabled, then if
1455
*  the qp changes the quant param structure needs to be updated. Also to
1456
*encoding the next mb, the current mb info is used as part of mode prediction or
1457
*mv prediction. Hence the current mb info has to preserved at top/top left/left
1458
*  locations.
1459
*
1460
* @param[in] ps_proc
1461
*  Pointer to the current process context
1462
*
1463
* @returns none
1464
*
1465
* @remarks none
1466
*
1467
*******************************************************************************
1468
*/
1469
WORD32 isvce_update_proc_ctxt(isvce_process_ctxt_t *ps_proc)
1470
9.37M
{
1471
    /* error status */
1472
9.37M
    WORD32 error_status = IH264_SUCCESS;
1473
1474
    /* codec context */
1475
9.37M
    isvce_codec_t *ps_codec = ps_proc->ps_codec;
1476
9.37M
    isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
1477
9.37M
    mem_fxns_t *ps_mem_fxns = &ps_isa_dependent_fxns->s_mem_fxns;
1478
1479
    /* curr mb indices */
1480
9.37M
    WORD32 i4_mb_x = ps_proc->i4_mb_x;
1481
9.37M
    WORD32 i4_mb_y = ps_proc->i4_mb_y;
1482
1483
    /* mb syntax elements of neighbors */
1484
9.37M
    isvce_mb_info_t *ps_left_syn = ps_proc->s_nbr_info.ps_left_mb_info;
1485
9.37M
    isvce_mb_info_t *ps_top_syn =
1486
9.37M
        ps_proc->s_nbr_info_base.ps_layer_nbr_info[ps_proc->u1_spatial_layer_id]
1487
9.37M
            .ps_top_row_mb_info +
1488
9.37M
        i4_mb_x + i4_mb_y * ps_proc->i4_wd_mbs;
1489
1490
    /* curr mb type */
1491
9.37M
    UWORD32 u4_mb_type = ps_proc->ps_mb_info->u2_mb_type;
1492
1493
    /* curr mb type */
1494
9.37M
    UWORD32 u4_is_intra = ps_proc->ps_mb_info->u1_is_intra;
1495
1496
    /* width in mbs */
1497
9.37M
    WORD32 i4_wd_mbs = ps_proc->i4_wd_mbs;
1498
1499
    /*height in mbs*/
1500
9.37M
    WORD32 i4_ht_mbs = ps_proc->i4_ht_mbs;
1501
1502
    /* proc map */
1503
9.37M
    UWORD8 *pu1_proc_map = ps_proc->pu1_proc_map + (i4_mb_y * i4_wd_mbs);
1504
1505
    /* deblk context */
1506
9.37M
    isvce_deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
1507
1508
    /* deblk bs context */
1509
9.37M
    isvce_bs_ctxt_t *ps_bs = &(ps_deblk->s_bs_ctxt);
1510
1511
    /* sub mb modes */
1512
9.37M
    UWORD8 *pu1_top_mb_intra_modes =
1513
9.37M
        (ps_proc->s_nbr_info_base.ps_layer_nbr_info[ps_proc->u1_spatial_layer_id]
1514
9.37M
             .ps_top_mb_intra_modes +
1515
9.37M
         i4_mb_x + i4_mb_y * ps_proc->i4_wd_mbs)
1516
9.37M
            ->au1_intra_modes;
1517
1518
    /*************************************************************/
1519
    /* During MV prediction, when top right mb is not available, */
1520
    /* top left mb info. is used for prediction. Hence the curr  */
1521
    /* top, which will be top left for the next mb needs to be   */
1522
    /* preserved before updating it with curr mb info.           */
1523
    /*************************************************************/
1524
1525
    /*************************************************/
1526
    /* update top and left with curr mb info results */
1527
    /*************************************************/
1528
9.37M
    ps_left_syn[0] = ps_top_syn[0] = ps_proc->ps_mb_info[0];
1529
9.37M
    ps_left_syn->u2_mb_type = ps_top_syn->u2_mb_type = u4_mb_type;
1530
9.37M
    ps_left_syn->i4_mb_distortion = ps_top_syn->i4_mb_distortion = ps_proc->i4_mb_distortion;
1531
1532
9.37M
    if(u4_is_intra)
1533
8.35M
    {
1534
        /* mb / sub mb modes */
1535
8.35M
        if(I16x16 == u4_mb_type)
1536
5.11M
        {
1537
5.11M
            pu1_top_mb_intra_modes[0] =
1538
5.11M
                ps_proc->s_nbr_info.ps_left_mb_intra_modes->au1_intra_modes[0] =
1539
5.11M
                    ps_proc->u1_l_i16_mode;
1540
5.11M
        }
1541
3.23M
        else if(I4x4 == u4_mb_type)
1542
548k
        {
1543
548k
            ps_mem_fxns->pf_mem_cpy_mul8(
1544
548k
                ps_proc->s_nbr_info.ps_left_mb_intra_modes->au1_intra_modes,
1545
548k
                ps_proc->au1_intra_luma_mb_4x4_modes, 16);
1546
548k
            ps_mem_fxns->pf_mem_cpy_mul8(pu1_top_mb_intra_modes,
1547
548k
                                         ps_proc->au1_intra_luma_mb_4x4_modes, 16);
1548
548k
        }
1549
2.68M
        else if(I8x8 == u4_mb_type)
1550
0
        {
1551
0
            memcpy(ps_proc->s_nbr_info.ps_left_mb_intra_modes->au1_intra_modes,
1552
0
                   ps_proc->au1_intra_luma_mb_8x8_modes, 4);
1553
0
            memcpy(pu1_top_mb_intra_modes, ps_proc->au1_intra_luma_mb_8x8_modes, 4);
1554
0
        }
1555
1556
8.35M
        *ps_proc->pu4_mb_pu_cnt = 1;
1557
8.35M
    }
1558
1559
    /*
1560
     * Mark that the MB has been coded intra
1561
     * So that future AIRs can skip it
1562
     */
1563
9.37M
    ps_proc->pu1_is_intra_coded[i4_mb_x + (i4_mb_y * i4_wd_mbs)] = u4_is_intra;
1564
1565
    /**************************************************/
1566
    /* pack mb header info. for entropy coding        */
1567
    /**************************************************/
1568
9.37M
    isvce_pack_header_data(ps_proc);
1569
1570
    /*
1571
     * We need to sync the cache to make sure that the nmv content of proc
1572
     * is updated to cache properly
1573
     */
1574
9.37M
    DATA_SYNC();
1575
1576
    /* Just before finishing the row, enqueue the job in to entropy queue.
1577
     * The master thread depending on its convenience shall dequeue it and
1578
     * performs entropy.
1579
     *
1580
     * WARN !! Placing this block post proc map update can cause queuing of
1581
     * entropy jobs in out of order.
1582
     */
1583
9.37M
    if(i4_mb_x == i4_wd_mbs - 1)
1584
322k
    {
1585
        /* job structures */
1586
322k
        job_t s_job;
1587
1588
        /* job class */
1589
322k
        s_job.i4_cmd = CMD_ENTROPY;
1590
1591
        /* number of mbs to be processed in the current job */
1592
322k
        s_job.i2_mb_cnt = ps_proc->i4_wd_mbs;
1593
1594
        /* job start index x */
1595
322k
        s_job.i2_mb_x = 0;
1596
1597
        /* job start index y */
1598
322k
        s_job.i2_mb_y = ps_proc->i4_mb_y;
1599
1600
        /* queue the job */
1601
322k
        error_status = ih264_list_queue(ps_proc->pv_entropy_jobq, &s_job, 1);
1602
1603
322k
        if(error_status != IH264_SUCCESS)
1604
0
        {
1605
0
            return error_status;
1606
0
        }
1607
1608
322k
        if(ps_proc->i4_mb_y == (i4_ht_mbs - 1))
1609
61.3k
        {
1610
61.3k
            ih264_list_terminate(ps_codec->pv_entropy_jobq);
1611
61.3k
        }
1612
322k
    }
1613
1614
    /* update proc map */
1615
9.37M
    pu1_proc_map[i4_mb_x] = 1;
1616
9.37M
    ASSERT(i4_mb_x < i4_wd_mbs);
1617
1618
    /**************************************************/
1619
    /* update proc ctxt elements for encoding next mb */
1620
    /**************************************************/
1621
    /* update indices */
1622
9.37M
    i4_mb_x++;
1623
9.36M
    ps_proc->i4_mb_x = i4_mb_x;
1624
1625
9.36M
    if(ps_proc->i4_mb_x == i4_wd_mbs)
1626
322k
    {
1627
322k
        ps_proc->i4_mb_y++;
1628
322k
        ps_proc->i4_mb_x = 0;
1629
322k
    }
1630
1631
    /* update slice index */
1632
9.36M
    ps_proc->i4_cur_slice_idx =
1633
9.36M
        ps_proc->pu1_slice_idx[ps_proc->i4_mb_y * i4_wd_mbs + ps_proc->i4_mb_x];
1634
1635
    /* update buffers pointers */
1636
9.36M
    ps_proc->s_src_buf_props.as_component_bufs[0].pv_data =
1637
9.36M
        ((UWORD8 *) ps_proc->s_src_buf_props.as_component_bufs[0].pv_data) + MB_SIZE;
1638
9.36M
    ps_proc->s_rec_buf_props.as_component_bufs[0].pv_data =
1639
9.36M
        ((UWORD8 *) ps_proc->s_rec_buf_props.as_component_bufs[0].pv_data) + MB_SIZE;
1640
9.36M
    ps_proc->as_ref_buf_props[0].as_component_bufs[0].pv_data =
1641
9.36M
        ((UWORD8 *) ps_proc->as_ref_buf_props[0].as_component_bufs[0].pv_data) + MB_SIZE;
1642
9.36M
    ps_proc->as_ref_buf_props[1].as_component_bufs[0].pv_data =
1643
9.36M
        ((UWORD8 *) ps_proc->as_ref_buf_props[1].as_component_bufs[0].pv_data) + MB_SIZE;
1644
1645
    /*
1646
     * Note: Although chroma mb size is 8, as the chroma buffers are
1647
     * interleaved, the stride per MB is MB_SIZE
1648
     */
1649
9.36M
    ps_proc->s_src_buf_props.as_component_bufs[1].pv_data =
1650
9.36M
        ((UWORD8 *) ps_proc->s_src_buf_props.as_component_bufs[1].pv_data) + MB_SIZE;
1651
9.36M
    ps_proc->s_rec_buf_props.as_component_bufs[1].pv_data =
1652
9.36M
        ((UWORD8 *) ps_proc->s_rec_buf_props.as_component_bufs[1].pv_data) + MB_SIZE;
1653
9.36M
    ps_proc->as_ref_buf_props[0].as_component_bufs[1].pv_data =
1654
9.36M
        ((UWORD8 *) ps_proc->as_ref_buf_props[0].as_component_bufs[1].pv_data) + MB_SIZE;
1655
9.36M
    ps_proc->as_ref_buf_props[1].as_component_bufs[1].pv_data =
1656
9.36M
        ((UWORD8 *) ps_proc->as_ref_buf_props[1].as_component_bufs[1].pv_data) + MB_SIZE;
1657
1658
    /* Reset cost, distortion params */
1659
9.36M
    ps_proc->i4_mb_cost = INT_MAX;
1660
9.36M
    ps_proc->i4_mb_distortion = SHRT_MAX;
1661
1662
9.36M
    ps_proc->ps_mb_info++;
1663
9.36M
    ps_proc->pu4_mb_pu_cnt++;
1664
1665
    /* Update colocated pu */
1666
9.36M
    if(ps_proc->i4_slice_type == BSLICE)
1667
0
    {
1668
0
        ps_proc->ps_col_mb++;
1669
0
    }
1670
1671
9.36M
    if(ps_proc->u4_disable_deblock_level != 1)
1672
7.10M
    {
1673
7.10M
        ps_bs->i4_mb_x = ps_proc->i4_mb_x;
1674
7.10M
        ps_bs->i4_mb_y = ps_proc->i4_mb_y;
1675
1676
#ifndef N_MB_ENABLE /* For N MB processing update take place inside deblocking \
1677
                       function */
1678
        ASSERT(0);
1679
        ps_deblk->i4_mb_x++;
1680
1681
        ((UWORD8 *) ps_deblk->s_rec_pic_buf_props.as_component_bufs[0].pv_data) += MB_SIZE;
1682
        /*
1683
         * Note: Although chroma mb size is 8, as the chroma buffers are
1684
         * interleaved, the stride per MB is MB_SIZE
1685
         */
1686
        ((UWORD8 *) ps_deblk->s_rec_pic_buf_props.as_component_bufs[1].pv_data) += MB_SIZE;
1687
#endif
1688
7.10M
    }
1689
1690
9.36M
    return error_status;
1691
9.37M
}
1692
1693
/**
1694
*******************************************************************************
1695
*
1696
* @brief This function performs luma & chroma padding
1697
*
1698
* @par Description:
1699
*
1700
* @param[in] ps_proc
1701
*  Process context corresponding to the job
1702
*
1703
* @param[in] pu1_curr_pic_luma
1704
*  Pointer to luma buffer
1705
*
1706
* @param[in] pu1_curr_pic_chroma
1707
*  Pointer to chroma buffer
1708
*
1709
* @param[in] i4_mb_x
1710
*  mb index x
1711
*
1712
* @param[in] i4_mb_y
1713
*  mb index y
1714
*
1715
*  @param[in] i4_pad_ht
1716
*  number of rows to be padded
1717
*
1718
* @returns  error status
1719
*
1720
* @remarks none
1721
*
1722
*******************************************************************************
1723
*/
1724
IH264E_ERROR_T isvce_pad_recon_buffer(isvce_process_ctxt_t *ps_proc, UWORD8 *pu1_curr_pic_luma,
1725
                                      WORD32 i4_luma_stride, UWORD8 *pu1_curr_pic_chroma,
1726
                                      WORD32 i4_chroma_stride, WORD32 i4_mb_x, WORD32 i4_mb_y,
1727
                                      WORD32 i4_pad_ht)
1728
0
{
1729
    /* codec context */
1730
0
    isvce_codec_t *ps_codec = ps_proc->ps_codec;
1731
1732
0
    if(i4_mb_x == 0)
1733
0
    {
1734
        /* padding left luma */
1735
0
        ps_codec->pf_pad_left_luma(pu1_curr_pic_luma, i4_luma_stride, i4_pad_ht, PAD_LEFT);
1736
1737
        /* padding left chroma */
1738
0
        ps_codec->pf_pad_left_chroma(pu1_curr_pic_chroma, i4_chroma_stride, i4_pad_ht >> 1,
1739
0
                                     PAD_LEFT);
1740
0
    }
1741
0
    if(i4_mb_x == ps_proc->i4_wd_mbs - 1)
1742
0
    {
1743
        /* padding right luma */
1744
0
        ps_codec->pf_pad_right_luma(pu1_curr_pic_luma + MB_SIZE, i4_luma_stride, i4_pad_ht,
1745
0
                                    PAD_RIGHT);
1746
1747
        /* padding right chroma */
1748
0
        ps_codec->pf_pad_right_chroma(pu1_curr_pic_chroma + MB_SIZE, i4_chroma_stride,
1749
0
                                      i4_pad_ht >> 1, PAD_RIGHT);
1750
1751
0
        if(i4_mb_y == ps_proc->i4_ht_mbs - 1)
1752
0
        {
1753
0
            UWORD8 *pu1_rec_luma =
1754
0
                pu1_curr_pic_luma + MB_SIZE + PAD_RIGHT + ((i4_pad_ht - 1) * i4_luma_stride);
1755
0
            UWORD8 *pu1_rec_chroma = pu1_curr_pic_chroma + MB_SIZE + PAD_RIGHT +
1756
0
                                     (((i4_pad_ht >> 1) - 1) * i4_chroma_stride);
1757
1758
            /* padding bottom luma */
1759
0
            ps_codec->pf_pad_bottom(pu1_rec_luma, i4_luma_stride, i4_luma_stride, PAD_BOT);
1760
1761
            /* padding bottom chroma */
1762
0
            ps_codec->pf_pad_bottom(pu1_rec_chroma, i4_chroma_stride, i4_chroma_stride,
1763
0
                                    (PAD_BOT >> 1));
1764
0
        }
1765
0
    }
1766
1767
0
    if(i4_mb_y == 0)
1768
0
    {
1769
0
        UWORD8 *pu1_rec_luma = pu1_curr_pic_luma;
1770
0
        UWORD8 *pu1_rec_chroma = pu1_curr_pic_chroma;
1771
0
        WORD32 wd = MB_SIZE;
1772
1773
0
        if(i4_mb_x == 0)
1774
0
        {
1775
0
            pu1_rec_luma -= PAD_LEFT;
1776
0
            pu1_rec_chroma -= PAD_LEFT;
1777
1778
0
            wd += PAD_LEFT;
1779
0
        }
1780
0
        if(i4_mb_x == ps_proc->i4_wd_mbs - 1)
1781
0
        {
1782
0
            wd += PAD_RIGHT;
1783
0
        }
1784
1785
        /* padding top luma */
1786
0
        ps_codec->pf_pad_top(pu1_rec_luma, i4_luma_stride, wd, PAD_TOP);
1787
1788
        /* padding top chroma */
1789
0
        ps_codec->pf_pad_top(pu1_rec_chroma, i4_chroma_stride, wd, (PAD_TOP >> 1));
1790
0
    }
1791
1792
0
    return IH264E_SUCCESS;
1793
0
}
1794
1795
/**
1796
*******************************************************************************
1797
*
1798
* @brief This function performs deblocking
1799
*
1800
* @par Description:
1801
*
1802
* @param[in] ps_proc
1803
*  Process context corresponding to the job
1804
*
1805
* @returns  error status
1806
*
1807
* @remarks none
1808
*
1809
*******************************************************************************
1810
*/
1811
static IH264E_ERROR_T isvce_dblk_n_mbs(isvce_process_ctxt_t *ps_proc,
1812
                                       UWORD8 u1_inter_layer_deblk_flag)
1813
9.37M
{
1814
9.37M
    WORD32 i;
1815
9.37M
    WORD32 row, col;
1816
1817
9.37M
    n_mb_process_ctxt_t *ps_n_mb_ctxt = &ps_proc->s_n_mb_ctxt;
1818
9.37M
    isvce_deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
1819
1820
9.37M
    UWORD8 *pu1_deblk_map = ps_proc->pu1_deblk_map + ps_deblk->i4_mb_y * ps_proc->i4_wd_mbs;
1821
9.37M
    UWORD8 *pu1_deblk_map_prev_row = pu1_deblk_map - ps_proc->i4_wd_mbs;
1822
9.37M
    WORD32 u4_deblk_prev_row = 0;
1823
9.37M
    WORD32 i4_n_mbs = ps_n_mb_ctxt->i4_n_mbs;
1824
9.37M
    WORD32 i4_n_mb_process_count = 0;
1825
9.37M
    WORD32 i4_mb_x = ps_proc->i4_mb_x;
1826
9.37M
    WORD32 i4_mb_y = ps_proc->i4_mb_y;
1827
1828
9.37M
    ASSERT(i4_n_mbs == ps_proc->i4_wd_mbs);
1829
1830
9.37M
    if(ps_proc->u4_disable_deblock_level != 1)
1831
7.11M
    {
1832
7.11M
        if((i4_mb_y > 0) || (i4_mb_y == (ps_proc->i4_ht_mbs - 1)))
1833
6.82M
        {
1834
            /* if number of mb's to be processed are less than 'N', go back.
1835
             * exception to the above clause is end of row */
1836
6.82M
            if(((i4_mb_x - (ps_n_mb_ctxt->i4_mb_x - 1)) < i4_n_mbs) &&
1837
6.62M
               (i4_mb_x < (ps_proc->i4_wd_mbs - 1)))
1838
6.62M
            {
1839
6.62M
                return IH264E_SUCCESS;
1840
6.62M
            }
1841
197k
            else
1842
197k
            {
1843
197k
                WORD32 i4_num_deblk_rows = 1;
1844
1845
197k
                if(i4_mb_y == (ps_proc->i4_ht_mbs - 1))
1846
36.3k
                {
1847
36.3k
                    i4_num_deblk_rows += (ps_proc->i4_ht_mbs > 1);
1848
36.3k
                }
1849
1850
197k
                if(1 == ps_proc->i4_ht_mbs)
1851
10.8k
                {
1852
10.8k
                    ps_deblk->i4_mb_y = 0;
1853
10.8k
                    pu1_deblk_map_prev_row = pu1_deblk_map;
1854
10.8k
                }
1855
1856
421k
                for(i = 0; i < i4_num_deblk_rows; i++)
1857
223k
                {
1858
223k
                    if(i == 1)
1859
25.5k
                    {
1860
                        /* Deblock last row */
1861
25.5k
                        ps_n_mb_ctxt->i4_mb_x = 0;
1862
25.5k
                        ps_n_mb_ctxt->i4_mb_y = ps_proc->i4_mb_y;
1863
25.5k
                        ps_deblk->i4_mb_x = 0;
1864
25.5k
                        ps_deblk->i4_mb_y = ps_proc->i4_mb_y;
1865
25.5k
                        pu1_deblk_map_prev_row = pu1_deblk_map;
1866
25.5k
                        pu1_deblk_map += ps_proc->i4_wd_mbs;
1867
25.5k
                    }
1868
1869
223k
                    i4_n_mb_process_count = MIN(i4_mb_x - (ps_n_mb_ctxt->i4_mb_x - 1), i4_n_mbs);
1870
1871
                    /* performing deblocking for required number of MBs */
1872
223k
                    u4_deblk_prev_row = 1;
1873
1874
                    /* checking whether the top rows are deblocked */
1875
7.35M
                    for(col = 0; col < i4_n_mb_process_count; col++)
1876
7.13M
                    {
1877
7.13M
                        u4_deblk_prev_row &= pu1_deblk_map_prev_row[ps_deblk->i4_mb_x + col];
1878
7.13M
                    }
1879
1880
                    /* checking whether the top right MB is deblocked */
1881
223k
                    if((ps_deblk->i4_mb_x + i4_n_mb_process_count) != ps_proc->i4_wd_mbs)
1882
0
                    {
1883
0
                        u4_deblk_prev_row &=
1884
0
                            pu1_deblk_map_prev_row[ps_deblk->i4_mb_x + i4_n_mb_process_count];
1885
0
                    }
1886
1887
                    /* Top or Top right MBs not deblocked */
1888
223k
                    if((u4_deblk_prev_row != 1) && (i4_mb_y > 0))
1889
0
                    {
1890
0
                        return IH264E_SUCCESS;
1891
0
                    }
1892
1893
7.35M
                    for(row = 0; row < i4_n_mb_process_count; row++)
1894
7.13M
                    {
1895
7.13M
                        isvce_deblock_mb(ps_proc, ps_deblk, u1_inter_layer_deblk_flag);
1896
1897
7.13M
                        pu1_deblk_map[ps_deblk->i4_mb_x] = 1;
1898
1899
7.13M
                        ps_deblk->i4_mb_x++;
1900
7.13M
                    }
1901
223k
                }
1902
197k
            }
1903
6.82M
        }
1904
7.11M
    }
1905
1906
2.74M
    return IH264E_SUCCESS;
1907
9.37M
}
1908
1909
/**
1910
*******************************************************************************
1911
*
1912
* @brief This function performs 'intra base' deblocking
1913
*
1914
* @par Description:
1915
*
1916
* @param[in] ps_proc
1917
*  Process context corresponding to the job
1918
*
1919
* @returns  error status
1920
*
1921
* @remarks none
1922
*
1923
*******************************************************************************
1924
*/
1925
static IH264E_ERROR_T isvce_intra_base_dblk(isvce_process_ctxt_t *ps_proc)
1926
0
{
1927
0
    isvce_codec_t *ps_codec = ps_proc->ps_codec;
1928
0
    isvce_deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
1929
0
1930
0
    IH264E_ERROR_T e_ret = IH264E_SUCCESS;
1931
0
1932
0
    if(ps_proc->u1_spatial_layer_id < (ps_proc->s_svc_params.u1_num_spatial_layers - 1))
1933
0
    {
1934
0
        ps_deblk->i4_mb_x = ps_proc->i4_mb_x;
1935
0
        ps_deblk->i4_mb_y = ps_proc->i4_mb_y - 1;
1936
0
1937
0
        ps_deblk->s_rec_pic_buf_props =
1938
0
            ps_codec->s_svc_ilp_data.ps_intra_recon_bufs[ps_proc->u1_spatial_layer_id];
1939
0
1940
0
        e_ret = isvce_dblk_n_mbs(ps_proc, 1);
1941
0
1942
0
        ps_deblk->s_rec_pic_buf_props = ps_proc->s_rec_pic_buf_props;
1943
0
    }
1944
0
1945
0
    return e_ret;
1946
0
}
1947
1948
/**
1949
*******************************************************************************
1950
*
1951
* @brief This function performs luma & chroma core coding for a set of mb's.
1952
*
1953
* @par Description:
1954
*  The mb to be coded is taken and is evaluated over a predefined set of modes
1955
*  (intra (i16, i4, i8)/inter (mv, skip)) for best cost. The mode with least
1956
*cost is selected and using intra/inter prediction filters, prediction is
1957
*carried out. The deviation between src and pred signal constitutes error
1958
*signal. This error signal is transformed (hierarchical transform if necessary)
1959
*and quantized. The quantized residue is packed in to entropy buffer for entropy
1960
*coding. This is repeated for all the mb's enlisted under the job.
1961
*
1962
* @param[in] ps_proc
1963
*  Process context corresponding to the job
1964
*
1965
* @returns  error status
1966
*
1967
* @remarks none
1968
*
1969
*******************************************************************************
1970
*/
1971
WORD32 isvce_process(isvce_process_ctxt_t *ps_proc)
1972
322k
{
1973
322k
    UWORD32 u4_cbp_l, u4_cbp_c;
1974
322k
    WORD32 i4_mb_idx;
1975
322k
    WORD32 luma_idx, chroma_idx, is_intra;
1976
1977
322k
    isvce_codec_t *ps_codec = ps_proc->ps_codec;
1978
322k
    isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
1979
322k
    enc_loop_fxns_t *ps_enc_loop_fxns = &ps_isa_dependent_fxns->s_enc_loop_fxns;
1980
1981
322k
    WORD32 error_status = IH264_SUCCESS;
1982
322k
    WORD32 i4_wd_mbs = ps_proc->i4_wd_mbs;
1983
322k
    WORD32 i4_mb_cnt = ps_proc->i4_mb_cnt;
1984
322k
    UWORD32 u4_valid_modes = 0;
1985
322k
    WORD32 i4_gate_threshold = 0;
1986
322k
    WORD32 ctxt_sel = ps_proc->i4_encode_api_call_cnt % MAX_CTXT_SETS;
1987
322k
    bool b_enable_intra4x4_eval = true;
1988
1989
    /*
1990
     * list of modes for evaluation
1991
     * -------------------------------------------------------------------------
1992
     * Note on enabling I4x4 and I16x16
1993
     * At very low QP's the hadamard transform in I16x16 will push up the maximum
1994
     * coeff value very high. CAVLC may not be able to represent the value and
1995
     * hence the stream may not be decodable in some clips.
1996
     * Hence at low QPs, we will enable I4x4 and disable I16x16 irrespective of
1997
     * preset.
1998
     */
1999
322k
    if(ps_proc->i4_slice_type == ISLICE)
2000
192k
    {
2001
18.4E
        u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_16x16 ? (1 << I16x16) : 0;
2002
2003
        /* enable intra 8x8 */
2004
192k
        u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_8x8 ? (1 << I8x8) : 0;
2005
2006
        /* enable intra 4x4 */
2007
192k
        u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_4x4 ? (1 << I4x4) : 0;
2008
192k
        u4_valid_modes |= (ps_proc->u1_frame_qp <= 10) << I4x4;
2009
192k
    }
2010
129k
    else if(ps_proc->i4_slice_type == PSLICE)
2011
129k
    {
2012
129k
        u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_16x16 ? (1 << I16x16) : 0;
2013
2014
        /* enable intra 4x4 */
2015
129k
        if(ps_codec->s_cfg.u4_enc_speed_preset == IVE_SLOWEST)
2016
18.7k
        {
2017
18.7k
            u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_4x4 ? (1 << I4x4) : 0;
2018
18.7k
        }
2019
129k
        u4_valid_modes |= (ps_proc->u1_frame_qp <= 10) << I4x4;
2020
2021
        /* enable inter P16x16 */
2022
129k
        u4_valid_modes |= (1 << P16x16);
2023
129k
    }
2024
18.4E
    else if(ps_proc->i4_slice_type == BSLICE)
2025
0
    {
2026
0
        u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_16x16 ? (1 << I16x16) : 0;
2027
2028
        /* enable intra 4x4 */
2029
0
        if(ps_codec->s_cfg.u4_enc_speed_preset == IVE_SLOWEST)
2030
0
        {
2031
0
            u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_4x4 ? (1 << I4x4) : 0;
2032
0
        }
2033
0
        u4_valid_modes |= (ps_proc->u1_frame_qp <= 10) << I4x4;
2034
2035
        /* enable inter B16x16 */
2036
0
        u4_valid_modes |= (1 << B16x16);
2037
0
    }
2038
2039
322k
    ps_proc->s_entropy.i4_mb_x = ps_proc->i4_mb_x;
2040
322k
    ps_proc->s_entropy.i4_mb_y = ps_proc->i4_mb_y;
2041
322k
    ps_proc->s_entropy.i4_mb_cnt = MIN(ps_proc->i4_nmb_ntrpy, i4_wd_mbs - ps_proc->i4_mb_x);
2042
2043
    /* compute recon when :
2044
     *   1. current frame is to be used as a reference
2045
     *   2. dump recon for bit stream sanity check
2046
     */
2047
322k
    ps_proc->u4_compute_recon = ((ps_proc->s_svc_params.u1_num_spatial_layers > 1) &&
2048
284k
                                 (ENABLE_RESIDUAL_PREDICTION || ENABLE_IBL_MODE)) ||
2049
38.4k
                                ps_codec->u4_is_curr_frm_ref || ps_codec->s_cfg.u4_enable_recon;
2050
2051
9.65M
    for(i4_mb_idx = 0; i4_mb_idx < i4_mb_cnt; i4_mb_idx++)
2052
9.37M
    {
2053
        /* since we have not yet found sad, we have not yet got min sad */
2054
        /* we need to initialize these variables for each MB */
2055
        /* TODO how to get the min sad into the codec */
2056
9.37M
        ps_proc->u4_min_sad = ps_codec->s_cfg.i4_min_sad;
2057
9.37M
        ps_proc->u4_min_sad_reached = 0;
2058
2059
9.37M
        ps_proc->ps_mb_info->u1_mb_qp = ps_proc->u1_mb_qp;
2060
2061
        /* wait until the proc of [top + 1] mb is computed.
2062
         * We wait till the proc dependencies are satisfied */
2063
9.37M
        if(ps_proc->i4_mb_y > 0)
2064
8.64M
        {
2065
8.64M
            UWORD8 *pu1_proc_map_top;
2066
2067
8.64M
            pu1_proc_map_top = ps_proc->pu1_proc_map + ((ps_proc->i4_mb_y - 1) * i4_wd_mbs);
2068
2069
30.9M
            while(1)
2070
30.9M
            {
2071
30.9M
                volatile UWORD8 *pu1_buf;
2072
30.9M
                WORD32 idx = MIN(i4_mb_cnt - 1, i4_mb_idx + 1);
2073
2074
30.9M
                idx = MIN(idx, ((WORD32) ps_codec->s_cfg.i4_wd_mbs - 1));
2075
30.9M
                pu1_buf = pu1_proc_map_top + idx;
2076
30.9M
                if(*pu1_buf) break;
2077
22.3M
                ithread_yield();
2078
22.3M
            }
2079
8.64M
        }
2080
2081
9.37M
        if(ENABLE_ILP_MV && (ps_proc->u1_spatial_layer_id > 0) &&
2082
7.21M
           (ps_proc->i4_slice_type != ISLICE))
2083
1.00M
        {
2084
1.00M
            svc_ilp_mv_ctxt_t *ps_svc_ilp_mv_ctxt = ps_proc->ps_svc_ilp_mv_ctxt;
2085
1.00M
            coordinates_t s_mb_pos = {ps_proc->i4_mb_x, ps_proc->i4_mb_y};
2086
2087
1.00M
            ps_svc_ilp_mv_ctxt->s_ilp_mv_variables.ps_svc_ilp_data = &ps_codec->s_svc_ilp_data;
2088
1.00M
            ps_svc_ilp_mv_ctxt->s_ilp_mv_variables.s_mb_pos = s_mb_pos;
2089
1.00M
            ps_svc_ilp_mv_ctxt->s_ilp_mv_variables.u1_spatial_layer_id =
2090
1.00M
                ps_proc->u1_spatial_layer_id;
2091
2092
1.00M
            isvce_get_mb_ilp_mv(ps_svc_ilp_mv_ctxt);
2093
2094
1.00M
            ps_proc->ps_ilp_mv = &ps_svc_ilp_mv_ctxt->s_ilp_mv_outputs.s_ilp_mv;
2095
1.00M
            ps_proc->s_me_ctxt.ps_ilp_me_cands =
2096
1.00M
                &ps_svc_ilp_mv_ctxt->s_ilp_mv_outputs.s_ilp_me_cands;
2097
1.00M
        }
2098
8.37M
        else
2099
8.37M
        {
2100
8.37M
            ps_proc->ps_ilp_mv = NULL;
2101
8.37M
            ps_proc->s_me_ctxt.ps_ilp_me_cands = NULL;
2102
8.37M
        }
2103
2104
9.37M
        ps_proc->ps_mb_info->u2_mb_type = INVALID_MB_TYPE;
2105
9.37M
        ps_proc->i4_mb_distortion = SHRT_MAX;
2106
2107
9.37M
        {
2108
9.37M
            WORD32 i4_mb_id = ps_proc->i4_mb_x + ps_proc->i4_mb_y * i4_wd_mbs;
2109
2110
9.37M
            WORD32 i4_air_enable_inter =
2111
9.37M
                (ps_codec->s_cfg.e_air_mode == IVE_AIR_MODE_NONE) ||
2112
0
                (ps_codec->pu2_intr_rfrsh_map[i4_mb_id] != ps_codec->i4_air_pic_cnt);
2113
2114
9.37M
            if((u4_valid_modes & (1 << P16x16)) || (u4_valid_modes & (1 << B16x16)))
2115
1.34M
            {
2116
1.34M
                if(ps_proc->i4_mb_x % ps_proc->u4_nmb_me == 0)
2117
1.34M
                {
2118
1.34M
                    isvce_compute_me_nmb(
2119
1.34M
                        ps_proc, MIN((WORD32) ps_proc->u4_nmb_me, i4_wd_mbs - ps_proc->i4_mb_x));
2120
1.34M
                }
2121
2122
1.34M
                {
2123
1.34M
                    UWORD32 u4_mb_index = ps_proc->i4_mb_x % ps_proc->u4_nmb_me;
2124
2125
1.34M
                    ps_proc->u4_min_sad_reached =
2126
1.34M
                        ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad_reached;
2127
1.34M
                    ps_proc->u4_min_sad = ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad;
2128
2129
1.34M
                    ps_proc->ps_skip_mv = &(ps_proc->ps_nmb_info[u4_mb_index].as_skip_mv[0]);
2130
1.34M
                    ps_proc->ps_ngbr_avbl = &(ps_proc->ps_nmb_info[u4_mb_index].s_ngbr_avbl);
2131
1.34M
                    ps_proc->ps_pred_mv = &(ps_proc->ps_nmb_info[u4_mb_index].as_pred_mv[0]);
2132
2133
1.34M
                    ps_proc->i4_mb_distortion = ps_proc->ps_nmb_info[u4_mb_index].i4_mb_distortion;
2134
2135
1.34M
                    ps_proc->i4_mb_cost = ps_proc->ps_nmb_info[u4_mb_index].i4_mb_cost;
2136
1.34M
                    ps_proc->u4_min_sad = ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad;
2137
1.34M
                    ps_proc->u4_min_sad_reached =
2138
1.34M
                        ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad_reached;
2139
1.34M
                    ps_proc->ps_mb_info->u2_mb_type = ps_proc->ps_nmb_info[u4_mb_index].u4_mb_type;
2140
2141
1.34M
                    ps_proc->pu1_best_subpel_buf =
2142
1.34M
                        ps_proc->ps_nmb_info[u4_mb_index].pu1_best_sub_pel_buf;
2143
1.34M
                    ps_proc->u4_bst_spel_buf_strd =
2144
1.34M
                        ps_proc->ps_nmb_info[u4_mb_index].u4_bst_spel_buf_strd;
2145
1.34M
                }
2146
2147
1.34M
                isvce_derive_nghbr_avbl_of_mbs(ps_proc);
2148
1.34M
            }
2149
8.03M
            else
2150
8.03M
            {
2151
8.03M
                ps_proc->ps_ngbr_avbl = &ps_proc->s_ngbr_avbl;
2152
2153
8.03M
                isvce_derive_nghbr_avbl_of_mbs(ps_proc);
2154
8.03M
            }
2155
2156
            /*
2157
             * If air says intra, we need to force the following code path to evaluate
2158
             * intra The easy way is just to say that the inter cost is too much
2159
             */
2160
9.37M
            if(!i4_air_enable_inter)
2161
0
            {
2162
0
                ps_proc->u4_min_sad_reached = 0;
2163
0
                ps_proc->i4_mb_cost = INT_MAX;
2164
0
                ps_proc->i4_mb_distortion = INT_MAX;
2165
0
            }
2166
9.37M
            else if(ps_proc->ps_mb_info->u2_mb_type == PSKIP)
2167
0
            {
2168
0
                ps_proc->ps_mb_info->u1_base_mode_flag = 0;
2169
0
                ps_proc->ps_mb_info->u1_residual_prediction_flag = 0;
2170
0
                goto UPDATE_MB_INFO;
2171
0
            }
2172
2173
            /* If we already have the minimum sad, there is no point in searching for
2174
             * sad again */
2175
9.37M
            if((ps_proc->u4_min_sad_reached == 0) ||
2176
463k
               (ps_codec->s_cfg.u4_enc_speed_preset != IVE_FASTEST))
2177
9.35M
            {
2178
                /* intra gating in inter slices */
2179
                /* No need of gating if we want to force intra, we need to find the
2180
                 * threshold only if inter is enabled by AIR*/
2181
9.35M
                if((ps_proc->i4_slice_type != ISLICE) &&
2182
1.33M
                   (FORCE_DISTORTION_BASED_INTRA_4X4_GATING ||
2183
0
                    (i4_air_enable_inter && ps_codec->u4_inter_gate)))
2184
1.33M
                {
2185
1.33M
                    WORD32 i4_distortion[4];
2186
2187
1.33M
                    if((ps_proc->i4_mb_x > 0) && (ps_proc->i4_mb_y > 0))
2188
778k
                    {
2189
778k
                        i4_distortion[0] = ps_proc->s_nbr_info.ps_left_mb_info->i4_mb_distortion;
2190
2191
778k
                        i4_distortion[1] = ps_proc->s_nbr_info.ps_top_row_mb_info[ps_proc->i4_mb_x]
2192
778k
                                               .i4_mb_distortion;
2193
2194
778k
                        i4_distortion[2] =
2195
778k
                            ps_proc->s_nbr_info.ps_top_row_mb_info[ps_proc->i4_mb_x + 1]
2196
778k
                                .i4_mb_distortion;
2197
2198
778k
                        i4_distortion[3] =
2199
778k
                            ps_proc->s_nbr_info.ps_top_row_mb_info[ps_proc->i4_mb_x - 1]
2200
778k
                                .i4_mb_distortion;
2201
2202
778k
                        i4_gate_threshold = (i4_distortion[0] + i4_distortion[1] +
2203
778k
                                             i4_distortion[2] + i4_distortion[3]) /
2204
778k
                                            4;
2205
778k
                    }
2206
1.33M
                }
2207
2208
9.35M
                b_enable_intra4x4_eval = true;
2209
2210
9.35M
                if(ENABLE_IBL_MODE && (ps_proc->u1_spatial_layer_id > 0) &&
2211
7.20M
                   (ps_proc->s_svc_params.d_spatial_res_ratio == 2.) && !ps_proc->ps_ilp_mv)
2212
5.14M
                {
2213
5.14M
                    isvce_evaluate_IBL_mode(ps_proc);
2214
5.14M
                }
2215
4.20M
                else
2216
4.20M
                {
2217
4.20M
                    ps_proc->ps_mb_info->u1_base_mode_flag = 0;
2218
4.20M
                }
2219
2220
9.35M
                if(u4_valid_modes & (1 << I16x16))
2221
9.34M
                {
2222
9.34M
                    isvce_evaluate_intra16x16_modes_for_least_cost_rdoptoff(ps_proc);
2223
2224
9.34M
                    if(ENABLE_INTRA16X16_BASED_INTRA4X4_GATING &&
2225
0
                       (ps_proc->i4_slice_type != ISLICE) &&
2226
0
                       (ps_proc->ps_mb_info->u2_mb_type == I16x16))
2227
0
                    {
2228
0
                        b_enable_intra4x4_eval = false;
2229
0
                    }
2230
9.34M
                }
2231
2232
9.35M
                if(u4_valid_modes & (1 << I8x8))
2233
0
                {
2234
0
                    isvce_evaluate_intra8x8_modes_for_least_cost_rdoptoff(ps_proc);
2235
0
                }
2236
2237
9.35M
                if(ENABLE_ILP_BASED_INTRA4X4_GATING && (ps_proc->i4_slice_type != ISLICE))
2238
0
                {
2239
0
                    b_enable_intra4x4_eval =
2240
0
                        !(ps_proc->ps_ilp_mv && (INVALID_MB_TYPE != ps_proc->ps_ilp_mv->e_mb_type));
2241
0
                }
2242
2243
                /* If we are going to force intra we need to evaluate intra irrespective
2244
                 * of gating */
2245
9.35M
                if((!i4_air_enable_inter) ||
2246
9.36M
                   ((i4_gate_threshold + 16 * ((WORD32) ps_proc->u4_lambda)) <
2247
9.36M
                    ps_proc->i4_mb_distortion))
2248
2.60M
                {
2249
2.60M
                    if(b_enable_intra4x4_eval && (u4_valid_modes & (1 << I4x4)))
2250
954k
                    {
2251
954k
                        if(!FORCE_FAST_INTRA4X4 &&
2252
955k
                           (ps_codec->s_cfg.u4_enc_speed_preset == IVE_SLOWEST))
2253
343k
                        {
2254
343k
                            isvce_evaluate_intra4x4_modes_for_least_cost_rdopton(ps_proc);
2255
343k
                        }
2256
611k
                        else
2257
611k
                        {
2258
611k
                            isvce_evaluate_intra4x4_modes_for_least_cost_rdoptoff(ps_proc);
2259
611k
                        }
2260
954k
                    }
2261
2.60M
                }
2262
9.35M
            }
2263
9.37M
        }
2264
2265
9.37M
        if(ps_proc->ps_mb_info->u2_mb_type == I4x4 || ps_proc->ps_mb_info->u2_mb_type == I16x16 ||
2266
3.66M
           ps_proc->ps_mb_info->u2_mb_type == I8x8)
2267
5.70M
        {
2268
5.70M
            luma_idx = ps_proc->ps_mb_info->u2_mb_type;
2269
5.70M
            chroma_idx = 0;
2270
5.70M
            is_intra = 1;
2271
2272
5.70M
            isvce_evaluate_chroma_intra8x8_modes_for_least_cost_rdoptoff(ps_proc);
2273
5.70M
        }
2274
3.66M
        else if(ps_proc->ps_mb_info->u2_mb_type == BASE_MODE)
2275
2.72M
        {
2276
2.72M
            luma_idx = 3;
2277
2.72M
            chroma_idx = 1;
2278
2.72M
            is_intra = 1;
2279
2.72M
            ps_proc->u4_min_sad_reached = 0;
2280
2.72M
        }
2281
947k
        else
2282
947k
        {
2283
947k
            luma_idx = 3;
2284
947k
            chroma_idx = 1;
2285
947k
            is_intra = 0;
2286
947k
        }
2287
2288
9.37M
        ps_proc->ps_mb_info->u1_is_intra = is_intra;
2289
2290
9.37M
        if(is_intra)
2291
8.43M
        {
2292
8.43M
            ps_proc->ps_mb_info->as_pu->as_me_info[L0].i1_ref_idx = -1;
2293
8.43M
            ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvx = 0;
2294
8.43M
            ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvy = 0;
2295
2296
8.43M
            ps_proc->ps_mb_info->as_pu->as_me_info[L1].i1_ref_idx = -1;
2297
8.43M
            ps_proc->ps_mb_info->as_pu->as_me_info[L1].s_mv.i2_mvx = 0;
2298
8.43M
            ps_proc->ps_mb_info->as_pu->as_me_info[L1].s_mv.i2_mvy = 0;
2299
8.43M
        }
2300
939k
        else
2301
939k
        {
2302
939k
            isvce_mv_pred(ps_proc, ps_proc->i4_slice_type);
2303
939k
        }
2304
2305
9.37M
        if(ENABLE_RESIDUAL_PREDICTION && !is_intra && (ps_proc->u1_spatial_layer_id > 0) &&
2306
644k
           (ps_proc->i4_slice_type == PSLICE) && (ps_proc->ps_mb_info->u2_mb_type != PSKIP))
2307
644k
        {
2308
644k
            svc_res_pred_ctxt_t *ps_res_pred_ctxt = ps_proc->ps_res_pred_ctxt;
2309
2310
644k
            UWORD32 u4_res_pred_sad;
2311
2312
644k
            isvce_me_ctxt_t *ps_me_ctxt = &ps_proc->s_me_ctxt;
2313
644k
            yuv_buf_props_t s_pred = ps_proc->s_src_buf_props;
2314
2315
644k
            if(!(ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvx % 4) &&
2316
606k
               !(ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvy % 4))
2317
582k
            {
2318
582k
                s_pred.as_component_bufs[Y].pv_data =
2319
582k
                    ps_me_ctxt->apu1_ref_buf_luma[L0] +
2320
582k
                    (ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvx >> 2) +
2321
582k
                    (ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvy >> 2) *
2322
582k
                        ps_me_ctxt->ai4_rec_strd[L0];
2323
582k
                s_pred.as_component_bufs[Y].i4_data_stride = ps_me_ctxt->ai4_rec_strd[L0];
2324
582k
            }
2325
62.5k
            else
2326
62.5k
            {
2327
62.5k
                s_pred.as_component_bufs[Y].pv_data = ps_proc->pu1_best_subpel_buf;
2328
62.5k
                s_pred.as_component_bufs[Y].i4_data_stride = ps_proc->u4_bst_spel_buf_strd;
2329
62.5k
            }
2330
2331
644k
            s_pred.as_component_bufs[U].pv_data = s_pred.as_component_bufs[V].pv_data = NULL;
2332
2333
644k
            ps_res_pred_ctxt->s_res_pred_variables.ps_svc_ilp_data = &ps_codec->s_svc_ilp_data;
2334
644k
            ps_res_pred_ctxt->s_res_pred_variables.s_mb_pos.i4_abscissa = ps_proc->i4_mb_x;
2335
644k
            ps_res_pred_ctxt->s_res_pred_variables.s_mb_pos.i4_ordinate = ps_proc->i4_mb_y;
2336
644k
            ps_res_pred_ctxt->s_res_pred_variables.u1_spatial_layer_id =
2337
644k
                ps_proc->u1_spatial_layer_id;
2338
2339
644k
            if(ps_proc->s_svc_params.d_spatial_res_ratio == 2.)
2340
195k
            {
2341
195k
                isvce_get_mb_residual_pred(ps_proc->ps_res_pred_ctxt);
2342
195k
            }
2343
449k
            else
2344
449k
            {
2345
449k
                isvce_get_mb_residual_pred_non_dyadic(ps_proc->ps_res_pred_ctxt);
2346
449k
            }
2347
2348
644k
            isvce_residual_pred_eval(ps_proc->ps_res_pred_ctxt, &ps_proc->s_src_buf_props, &s_pred,
2349
644k
                                     ps_proc->ps_mb_res_buf, &u4_res_pred_sad,
2350
644k
                                     &ps_proc->ps_mb_info->u1_residual_prediction_flag,
2351
644k
                                     ps_proc->i4_mb_distortion);
2352
2353
644k
            if(ps_proc->ps_mb_info->u1_residual_prediction_flag)
2354
69.3k
            {
2355
69.3k
                ps_proc->i4_mb_cost -= ps_proc->i4_mb_distortion;
2356
69.3k
                ps_proc->i4_mb_cost += (WORD32) u4_res_pred_sad;
2357
69.3k
                ps_proc->i4_mb_distortion = (WORD32) u4_res_pred_sad;
2358
69.3k
            }
2359
644k
        }
2360
8.72M
        else
2361
8.72M
        {
2362
8.72M
            ps_proc->ps_mb_info->u1_residual_prediction_flag = 0;
2363
8.72M
        }
2364
2365
9.37M
        if(isvce_is_ilp_mv_winning_mv(ps_proc->ps_mb_info, ps_proc->ps_ilp_mv))
2366
73.7k
        {
2367
73.7k
            ps_proc->ps_mb_info->as_pu->as_me_info[L0] = ps_proc->ps_ilp_mv->as_mv[0][L0];
2368
73.7k
            ps_proc->ps_mb_info->as_pu->as_me_info[L1] = ps_proc->ps_ilp_mv->as_mv[0][L1];
2369
2370
73.7k
            ps_proc->ps_mb_info->u1_base_mode_flag = 1;
2371
73.7k
            ps_proc->ps_mb_info->u2_mb_type = BASE_MODE;
2372
73.7k
        }
2373
9.29M
        else if(ps_proc->ps_mb_info->u2_mb_type != BASE_MODE)
2374
6.57M
        {
2375
6.57M
            ps_proc->ps_mb_info->u1_base_mode_flag = 0;
2376
6.57M
        }
2377
2378
9.37M
        isvce_mvp_idx_eval(ps_proc->ps_mb_info, ps_proc->ps_pred_mv,
2379
9.37M
                           ps_proc->ps_ilp_mv ? ps_proc->ps_ilp_mv->as_mv[0] : NULL,
2380
9.37M
                           ps_proc->s_me_ctxt.pu1_mv_bits);
2381
2382
        /* 8x8 Tx is not supported, and I8x8 is also unsupported */
2383
9.37M
        ASSERT((luma_idx == 0) || (luma_idx == 1) || (luma_idx == 3));
2384
9.37M
        ps_proc->ps_mb_info->u1_tx_size = 4;
2385
2386
        /* Perform luma mb core coding */
2387
9.36M
        u4_cbp_l = (ps_enc_loop_fxns->apf_luma_energy_compaction)[luma_idx](ps_proc);
2388
2389
        /* Perform chroma mb core coding */
2390
9.36M
        u4_cbp_c = (ps_enc_loop_fxns->apf_chroma_energy_compaction)[chroma_idx](ps_proc);
2391
2392
9.36M
        ps_proc->u4_cbp = (u4_cbp_c << 4) | u4_cbp_l;
2393
9.36M
        ps_proc->ps_mb_info->u4_cbp = (u4_cbp_c << 4) | u4_cbp_l;
2394
9.36M
        ps_proc->ps_mb_info->u4_csbp = isvce_calculate_csbp(ps_proc);
2395
2396
9.36M
        if(ps_proc->ps_mb_info->u1_is_intra)
2397
8.42M
        {
2398
8.42M
            switch(ps_proc->ps_mb_info->u2_mb_type)
2399
8.42M
            {
2400
5.15M
                case I16x16:
2401
5.15M
                {
2402
5.15M
                    ps_proc->ps_mb_info->s_intra_pu.s_i16x16_mode_data.u1_mode =
2403
5.15M
                        ps_proc->u1_l_i16_mode;
2404
2405
5.15M
                    break;
2406
0
                }
2407
554k
                case I4x4:
2408
554k
                {
2409
554k
                    WORD32 i;
2410
2411
9.40M
                    for(i = 0; i < MAX_TU_IN_MB; i++)
2412
8.84M
                    {
2413
8.84M
                        ps_proc->ps_mb_info->s_intra_pu.as_i4x4_mode_data[i].u1_mode =
2414
8.84M
                            ps_proc->au1_intra_luma_mb_4x4_modes[i];
2415
8.84M
                        ps_proc->ps_mb_info->s_intra_pu.as_i4x4_mode_data[i].u1_predicted_mode =
2416
8.84M
                            ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i];
2417
8.84M
                    }
2418
2419
554k
                    break;
2420
0
                }
2421
2.71M
                case BASE_MODE:
2422
2.71M
                {
2423
2.71M
                    break;
2424
0
                }
2425
0
                default:
2426
0
                {
2427
0
                    ASSERT(false);
2428
0
                }
2429
8.42M
            }
2430
2431
8.42M
            ps_proc->ps_mb_info->s_intra_pu.u1_chroma_intra_mode = ps_proc->u1_c_i8_mode;
2432
8.42M
        }
2433
2434
9.36M
        if(!ps_proc->ps_mb_info->u1_is_intra && !ps_proc->ps_mb_info->u1_residual_prediction_flag)
2435
880k
        {
2436
880k
            if(ps_proc->i4_slice_type == BSLICE)
2437
0
            {
2438
0
                if(isvce_find_bskip_params(ps_proc, L0))
2439
0
                {
2440
0
                    ps_proc->ps_mb_info->u2_mb_type = (ps_proc->u4_cbp) ? BDIRECT : BSKIP;
2441
0
                }
2442
0
            }
2443
880k
            else if(!ps_proc->u4_cbp)
2444
403k
            {
2445
403k
                if(isvce_find_pskip_params(ps_proc, L0))
2446
369k
                {
2447
369k
                    ps_proc->ps_mb_info->u2_mb_type = PSKIP;
2448
369k
                }
2449
403k
            }
2450
880k
        }
2451
2452
9.37M
    UPDATE_MB_INFO:
2453
9.37M
        isvce_svc_ilp_buf_update(ps_proc);
2454
2455
9.37M
        isvce_update_ibl_info(
2456
9.37M
            ps_proc->ps_intra_pred_ctxt, ps_proc->s_svc_params.u1_num_spatial_layers,
2457
9.37M
            ps_proc->u1_spatial_layer_id, ps_proc->ps_mb_info->u2_mb_type, ps_proc->i4_mb_x,
2458
9.37M
            ps_proc->i4_mb_y, ps_proc->ps_mb_info->u1_base_mode_flag);
2459
2460
9.37M
        isvce_update_res_pred_info(ps_proc);
2461
2462
        /* Update mb sad, mb qp and intra mb cost. Will be used by rate control */
2463
9.37M
        isvce_update_rc_mb_info(&ps_proc->s_frame_info, ps_proc);
2464
2465
9.37M
        {
2466
9.37M
            svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt = ps_proc->ps_sub_pic_rc_ctxt;
2467
9.37M
            svc_sub_pic_rc_mb_variables_t *ps_sub_pic_rc_variables =
2468
9.37M
                &ps_sub_pic_rc_ctxt->s_sub_pic_rc_variables.s_mb_variables;
2469
2470
9.37M
            ps_sub_pic_rc_variables->ps_mb_info = ps_proc->ps_mb_info;
2471
9.37M
            ps_sub_pic_rc_variables->s_mb_pos.i4_abscissa = ps_proc->i4_mb_x;
2472
9.37M
            ps_sub_pic_rc_variables->s_mb_pos.i4_ordinate = ps_proc->i4_mb_y;
2473
9.37M
            ps_sub_pic_rc_variables->u4_cbp = ps_proc->u4_cbp;
2474
9.37M
            ps_sub_pic_rc_variables->aps_mvps[0] = ps_proc->ps_pred_mv;
2475
9.37M
#if MAX_MVP_IDX == 1
2476
9.37M
            ps_sub_pic_rc_variables->aps_mvps[1] =
2477
9.37M
                ps_proc->ps_ilp_mv ? ps_proc->ps_ilp_mv->as_mv[0] : NULL;
2478
9.37M
#endif
2479
9.37M
            ps_sub_pic_rc_variables->apu1_nnzs[Y] = (UWORD8 *) ps_proc->au4_nnz;
2480
9.37M
            ps_sub_pic_rc_variables->apu1_nnzs[UV] = ps_proc->au1_chroma_nnz;
2481
2482
            /* Quant coeffs are arranged TU by TU */
2483
9.37M
            switch(ps_proc->ps_mb_info->u2_mb_type)
2484
9.37M
            {
2485
5.13M
                case I16x16:
2486
5.68M
                case I4x4:
2487
6.20M
                case P16x16:
2488
6.20M
                case B16x16:
2489
8.97M
                case BASE_MODE:
2490
8.97M
                {
2491
8.97M
                    ps_sub_pic_rc_variables->as_quant_coeffs[Y].pv_data =
2492
8.97M
                        ps_proc->pi2_res_buf_intra_4x4;
2493
8.97M
                    ps_sub_pic_rc_variables->as_quant_coeffs[Y].i4_data_stride =
2494
8.97M
                        ps_proc->i4_res_strd;
2495
8.97M
                    ps_sub_pic_rc_variables->as_quant_coeffs[UV].pv_data = ps_proc->pi2_res_buf;
2496
8.97M
                    ps_sub_pic_rc_variables->as_quant_coeffs[UV].i4_data_stride =
2497
8.97M
                        ps_proc->i4_res_strd;
2498
2499
8.97M
                    break;
2500
6.20M
                }
2501
368k
                case PSKIP:
2502
368k
                case BSKIP:
2503
368k
                {
2504
368k
                    ps_sub_pic_rc_variables->as_quant_coeffs[Y].pv_data = NULL;
2505
368k
                    ps_sub_pic_rc_variables->as_quant_coeffs[UV].pv_data = NULL;
2506
2507
368k
                    break;
2508
368k
                }
2509
0
                default:
2510
0
                {
2511
0
                    ASSERT(false);
2512
2513
0
                    break;
2514
0
                }
2515
9.37M
            }
2516
2517
9.33M
            isvce_sub_pic_rc_ctxt_update(ps_proc->ps_sub_pic_rc_ctxt);
2518
9.33M
        }
2519
2520
#if ENABLE_MODE_STAT_VISUALISER
2521
        if(ps_proc->u1_spatial_layer_id == (ps_proc->s_svc_params.u1_num_spatial_layers - 1))
2522
        {
2523
            coordinates_t s_mb_pos = {ps_proc->i4_mb_x, ps_proc->i4_mb_y};
2524
2525
            isvce_msv_set_mode(ps_codec->ps_mode_stat_visualiser, ps_proc->ps_mb_info, &s_mb_pos);
2526
        }
2527
#endif
2528
2529
        /**********************************************************************/
2530
        /* if disable deblock level is '0' this implies enable deblocking for */
2531
        /* all edges of all macroblocks with out any restrictions             */
2532
        /*                                                                    */
2533
        /* if disable deblock level is '1' this implies disable deblocking for*/
2534
        /* all edges of all macroblocks with out any restrictions             */
2535
        /*                                                                    */
2536
        /* if disable deblock level is '2' this implies enable deblocking for */
2537
        /* all edges of all macroblocks except edges overlapping with slice   */
2538
        /* boundaries. This option is not currently supported by the encoder  */
2539
        /* hence the slice map should be of no significance to perform debloc */
2540
        /* king                                                               */
2541
        /**********************************************************************/
2542
2543
9.33M
        if(ps_proc->u4_compute_recon)
2544
9.38M
        {
2545
            /* compute blocking strength */
2546
9.38M
            if(ps_proc->u4_disable_deblock_level != 1)
2547
7.12M
            {
2548
7.12M
                isvce_compute_bs(ps_proc, 0);
2549
2550
7.12M
                if(ENABLE_INTRA_BASE_DEBLOCK && (ps_proc->u1_spatial_layer_id <
2551
0
                                                 (ps_proc->s_svc_params.u1_num_spatial_layers - 1)))
2552
0
                {
2553
0
                    isvce_compute_bs(ps_proc, 1);
2554
0
                }
2555
7.12M
            }
2556
            /* nmb deblocking and hpel and padding */
2557
9.38M
            isvce_dblk_n_mbs(ps_proc, 0);
2558
2559
9.38M
            if(ENABLE_INTRA_BASE_DEBLOCK &&
2560
0
               (ps_proc->u1_spatial_layer_id < (ps_proc->s_svc_params.u1_num_spatial_layers - 1)))
2561
0
            {
2562
0
                isvce_intra_base_dblk(ps_proc);
2563
0
            }
2564
2565
9.38M
            if(ps_proc->i4_mb_x == (ps_proc->i4_wd_mbs - 1) &&
2566
322k
               ps_proc->i4_mb_y == (ps_proc->i4_ht_mbs - 1))
2567
61.3k
            {
2568
61.3k
                isvce_svc_pad_frame(ps_proc);
2569
2570
61.3k
                isvce_pad_mb_mode_buf(ps_proc->ps_intra_pred_ctxt, ps_proc->u1_spatial_layer_id,
2571
61.3k
                                      ps_proc->s_svc_params.u1_num_spatial_layers,
2572
61.3k
                                      ps_proc->s_svc_params.d_spatial_res_ratio,
2573
61.3k
                                      ps_codec->s_cfg.u4_wd, ps_codec->s_cfg.u4_ht);
2574
61.3k
            }
2575
9.38M
        }
2576
2577
        /* update the context after for coding next mb */
2578
9.33M
        error_status = isvce_update_proc_ctxt(ps_proc);
2579
2580
9.33M
        if(error_status != IH264E_SUCCESS)
2581
0
        {
2582
0
            return error_status;
2583
0
        }
2584
2585
9.33M
        {
2586
9.33M
            UWORD8 u1_new_mb_qp;
2587
2588
9.33M
            u1_new_mb_qp =
2589
9.33M
                isvce_sub_pic_rc_get_mb_qp(ps_proc->ps_sub_pic_rc_ctxt, ps_proc->u1_mb_qp);
2590
2591
9.33M
            if(u1_new_mb_qp != ps_proc->u1_mb_qp)
2592
459k
            {
2593
459k
                ps_proc->u1_mb_qp = u1_new_mb_qp;
2594
459k
                ps_proc->u4_lambda = gu1_qp0[u1_new_mb_qp];
2595
2596
459k
                isvce_init_quant_params(ps_proc, ps_proc->u1_mb_qp);
2597
459k
            }
2598
9.33M
        }
2599
2600
        /* Once the last row is processed, mark the buffer status appropriately */
2601
9.33M
        if(ps_proc->i4_ht_mbs == ps_proc->i4_mb_y)
2602
61.3k
        {
2603
            /* Pointer to current picture buffer structure */
2604
61.3k
            svc_au_buf_t *ps_cur_pic = ps_proc->ps_cur_pic;
2605
2606
            /* Pointer to current picture's mv buffer structure */
2607
61.3k
            svc_au_data_t *ps_cur_mv_buf = ps_proc->ps_cur_mv_buf;
2608
2609
            /**********************************************************************/
2610
            /* if disable deblock level is '0' this implies enable deblocking for */
2611
            /* all edges of all macroblocks with out any restrictions             */
2612
            /*                                                                    */
2613
            /* if disable deblock level is '1' this implies disable deblocking for*/
2614
            /* all edges of all macroblocks with out any restrictions             */
2615
            /*                                                                    */
2616
            /* if disable deblock level is '2' this implies enable deblocking for */
2617
            /* all edges of all macroblocks except edges overlapping with slice   */
2618
            /* boundaries. This option is not currently supported by the encoder  */
2619
            /* hence the slice map should be of no significance to perform debloc */
2620
            /* king                                                               */
2621
            /**********************************************************************/
2622
61.3k
            error_status = ih264_buf_mgr_release(ps_codec->pv_svc_au_data_store_mgr,
2623
61.3k
                                                 ps_cur_mv_buf->i4_buf_id, BUF_MGR_CODEC);
2624
61.3k
            if(error_status != IH264E_SUCCESS)
2625
0
            {
2626
0
                return error_status;
2627
0
            }
2628
61.3k
            error_status = ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr, ps_cur_pic->i4_buf_id,
2629
61.3k
                                                 BUF_MGR_CODEC);
2630
61.3k
            if(error_status != IH264E_SUCCESS)
2631
0
            {
2632
0
                return error_status;
2633
0
            }
2634
61.3k
            if(ps_codec->s_cfg.u4_enable_recon)
2635
8.21k
            {
2636
                /* pic cnt */
2637
8.21k
                ps_codec->as_rec_buf[ctxt_sel].i4_pic_cnt = ps_proc->i4_pic_cnt;
2638
2639
                /* rec buffers */
2640
8.21k
                ps_codec->as_rec_buf[ctxt_sel].s_pic_buf = *ps_proc->ps_cur_pic;
2641
2642
                /* is last? */
2643
8.21k
                ps_codec->as_rec_buf[ctxt_sel].u4_is_last = ps_proc->s_entropy.u4_is_last;
2644
2645
                /* frame time stamp */
2646
8.21k
                ps_codec->as_rec_buf[ctxt_sel].u4_timestamp_high =
2647
8.21k
                    ps_proc->s_entropy.u4_timestamp_high;
2648
8.21k
                ps_codec->as_rec_buf[ctxt_sel].u4_timestamp_low =
2649
8.21k
                    ps_proc->s_entropy.u4_timestamp_low;
2650
8.21k
            }
2651
61.3k
        }
2652
9.33M
    }
2653
2654
283k
    DEBUG_HISTOGRAM_DUMP(ps_codec->s_cfg.i4_ht_mbs == ps_proc->i4_mb_y);
2655
2656
283k
    return error_status;
2657
322k
}
2658
2659
/**
2660
*******************************************************************************
2661
*
2662
* @brief
2663
*  entry point of a spawned encoder thread
2664
*
2665
* @par Description:
2666
*  The encoder thread dequeues a proc/entropy job from the encoder queue and
2667
*  calls necessary routines.
2668
*
2669
* @param[in] pv_proc
2670
*  Process context corresponding to the thread
2671
*
2672
* @returns  error status
2673
*
2674
* @remarks
2675
*
2676
*******************************************************************************
2677
*/
2678
WORD32 isvce_process_thread(void *pv_proc)
2679
161k
{
2680
161k
    job_t s_job;
2681
2682
161k
    isvce_process_ctxt_t *ps_proc = pv_proc;
2683
161k
    isvce_codec_t *ps_codec = ps_proc->ps_codec;
2684
2685
161k
    IH264_ERROR_T ret = IH264_SUCCESS;
2686
2687
161k
    WORD32 ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS;
2688
161k
    WORD32 error_status = IH264_SUCCESS;
2689
161k
    WORD32 is_blocking = 0;
2690
2691
161k
    ps_proc->i4_error_code = IH264_SUCCESS;
2692
2693
4.55M
    while(1)
2694
4.55M
    {
2695
        /* dequeue a job from the entropy queue */
2696
4.55M
        {
2697
4.55M
            bool b_is_entropy_state_invalid = false;
2698
4.55M
            WORD32 retval = ithread_mutex_lock(ps_codec->pv_entropy_mutex);
2699
4.55M
            volatile ISVCE_ENTROPY_THREAD_STATES_T *pe_entropy_thread_state =
2700
4.55M
                &ps_codec->ae_entropy_thread_exit_state[ctxt_sel];
2701
2702
            /* have the lock */
2703
4.55M
            if(retval == 0)
2704
4.55M
            {
2705
4.55M
                if(*pe_entropy_thread_state == INACTIVE)
2706
829k
                {
2707
                    /* no entropy threads are active, try dequeuing a job from the entropy
2708
                     * queue */
2709
829k
                    ret = ih264_list_dequeue(ps_proc->pv_entropy_jobq, &s_job, is_blocking);
2710
2711
829k
                    if(IH264_SUCCESS == ret)
2712
322k
                    {
2713
322k
                        *pe_entropy_thread_state = IN_PROCESS;
2714
322k
                        ithread_mutex_unlock(ps_codec->pv_entropy_mutex);
2715
322k
                        goto WORKER;
2716
322k
                    }
2717
507k
                    else if(is_blocking)
2718
60.8k
                    {
2719
60.8k
                        ithread_mutex_unlock(ps_codec->pv_entropy_mutex);
2720
60.8k
                        break;
2721
60.8k
                    }
2722
829k
                }
2723
3.72M
                else if(*pe_entropy_thread_state == ERRONEOUS_EXIT)
2724
4.43k
                {
2725
4.43k
                    b_is_entropy_state_invalid = true;
2726
4.43k
                }
2727
2728
4.17M
                ithread_mutex_unlock(ps_codec->pv_entropy_mutex);
2729
4.17M
            }
2730
2731
4.17M
            if(b_is_entropy_state_invalid)
2732
4.43k
            {
2733
4.43k
                ps_proc->i4_error_code = IH264_FAIL;
2734
2735
4.43k
                return IH264_FAIL;
2736
4.43k
            }
2737
4.17M
        }
2738
2739
        /* dequeue a job from the process queue */
2740
4.16M
        ret = ih264_list_dequeue(ps_proc->pv_proc_jobq, &s_job, 1);
2741
4.16M
        if(IH264_SUCCESS != ret)
2742
3.84M
        {
2743
3.84M
            if(ps_proc->i4_id)
2744
95.8k
            {
2745
95.8k
                break;
2746
95.8k
            }
2747
3.75M
            else
2748
3.75M
            {
2749
3.75M
                is_blocking = 1;
2750
3.75M
                continue;
2751
3.75M
            }
2752
3.84M
        }
2753
2754
645k
    WORKER:
2755
        /* choose appropriate proc context based on proc_base_idx */
2756
645k
        switch(s_job.i4_cmd)
2757
645k
        {
2758
322k
            case CMD_PROCESS:
2759
322k
            {
2760
322k
                ps_proc->i4_mb_cnt = s_job.i2_mb_cnt;
2761
322k
                ps_proc->i4_mb_x = s_job.i2_mb_x;
2762
322k
                ps_proc->i4_mb_y = s_job.i2_mb_y;
2763
2764
322k
                isvce_init_layer_proc_ctxt(ps_proc);
2765
2766
322k
                error_status = isvce_process(ps_proc);
2767
2768
322k
                if(error_status != IH264_SUCCESS)
2769
0
                {
2770
0
                    ps_codec->ae_entropy_thread_exit_state[ctxt_sel] = ERRONEOUS_EXIT;
2771
0
                    ps_proc->i4_error_code = error_status;
2772
0
                    return ret;
2773
0
                }
2774
2775
322k
                break;
2776
322k
            }
2777
322k
            case CMD_ENTROPY:
2778
322k
            {
2779
322k
                ps_proc->s_entropy.i4_mb_x = s_job.i2_mb_x;
2780
322k
                ps_proc->s_entropy.i4_mb_y = s_job.i2_mb_y;
2781
322k
                ps_proc->s_entropy.i4_mb_cnt = s_job.i2_mb_cnt;
2782
2783
322k
                isvce_init_entropy_ctxt(ps_proc);
2784
2785
322k
                error_status = isvce_entropy(ps_proc);
2786
2787
322k
                if(error_status != IH264_SUCCESS)
2788
661
                {
2789
661
                    ps_codec->ae_entropy_thread_exit_state[ctxt_sel] = ERRONEOUS_EXIT;
2790
661
                    ps_proc->i4_error_code = error_status;
2791
661
                    return ret;
2792
661
                }
2793
2794
321k
                break;
2795
322k
            }
2796
321k
            default:
2797
0
            {
2798
0
                ps_proc->i4_error_code = IH264_FAIL;
2799
0
                return ret;
2800
322k
            }
2801
645k
        }
2802
645k
    }
2803
2804
157k
    return ret;
2805
161k
}