Coverage Report

Created: 2026-02-14 06:46

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.19k
{
138
4.19k
    sps_t *ps_sps;
139
4.19k
    pps_t *ps_pps;
140
4.19k
    subset_sps_t *ps_subset_sps;
141
142
4.19k
    WORD32 i;
143
144
4.19k
    isvce_process_ctxt_t *ps_proc = ps_codec->as_process;
145
4.19k
    isvce_entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
146
4.19k
    bitstrm_t *ps_bitstrm = ps_entropy->ps_bitstrm;
147
4.19k
    isvce_out_buf_t *ps_out_buf = ps_codec->as_out_buf;
148
149
4.19k
    UWORD8 u1_profile_idc = IH264_PROFILE_BASELINE;
150
151
4.19k
    ASSERT(1 == MAX_CTXT_SETS);
152
153
4.19k
    ih264e_bitstrm_init(ps_bitstrm, ps_out_buf->as_bits_buf[ps_proc->u1_spatial_layer_id].pv_buf,
154
4.19k
                        ps_out_buf->as_bits_buf[ps_proc->u1_spatial_layer_id].u4_bufsize);
155
156
4.19k
    ps_sps = ps_codec->ps_sps_base;
157
4.19k
    isvce_populate_sps(ps_codec, ps_sps, 0, u1_profile_idc, ps_inp_buf, 0);
158
159
4.19k
    ps_pps = ps_codec->ps_pps_base;
160
4.19k
    isvce_populate_pps(ps_codec, ps_pps, 0, 0, 0);
161
162
9.68k
    for(i = 1; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers; i++)
163
5.48k
    {
164
5.48k
        ps_subset_sps = ps_codec->ps_subset_sps_base + i;
165
5.48k
        isvce_populate_subset_sps(ps_codec, ps_subset_sps, i, ps_inp_buf, i);
166
167
5.48k
        ps_pps = ps_codec->ps_pps_base + i;
168
5.48k
        isvce_populate_pps(ps_codec, ps_pps, i, i, i);
169
5.48k
    }
170
171
4.19k
    ps_entropy->i4_error_code = IH264E_SUCCESS;
172
173
4.19k
    ps_entropy->i4_error_code = isvce_generate_sps(ps_bitstrm, ps_sps, NAL_SPS);
174
4.19k
    if(ps_entropy->i4_error_code != IH264E_SUCCESS)
175
0
    {
176
0
        return ps_entropy->i4_error_code;
177
0
    }
178
179
4.19k
    ps_pps = ps_codec->ps_pps_base;
180
4.19k
    ps_entropy->i4_error_code = isvce_generate_pps(ps_bitstrm, ps_pps, ps_sps);
181
182
9.68k
    for(i = 1; i < ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers; i++)
183
5.48k
    {
184
5.48k
        ps_subset_sps = ps_codec->ps_subset_sps_base + i;
185
5.48k
        isvce_generate_subset_sps(ps_bitstrm, ps_subset_sps);
186
187
        /* populate pps header */
188
5.48k
        ps_pps = ps_codec->ps_pps_base + i;
189
5.48k
        isvce_generate_pps(ps_bitstrm, ps_pps, &ps_subset_sps->s_sps);
190
5.48k
    }
191
192
    /* queue output buffer */
193
4.19k
    ps_out_buf->as_bits_buf[ps_proc->u1_spatial_layer_id].u4_bytes = ps_bitstrm->u4_strm_buf_offset;
194
195
4.19k
    return ps_entropy->i4_error_code;
196
4.19k
}
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
257k
{
220
    /* codec context */
221
257k
    isvce_codec_t *ps_codec = ps_proc->ps_codec;
222
223
    /* entropy ctxt */
224
257k
    isvce_entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
225
226
    /* start address */
227
257k
    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
257k
    ps_entropy->i4_mb_end_add = ps_entropy->i4_mb_start_add + ps_entropy->i4_mb_cnt;
231
232
    /* slice index */
233
257k
    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
257k
    if(ps_entropy->i4_mb_start_add == 0)
238
50.4k
    {
239
50.4k
        ps_entropy->i4_sof = 1;
240
50.4k
    }
241
242
257k
    if(ps_entropy->i4_mb_x == 0)
243
257k
    {
244
        /* packed mb coeff data */
245
257k
        ps_entropy->pv_mb_coeff_data = ((UWORD8 *) ps_entropy->pv_pic_mb_coeff_data) +
246
257k
                                       ps_entropy->i4_mb_y * ps_codec->u4_size_coeff_data;
247
248
        /* packed mb header data */
249
257k
        ps_entropy->pv_mb_header_data = ((UWORD8 *) ps_entropy->pv_pic_mb_header_data) +
250
257k
                                        ps_entropy->i4_mb_y * ps_codec->u4_size_header_data;
251
257k
    }
252
253
257k
    return IH264E_SUCCESS;
254
257k
}
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
50.0k
{
286
50.0k
    WORD32 i4_proc_ctxt_sel_base = ctxt_sel ? (MAX_PROCESS_CTXT / 2) : 0;
287
288
50.0k
    isvce_process_ctxt_t *ps_proc = &ps_codec->as_process[i4_proc_ctxt_sel_base];
289
290
50.0k
#if ENABLE_RE_ENC_AS_SKIP
291
50.0k
    isvce_entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
292
293
50.0k
    UWORD8 u1_is_post_enc_skip = 0;
294
50.0k
#endif
295
296
    /* frame qp */
297
50.0k
    UWORD8 u1_frame_qp = ps_codec->au4_frame_qp[ps_proc->u1_spatial_layer_id];
298
299
    /* cbr rc return status */
300
50.0k
    WORD32 i4_stuffing_byte = 0;
301
302
    /* current frame stats */
303
50.0k
    frame_info_t s_frame_info;
304
50.0k
    picture_type_e rc_pic_type = I_PIC;
305
306
    /* temp var */
307
50.0k
    WORD32 i, j;
308
309
    /********************************************************************/
310
    /*                            BEGIN INIT                            */
311
    /********************************************************************/
312
313
    /* init frame info */
314
50.0k
    irc_init_frame_info(&s_frame_info);
315
316
    /* get frame info */
317
169k
    for(i = 0; i < (WORD32) ps_codec->s_cfg.u4_num_cores; i++)
318
119k
    {
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
357k
        for(j = 0; j < MAX_MB_TYPE; j++)
325
238k
        {
326
238k
            s_frame_info.num_mbs[j] += ps_proc[i].s_frame_info.num_mbs[j];
327
328
238k
            s_frame_info.tot_mb_sad[j] += ps_proc[i].s_frame_info.tot_mb_sad[j];
329
330
238k
            s_frame_info.qp_sum[j] += ps_proc[i].s_frame_info.qp_sum[j];
331
238k
        }
332
333
119k
        s_frame_info.intra_mb_cost_sum += ps_proc[i].s_frame_info.intra_mb_cost_sum;
334
335
119k
        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
119k
        isvce_update_rc_bits_info(&s_frame_info, &ps_proc[i].s_entropy);
341
119k
    }
342
343
    /* get pic type */
344
50.0k
    switch(ps_codec->pic_type)
345
50.0k
    {
346
2.05k
        case PIC_I:
347
16.6k
        case PIC_IDR:
348
16.6k
            rc_pic_type = I_PIC;
349
16.6k
            break;
350
33.3k
        case PIC_P:
351
33.3k
            rc_pic_type = P_PIC;
352
33.3k
            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
50.0k
    }
360
361
    /* update rc lib with current frame stats */
362
50.0k
    i4_stuffing_byte = isvce_rc_post_enc(
363
50.0k
        ps_codec->s_rate_control.apps_rate_control_api[ps_proc->u1_spatial_layer_id],
364
50.0k
        &(s_frame_info), ps_codec->s_rate_control.pps_pd_frm_rate,
365
50.0k
        ps_codec->s_rate_control.pps_time_stamp, ps_codec->s_rate_control.pps_frame_time,
366
50.0k
        (ps_proc->i4_wd_mbs * ps_proc->i4_ht_mbs), &rc_pic_type, i4_is_first_frm,
367
50.0k
        &ps_codec->s_rate_control.post_encode_skip[ctxt_sel], u1_frame_qp,
368
50.0k
        &ps_codec->s_rate_control.ai4_num_intra_in_prev_frame[ps_proc->u1_spatial_layer_id],
369
50.0k
        &ps_codec->s_rate_control.ai4_avg_activity[ps_proc->u1_spatial_layer_id]
370
50.0k
#if ENABLE_RE_ENC_AS_SKIP
371
50.0k
        ,
372
50.0k
        &u1_is_post_enc_skip
373
50.0k
#endif
374
50.0k
    );
375
376
50.0k
#if ENABLE_RE_ENC_AS_SKIP
377
50.0k
    if(u1_is_post_enc_skip)
378
12.5k
    {
379
12.5k
        buffer_container_t s_dst;
380
381
12.5k
        WORD32 i;
382
383
12.5k
        isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
384
12.5k
        mem_fxns_t *ps_mem_fxns = &ps_isa_dependent_fxns->s_mem_fxns;
385
12.5k
        svc_ilp_data_t *ps_svc_ilp_data = &ps_codec->s_svc_ilp_data;
386
387
12.5k
        UWORD8 u1_spatial_layer_id = ps_proc->u1_spatial_layer_id;
388
12.5k
        UWORD8 u1_num_spatial_layers = ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers;
389
390
12.5k
        UWORD32 u4_wd = ps_codec->s_cfg.u4_wd;
391
12.5k
        UWORD32 u4_ht = ps_codec->s_cfg.u4_ht;
392
12.5k
        DOUBLE d_spatial_res_ratio = ps_codec->s_cfg.s_svc_params.d_spatial_res_ratio;
393
394
12.5k
        WORD32 i4_layer_luma_wd =
395
12.5k
            (WORD32) (((DOUBLE) u4_wd /
396
12.5k
                       pow(d_spatial_res_ratio, u1_num_spatial_layers - u1_spatial_layer_id - 1)) +
397
12.5k
                      0.99);
398
12.5k
        WORD32 i4_layer_luma_ht =
399
12.5k
            (WORD32) (((DOUBLE) u4_ht /
400
12.5k
                       pow(d_spatial_res_ratio, u1_num_spatial_layers - u1_spatial_layer_id - 1)) +
401
12.5k
                      0.99);
402
403
12.5k
        if(CABAC == ps_entropy->u1_entropy_coding_mode_flag)
404
2.05k
        {
405
2.05k
            isvce_reencode_as_skip_frame_cabac(ps_entropy);
406
2.05k
        }
407
10.5k
        else
408
10.5k
        {
409
10.5k
            isvce_reencode_as_skip_frame_cavlc(ps_entropy);
410
10.5k
        }
411
412
12.5k
        if(u1_num_spatial_layers > 1)
413
10.9k
        {
414
38.5k
            for(i = 0; i < ps_proc->i4_ht_mbs; i++)
415
27.5k
            {
416
190k
                for(j = 0; j < ps_proc->i4_wd_mbs; j++)
417
162k
                {
418
162k
                    isvce_update_ibl_info(ps_proc->ps_intra_pred_ctxt, u1_num_spatial_layers,
419
162k
                                          u1_spatial_layer_id, PSKIP, j, i, 0);
420
162k
                }
421
27.5k
            }
422
423
10.9k
            if(ENABLE_ILP_MV)
424
10.9k
            {
425
10.9k
                svc_layer_data_t *ps_layer_data;
426
427
10.9k
                svc_au_data_t *ps_svc_au_data = ps_svc_ilp_data->ps_svc_au_data;
428
429
10.9k
                WORD32 i4_num_mbs = ps_proc->i4_ht_mbs * ps_proc->i4_wd_mbs;
430
431
10.9k
                ps_layer_data = &ps_svc_au_data->ps_svc_layer_data[ps_entropy->u1_spatial_layer_id];
432
433
10.9k
                memset(ps_layer_data->ps_mb_info, 0,
434
10.9k
                       i4_num_mbs * sizeof(ps_layer_data->ps_mb_info[0]));
435
436
173k
                for(i = 0; i < i4_num_mbs; i++)
437
162k
                {
438
162k
                    ps_layer_data->pu4_num_pus_in_mb[i] = 1;
439
162k
                }
440
10.9k
            }
441
10.9k
        }
442
443
37.7k
        for(i = 0; i < NUM_SP_COMPONENTS; i++)
444
25.1k
        {
445
25.1k
            UWORD8 u1_is_chroma = (Y != ((COMPONENT_TYPE) i));
446
25.1k
            WORD32 i4_src_strd = ps_proc->aps_ref_pic[0]
447
25.1k
                                     ->ps_layer_yuv_buf_props[u1_spatial_layer_id]
448
25.1k
                                     .as_component_bufs[i]
449
25.1k
                                     .i4_data_stride;
450
25.1k
            WORD32 i4_dst_strd = ps_proc->ps_cur_pic->ps_layer_yuv_buf_props[u1_spatial_layer_id]
451
25.1k
                                     .as_component_bufs[i]
452
25.1k
                                     .i4_data_stride;
453
454
25.1k
            if(u1_spatial_layer_id < (u1_num_spatial_layers - 1))
455
13.6k
            {
456
13.6k
                s_dst.i4_data_stride = ps_svc_ilp_data->ps_intra_recon_bufs[u1_spatial_layer_id]
457
13.6k
                                           .as_component_bufs[i]
458
13.6k
                                           .i4_data_stride;
459
13.6k
                s_dst.pv_data =
460
13.6k
                    ((UWORD8 *) ps_svc_ilp_data->ps_intra_recon_bufs[u1_spatial_layer_id]
461
13.6k
                         .as_component_bufs[i]
462
13.6k
                         .pv_data);
463
464
13.6k
                ps_mem_fxns->pf_memset_2d((UWORD8 *) s_dst.pv_data, s_dst.i4_data_stride, 0,
465
13.6k
                                          i4_layer_luma_wd, (i4_layer_luma_ht >> u1_is_chroma));
466
467
13.6k
                if(ENABLE_RESIDUAL_PREDICTION)
468
13.6k
                {
469
13.6k
                    WORD16 *pi2_res;
470
13.6k
                    yuv_buf_props_t *ps_residual_buf =
471
13.6k
                        &ps_codec->s_svc_ilp_data.ps_residual_bufs[u1_spatial_layer_id];
472
473
13.6k
                    pi2_res = ps_residual_buf->as_component_bufs[u1_is_chroma].pv_data;
474
475
13.6k
                    ps_mem_fxns->pf_memset_2d(
476
13.6k
                        (UWORD8 *) pi2_res,
477
13.6k
                        ps_residual_buf->as_component_bufs[u1_is_chroma].i4_data_stride *
478
13.6k
                            (sizeof(WORD16) / sizeof(UWORD8)),
479
13.6k
                        0,
480
13.6k
                        ps_residual_buf->as_component_bufs[u1_is_chroma].i4_data_stride *
481
13.6k
                            (sizeof(WORD16) / sizeof(UWORD8)),
482
13.6k
                        i4_layer_luma_ht >> u1_is_chroma);
483
13.6k
                }
484
13.6k
            }
485
486
25.1k
            ps_mem_fxns->pf_copy_2d(
487
25.1k
                (UWORD8 *) (ps_proc->ps_cur_pic->ps_layer_yuv_buf_props[u1_spatial_layer_id]
488
25.1k
                                .as_component_bufs[i]
489
25.1k
                                .pv_data) -
490
25.1k
                    PAD_LEFT - (PAD_TOP * i4_dst_strd),
491
25.1k
                i4_dst_strd,
492
25.1k
                (UWORD8 *) (ps_proc->aps_ref_pic[0]
493
25.1k
                                ->ps_layer_yuv_buf_props[u1_spatial_layer_id]
494
25.1k
                                .as_component_bufs[i]
495
25.1k
                                .pv_data) -
496
25.1k
                    PAD_LEFT - (PAD_TOP * i4_src_strd),
497
25.1k
                i4_src_strd, (i4_layer_luma_wd + PAD_WD),
498
25.1k
                (i4_layer_luma_ht >> u1_is_chroma) + PAD_HT);
499
25.1k
        }
500
501
12.5k
        RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
502
12.5k
    }
503
504
50.0k
#endif
505
50.0k
    return i4_stuffing_byte;
506
50.0k
}
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
257k
{
531
257k
    svc_nalu_ext_t *aps_svc_nalu_ext[2];
532
257k
    isvce_out_buf_t s_out_buf;
533
257k
    sei_params_t s_sei;
534
257k
    nalu_info_t *ps_slice_nalu_info;
535
257k
    nalu_info_t *ps_non_vcl_nalu_info;
536
537
257k
    UWORD8 *pu1_proc_map;
538
257k
    UWORD8 *pu1_entropy_map_curr;
539
257k
    WORD32 i4_wd_mbs, i4_ht_mbs;
540
257k
    UWORD32 u4_mb_cnt, u4_mb_idx, u4_mb_end_idx, u4_insert_per_idr;
541
257k
    WORD32 bitstream_start_offset, bitstream_end_offset;
542
543
257k
    isvce_codec_t *ps_codec = ps_proc->ps_codec;
544
257k
    isvce_entropy_ctxt_t *ps_entropy = &ps_proc->s_entropy;
545
257k
    isvce_cabac_ctxt_t *ps_cabac_ctxt = ps_entropy->ps_cabac;
546
257k
    sps_t *ps_sps = ps_entropy->ps_sps_base;
547
257k
    subset_sps_t *ps_subset_sps = ps_entropy->ps_subset_sps_base;
548
257k
    pps_t *ps_pps = ps_entropy->ps_pps_base;
549
257k
    slice_header_t *ps_slice_hdr =
550
257k
        ps_entropy->ps_slice_hdr_base + (ps_entropy->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
551
257k
    svc_slice_header_t *ps_svc_slice_hdr = NULL;
552
257k
    bitstrm_t *ps_bitstrm = ps_entropy->ps_bitstrm;
553
257k
#if ENABLE_RE_ENC_AS_SKIP
554
257k
    bitstrm_t *ps_bitstrm_after_slice_hdr = ps_entropy->ps_bitstrm_after_slice_hdr;
555
257k
#endif
556
257k
    nalu_descriptors_t *ps_nalu_descriptor =
557
257k
        &ps_codec->as_nalu_descriptors[ps_proc->u1_spatial_layer_id];
558
559
257k
    WORD32 i4_slice_type = ps_proc->i4_slice_type;
560
257k
    WORD32 ctxt_sel = ps_proc->i4_encode_api_call_cnt % MAX_CTXT_SETS;
561
562
257k
    aps_svc_nalu_ext[0] =
563
257k
        ps_entropy->ps_svc_nalu_ext_base + (ps_entropy->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
564
257k
    aps_svc_nalu_ext[1] = ps_entropy->ps_svc_nalu_ext_base + 1 +
565
257k
                          (ps_entropy->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
566
567
    /********************************************************************/
568
    /*                            BEGIN INIT                            */
569
    /********************************************************************/
570
571
    /* entropy encode start address */
572
257k
    u4_mb_idx = ps_entropy->i4_mb_start_add;
573
574
    /* entropy encode end address */
575
257k
    u4_mb_end_idx = ps_entropy->i4_mb_end_add;
576
577
    /* width in mbs */
578
257k
    i4_wd_mbs = ps_entropy->i4_wd_mbs;
579
580
    /* height in mbs */
581
257k
    i4_ht_mbs = ps_entropy->i4_ht_mbs;
582
583
    /* total mb cnt */
584
257k
    u4_mb_cnt = i4_wd_mbs * i4_ht_mbs;
585
586
    /* proc map */
587
257k
    pu1_proc_map = ps_proc->pu1_proc_map + ps_entropy->i4_mb_y * i4_wd_mbs;
588
589
    /* entropy map */
590
257k
    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
257k
    if(ps_entropy->i4_sof)
600
50.4k
    {
601
        /********************************************************************/
602
        /*      initialize the output buffer                                */
603
        /********************************************************************/
604
50.4k
        s_out_buf = ps_codec->as_out_buf[ctxt_sel];
605
606
        /* is last frame to encode */
607
50.4k
        s_out_buf.u4_is_last = ps_entropy->u4_is_last;
608
609
        /* frame idx */
610
50.4k
        s_out_buf.u4_timestamp_high = ps_entropy->u4_timestamp_high;
611
50.4k
        s_out_buf.u4_timestamp_low = ps_entropy->u4_timestamp_low;
612
613
        /********************************************************************/
614
        /*      initialize the bit stream buffer                            */
615
        /********************************************************************/
616
50.4k
        ih264e_bitstrm_init(ps_bitstrm, s_out_buf.as_bits_buf[ps_proc->u1_spatial_layer_id].pv_buf,
617
50.4k
                            s_out_buf.as_bits_buf[ps_proc->u1_spatial_layer_id].u4_bufsize);
618
619
        /********************************************************************/
620
        /*                    BEGIN HEADER GENERATION                       */
621
        /********************************************************************/
622
50.4k
        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
50.4k
        ps_svc_slice_hdr = ps_entropy->ps_svc_slice_hdr_base +
690
50.4k
                           (ps_entropy->i4_cur_slice_idx % SVC_MAX_SLICE_HDR_CNT);
691
692
50.4k
        if((ps_codec->s_cfg.s_svc_params.u1_num_temporal_layers > 1) ||
693
22.5k
           (ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers > 1))
694
47.5k
        {
695
47.5k
            isvce_populate_svc_nalu_extension(ps_proc, aps_svc_nalu_ext[0], NAL_PREFIX,
696
47.5k
                                              ps_proc->u4_is_idr);
697
698
47.5k
            if(ps_proc->u1_spatial_layer_id > 0)
699
26.9k
            {
700
26.9k
                isvce_populate_svc_nalu_extension(ps_proc, aps_svc_nalu_ext[1],
701
26.9k
                                                  NAL_CODED_SLICE_EXTENSION, ps_proc->u4_is_idr);
702
26.9k
            }
703
47.5k
        }
704
2.88k
        else
705
2.88k
        {
706
2.88k
            isvce_populate_svc_nalu_extension(ps_proc, aps_svc_nalu_ext[0], NAL_PREFIX,
707
2.88k
                                              ps_proc->u4_is_idr);
708
2.88k
        }
709
710
50.4k
        if(ps_proc->u1_spatial_layer_id > 0)
711
26.9k
        {
712
26.9k
            ps_subset_sps = ps_entropy->ps_subset_sps_base + ps_proc->u1_spatial_layer_id;
713
26.9k
            ps_pps = ps_entropy->ps_pps_base + ps_proc->u1_spatial_layer_id;
714
715
26.9k
            ps_entropy->i4_error_code = isvce_populate_svc_slice(
716
26.9k
                ps_proc, ps_svc_slice_hdr, ps_pps, ps_subset_sps, aps_svc_nalu_ext[1]);
717
718
26.9k
            RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
719
720
26.9k
            ps_slice_hdr = &ps_svc_slice_hdr->s_slice_header;
721
26.9k
        }
722
23.5k
        else
723
23.5k
        {
724
23.5k
            ps_pps = ps_entropy->ps_pps_base;
725
23.5k
            ps_sps = ps_entropy->ps_sps_base;
726
727
23.5k
            ps_entropy->i4_error_code = isvce_populate_slice_header(
728
23.5k
                ps_proc, ps_slice_hdr, ps_pps, ps_sps, aps_svc_nalu_ext[0]->u1_idr_flag);
729
730
23.5k
            RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
731
23.5k
        }
732
733
        /* generate sei */
734
50.4k
        u4_insert_per_idr = (NAL_SLICE_IDR == ps_slice_hdr->i1_nal_unit_type);
735
736
50.4k
        memset(&s_sei, 0, sizeof(sei_params_t));
737
50.4k
        s_sei.u1_sei_mdcv_params_present_flag =
738
50.4k
            ps_codec->s_cfg.s_sei.u1_sei_mdcv_params_present_flag;
739
50.4k
        s_sei.s_sei_mdcv_params = ps_codec->s_cfg.s_sei.s_sei_mdcv_params;
740
50.4k
        s_sei.u1_sei_cll_params_present_flag = ps_codec->s_cfg.s_sei.u1_sei_cll_params_present_flag;
741
50.4k
        s_sei.s_sei_cll_params = ps_codec->s_cfg.s_sei.s_sei_cll_params;
742
50.4k
        s_sei.u1_sei_ave_params_present_flag = ps_codec->s_cfg.s_sei.u1_sei_ave_params_present_flag;
743
50.4k
        s_sei.s_sei_ave_params = ps_codec->s_cfg.s_sei.s_sei_ave_params;
744
50.4k
        s_sei.u1_sei_ccv_params_present_flag = 0;
745
50.4k
        s_sei.s_sei_ccv_params =
746
50.4k
            ps_codec->as_inp_list[ps_codec->i4_poc % SVC_MAX_NUM_INP_FRAMES].s_inp_props.s_sei_ccv;
747
748
50.4k
        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
50.4k
        if((1 == s_sei.u1_sei_mdcv_params_present_flag && u4_insert_per_idr) ||
763
47.2k
           (1 == s_sei.u1_sei_cll_params_present_flag && u4_insert_per_idr) ||
764
45.9k
           (1 == s_sei.u1_sei_ave_params_present_flag && u4_insert_per_idr) ||
765
44.9k
           (1 == s_sei.u1_sei_ccv_params_present_flag))
766
5.55k
        {
767
5.55k
            ps_non_vcl_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
768
5.55k
            isvce_nalu_info_buf_init(ps_non_vcl_nalu_info,
769
5.55k
                                     -((WORD32) isvce_get_num_bits(ps_bitstrm)), NAL_SEI,
770
5.55k
                                     ps_proc->u1_spatial_layer_id,
771
5.55k
                                     ps_proc->ps_cur_pic->i1_temporal_id, 1, !!ps_proc->u4_is_idr);
772
773
5.55k
            ps_entropy->i4_error_code = ih264e_generate_sei(ps_bitstrm, &s_sei, u4_insert_per_idr);
774
5.55k
            RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
775
776
5.55k
            ps_non_vcl_nalu_info->i8_num_bits += isvce_get_num_bits(ps_bitstrm);
777
5.55k
            isvce_update_nalu_count(ps_nalu_descriptor);
778
5.55k
        }
779
780
50.4k
        ps_codec->as_inp_list[ps_codec->i4_poc % SVC_MAX_NUM_INP_FRAMES]
781
50.4k
            .s_inp_props.u1_sei_ccv_params_present_flag = 0;
782
783
50.4k
        if((ps_proc->u1_spatial_layer_id == 0) &&
784
23.5k
           (ps_codec->s_cfg.s_svc_params.u1_num_temporal_layers > 1 ||
785
10.2k
            ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers > 1))
786
20.6k
        {
787
20.6k
            ps_non_vcl_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
788
20.6k
            isvce_nalu_info_buf_init(ps_non_vcl_nalu_info,
789
20.6k
                                     -((WORD32) isvce_get_num_bits(ps_bitstrm)), NAL_PREFIX,
790
20.6k
                                     ps_proc->u1_spatial_layer_id,
791
20.6k
                                     ps_proc->ps_cur_pic->i1_temporal_id, 1, !!ps_proc->u4_is_idr);
792
793
20.6k
            ps_entropy->i4_error_code =
794
20.6k
                isvce_generate_svc_nalu_extension(ps_bitstrm, aps_svc_nalu_ext[0], NAL_PREFIX);
795
796
20.6k
            ps_entropy->i4_error_code = isvce_generate_prefix_nal(
797
20.6k
                ps_bitstrm, aps_svc_nalu_ext[0], ps_slice_hdr, ps_sps->u1_max_num_ref_frames,
798
20.6k
                ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers);
799
20.6k
            RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
800
801
20.6k
            ps_non_vcl_nalu_info->i8_num_bits += isvce_get_num_bits(ps_bitstrm);
802
20.6k
            isvce_update_nalu_count(ps_nalu_descriptor);
803
20.6k
        }
804
805
50.4k
        ps_slice_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
806
50.4k
        isvce_nalu_info_buf_init(ps_slice_nalu_info, -((WORD32) isvce_get_num_bits(ps_bitstrm)),
807
50.4k
                                 ps_slice_hdr->i1_nal_unit_type, ps_proc->u1_spatial_layer_id,
808
50.4k
                                 ps_proc->ps_cur_pic->i1_temporal_id, 1, !!ps_proc->u4_is_idr);
809
810
50.4k
        if(ps_proc->u1_spatial_layer_id > 0)
811
26.9k
        {
812
26.9k
            ps_subset_sps = ps_entropy->ps_subset_sps_base + ps_proc->u1_spatial_layer_id;
813
26.9k
            ps_pps = ps_entropy->ps_pps_base + ps_proc->u1_spatial_layer_id;
814
815
26.9k
            ps_entropy->i4_error_code = isvce_generate_svc_nalu_extension(
816
26.9k
                ps_bitstrm, aps_svc_nalu_ext[1], NAL_CODED_SLICE_EXTENSION);
817
818
26.9k
            ps_entropy->i4_error_code = isvce_generate_slice_header_svc(
819
26.9k
                ps_bitstrm, ps_pps, aps_svc_nalu_ext[1], ps_svc_slice_hdr, ps_subset_sps);
820
821
26.9k
            RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
822
26.9k
        }
823
23.5k
        else
824
23.5k
        {
825
            /* generate slice header */
826
23.5k
            ps_entropy->i4_error_code = isvce_generate_slice_header(
827
23.5k
                ps_bitstrm, ps_slice_hdr, ps_pps, ps_sps, aps_svc_nalu_ext[0]->u1_idr_flag);
828
829
23.5k
            RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
830
23.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
50.4k
        ps_entropy->i4_sof = 0;
835
836
50.4k
        if(CABAC == ps_entropy->u1_entropy_coding_mode_flag)
837
7.94k
        {
838
7.94k
            BITSTREAM_BYTE_ALIGN(ps_bitstrm);
839
7.94k
            BITSTREAM_FLUSH(ps_bitstrm, ps_entropy->i4_error_code);
840
7.94k
            isvce_init_cabac_ctxt(ps_entropy, ps_slice_hdr);
841
7.94k
        }
842
843
50.4k
#if ENABLE_RE_ENC_AS_SKIP
844
50.4k
        ps_bitstrm_after_slice_hdr[0] = ps_bitstrm[0];
845
50.4k
#endif
846
50.4k
    }
847
848
    /* begin entropy coding for the mb set */
849
7.36M
    while(u4_mb_idx < u4_mb_end_idx)
850
7.10M
    {
851
7.10M
        mb_bits_info_t s_mb_bits = {
852
7.10M
            .i8_header_bits = -((WORD64) ps_entropy->u4_header_bits[i4_slice_type == PSLICE]),
853
7.10M
            .i8_texture_bits = -((WORD64) ps_entropy->u4_residue_bits[i4_slice_type == PSLICE])};
854
855
        /* init ptrs/indices */
856
7.10M
        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
7.10M
        DEBUG("\nmb indices x, y %d, %d", ps_entropy->i4_mb_x, ps_entropy->i4_mb_y);
877
7.10M
        ENTROPY_TRACE("mb index x %d", ps_entropy->i4_mb_x);
878
7.10M
        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
7.10M
        while(1)
885
7.10M
        {
886
7.10M
            volatile UWORD8 *pu1_buf1;
887
7.10M
            WORD32 idx = ps_entropy->i4_mb_x;
888
889
7.10M
            pu1_buf1 = pu1_proc_map + idx;
890
7.10M
            if(*pu1_buf1) break;
891
3
            ithread_yield();
892
3
        }
893
894
        /* write mb layer */
895
7.10M
        ps_entropy->i4_error_code =
896
7.10M
            ps_codec->pf_write_mb_syntax_layer[ps_entropy->u1_entropy_coding_mode_flag]
897
7.10M
                                              [i4_slice_type](ps_entropy);
898
7.10M
        RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
899
900
        /* Starting bitstream offset for header in bits */
901
7.10M
        bitstream_start_offset = isvce_get_num_bits(ps_bitstrm);
902
903
        /* set entropy map */
904
7.10M
        pu1_entropy_map_curr[ps_entropy->i4_mb_x] = 1;
905
7.10M
        ASSERT(ps_entropy->i4_mb_x < i4_wd_mbs);
906
907
7.10M
        u4_mb_idx++;
908
7.10M
        ps_entropy->i4_mb_x++;
909
        /* check for eof */
910
7.10M
        if(CABAC == ps_entropy->u1_entropy_coding_mode_flag)
911
3.40M
        {
912
3.40M
            if(ps_entropy->i4_mb_x < i4_wd_mbs)
913
3.33M
            {
914
3.33M
                isvce_cabac_encode_terminate(ps_cabac_ctxt, 0);
915
3.33M
            }
916
3.40M
        }
917
918
7.10M
        if(ps_entropy->i4_mb_x == i4_wd_mbs)
919
256k
        {
920
            /* if slices are enabled */
921
256k
            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
256k
        }
1008
1009
        /* Ending bitstream offset for header in bits */
1010
7.10M
        bitstream_end_offset = isvce_get_num_bits(ps_bitstrm);
1011
7.10M
        ps_entropy->u4_header_bits[i4_slice_type == PSLICE] +=
1012
7.10M
            bitstream_end_offset - bitstream_start_offset;
1013
1014
7.10M
        {
1015
7.10M
            svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt = ps_proc->ps_sub_pic_rc_ctxt;
1016
7.10M
            svc_sub_pic_rc_entropy_variables_t *ps_sub_pic_rc_variables =
1017
7.10M
                &ps_sub_pic_rc_ctxt->s_sub_pic_rc_entropy_variables;
1018
1019
7.10M
            s_mb_bits.i8_header_bits += ps_entropy->u4_header_bits[i4_slice_type == PSLICE];
1020
7.10M
            s_mb_bits.i8_texture_bits += ps_entropy->u4_residue_bits[i4_slice_type == PSLICE];
1021
1022
7.10M
            ps_sub_pic_rc_variables->s_mb_bits = s_mb_bits;
1023
7.10M
            ps_sub_pic_rc_variables->u1_spatial_layer_id = ps_proc->u1_spatial_layer_id;
1024
7.10M
            ps_sub_pic_rc_variables->s_mb_pos.i4_abscissa = ps_entropy->i4_mb_x - 1;
1025
7.10M
            ps_sub_pic_rc_variables->s_mb_pos.i4_ordinate = ps_entropy->i4_mb_y;
1026
1027
7.10M
            isvce_sub_pic_rc_get_entropy_data(ps_proc->ps_sub_pic_rc_ctxt);
1028
7.10M
        }
1029
7.10M
    }
1030
1031
    /* check for eof */
1032
256k
    if(u4_mb_idx == u4_mb_cnt)
1033
50.1k
    {
1034
        /* set end of frame flag */
1035
50.1k
        ps_entropy->i4_eof = 1;
1036
50.1k
    }
1037
206k
    else
1038
206k
    {
1039
206k
        if(CABAC == ps_entropy->u1_entropy_coding_mode_flag &&
1040
62.8k
           ps_codec->s_cfg.e_slice_mode != IVE_SLICE_MODE_BLOCKS)
1041
62.8k
        {
1042
62.8k
            isvce_cabac_encode_terminate(ps_cabac_ctxt, 0);
1043
62.8k
        }
1044
206k
    }
1045
1046
256k
    if(ps_entropy->i4_eof)
1047
50.1k
    {
1048
50.1k
        if(CAVLC == ps_entropy->u1_entropy_coding_mode_flag)
1049
42.3k
        {
1050
            /* mb skip run */
1051
42.3k
            if((i4_slice_type != ISLICE) && *ps_entropy->pi4_mb_skip_run)
1052
4.02k
            {
1053
4.02k
                if(*ps_entropy->pi4_mb_skip_run)
1054
4.02k
                {
1055
4.02k
                    PUT_BITS_UEV(ps_bitstrm, *ps_entropy->pi4_mb_skip_run,
1056
4.02k
                                 ps_entropy->i4_error_code, "mb skip run");
1057
4.02k
                    *ps_entropy->pi4_mb_skip_run = 0;
1058
4.02k
                    RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
1059
4.02k
                }
1060
4.02k
            }
1061
            /* put rbsp trailing bits */
1062
42.3k
            ps_entropy->i4_error_code = ih264e_put_rbsp_trailing_bits(ps_bitstrm);
1063
42.3k
            RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
1064
42.2k
        }
1065
7.80k
        else
1066
7.80k
        {
1067
7.80k
            isvce_cabac_encode_terminate(ps_cabac_ctxt, 1);
1068
7.80k
        }
1069
1070
        /* update current frame stats to rc library */
1071
        /* number of bytes to stuff */
1072
50.0k
        {
1073
50.0k
            WORD32 i4_stuff_bytes;
1074
1075
            /* update */
1076
50.0k
            i4_stuff_bytes = isvce_update_rc_post_enc(ps_codec, ctxt_sel, (ps_codec->i4_poc == 0));
1077
1078
50.0k
            if(ps_proc->u1_spatial_layer_id == (ps_proc->s_svc_params.u1_num_spatial_layers - 1))
1079
23.1k
            {
1080
                /* cbr rc - house keeping */
1081
23.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
23.1k
                else if(i4_stuff_bytes > 0)
1086
1.53k
                {
1087
                    /* add filler nal units */
1088
1.53k
                    ps_entropy->i4_error_code =
1089
1.53k
                        ih264e_add_filler_nal_unit(ps_bitstrm, i4_stuff_bytes);
1090
1.53k
                    RETURN_ENTROPY_IF_ERROR(ps_codec, ps_entropy, ctxt_sel);
1091
1.30k
                }
1092
23.1k
            }
1093
50.0k
        }
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
49.8k
        if(!ps_codec->s_rate_control.post_encode_skip[ctxt_sel] && ps_codec->u4_is_curr_frm_ref &&
1101
49.8k
           (ps_proc->u1_spatial_layer_id == ps_codec->s_cfg.s_svc_params.u1_num_spatial_layers - 1))
1102
22.9k
        {
1103
22.9k
            ps_codec->i4_frame_num++;
1104
22.9k
        }
1105
1106
        /********************************************************************/
1107
        /*      signal the output                                           */
1108
        /********************************************************************/
1109
49.8k
        ps_codec->as_out_buf[ctxt_sel].as_bits_buf[ps_entropy->u1_spatial_layer_id].u4_bytes =
1110
49.8k
            ps_bitstrm->u4_strm_buf_offset;
1111
1112
49.8k
        ps_slice_nalu_info = isvce_get_next_nalu_info_buf(ps_nalu_descriptor);
1113
49.8k
        ps_slice_nalu_info->i8_num_bits += isvce_get_num_bits(ps_bitstrm);
1114
49.8k
        isvce_update_nalu_count(ps_nalu_descriptor);
1115
1116
49.8k
        DEBUG("entropy status %x", ps_entropy->i4_error_code);
1117
49.8k
        ps_entropy->i4_eof = 0;
1118
49.8k
    }
1119
1120
    /* Dont execute any further instructions until store synchronization took
1121
     * place */
1122
256k
    DATA_SYNC();
1123
1124
    /* allow threads to dequeue entropy jobs */
1125
256k
    ps_codec->ae_entropy_thread_exit_state[ctxt_sel] = INACTIVE;
1126
1127
256k
    return ps_entropy->i4_error_code;
1128
256k
}
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
7.03M
{
1151
    /* curr mb type */
1152
7.03M
    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
7.03M
    if(u4_mb_type == I4x4)
1156
443k
    {
1157
        /* pointer to mb header storage space */
1158
443k
        UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
1159
443k
        isvce_mb_hdr_i4x4_t *ps_mb_hdr = (isvce_mb_hdr_i4x4_t *) ps_proc->pv_mb_header_data;
1160
1161
        /* temp var */
1162
443k
        WORD32 i4, byte;
1163
1164
        /* mb type plus mode */
1165
443k
        ps_mb_hdr->common.u1_mb_type_mode = (ps_proc->u1_c_i8_mode << 6) + u4_mb_type;
1166
1167
        /* cbp */
1168
443k
        ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
1169
1170
        /* mb qp delta */
1171
443k
        ps_mb_hdr->common.u1_mb_qp = ps_proc->u1_mb_qp;
1172
1173
443k
        ps_mb_hdr->common.u1_residual_prediction_flag =
1174
443k
            ps_proc->ps_mb_info->u1_residual_prediction_flag;
1175
1176
443k
        ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
1177
1178
        /* sub mb modes */
1179
3.98M
        for(i4 = 0; i4 < 16; i4++)
1180
3.54M
        {
1181
3.54M
            byte = 0;
1182
1183
3.54M
            if(ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i4] ==
1184
3.54M
               ps_proc->au1_intra_luma_mb_4x4_modes[i4])
1185
2.80M
            {
1186
2.80M
                byte |= 1;
1187
2.80M
            }
1188
741k
            else
1189
741k
            {
1190
741k
                if(ps_proc->au1_intra_luma_mb_4x4_modes[i4] <
1191
741k
                   ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i4])
1192
250k
                {
1193
250k
                    byte |= (ps_proc->au1_intra_luma_mb_4x4_modes[i4] << 1);
1194
250k
                }
1195
491k
                else
1196
491k
                {
1197
491k
                    byte |= (ps_proc->au1_intra_luma_mb_4x4_modes[i4] - 1) << 1;
1198
491k
                }
1199
741k
            }
1200
1201
3.54M
            i4++;
1202
1203
3.54M
            if(ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i4] ==
1204
3.54M
               ps_proc->au1_intra_luma_mb_4x4_modes[i4])
1205
2.84M
            {
1206
2.84M
                byte |= 16;
1207
2.84M
            }
1208
696k
            else
1209
696k
            {
1210
696k
                if(ps_proc->au1_intra_luma_mb_4x4_modes[i4] <
1211
696k
                   ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i4])
1212
207k
                {
1213
207k
                    byte |= (ps_proc->au1_intra_luma_mb_4x4_modes[i4] << 5);
1214
207k
                }
1215
488k
                else
1216
488k
                {
1217
488k
                    byte |= (ps_proc->au1_intra_luma_mb_4x4_modes[i4] - 1) << 5;
1218
488k
                }
1219
696k
            }
1220
1221
3.54M
            ps_mb_hdr->au1_sub_blk_modes[i4 >> 1] = byte;
1222
3.54M
        }
1223
1224
        /* end of mb layer */
1225
443k
        pu1_ptr += sizeof(isvce_mb_hdr_i4x4_t);
1226
443k
        ps_proc->pv_mb_header_data = pu1_ptr;
1227
443k
    }
1228
6.59M
    else if(u4_mb_type == I16x16)
1229
4.00M
    {
1230
        /* pointer to mb header storage space */
1231
4.00M
        UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
1232
4.00M
        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
4.00M
        ps_mb_hdr->common.u1_mb_type_mode =
1236
4.00M
            (ps_proc->u1_c_i8_mode << 6) + (ps_proc->u1_l_i16_mode << 4) + u4_mb_type;
1237
1238
        /* cbp */
1239
4.00M
        ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
1240
1241
        /* mb qp delta */
1242
4.00M
        ps_mb_hdr->common.u1_mb_qp = ps_proc->u1_mb_qp;
1243
1244
4.00M
        ps_mb_hdr->common.u1_residual_prediction_flag =
1245
4.00M
            ps_proc->ps_mb_info->u1_residual_prediction_flag;
1246
1247
4.00M
        ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
1248
1249
        /* end of mb layer */
1250
4.00M
        pu1_ptr += sizeof(isvce_mb_hdr_i16x16_t);
1251
4.00M
        ps_proc->pv_mb_header_data = pu1_ptr;
1252
4.00M
    }
1253
2.58M
    else if(u4_mb_type == P16x16)
1254
375k
    {
1255
        /* pointer to mb header storage space */
1256
375k
        UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
1257
375k
        isvce_mb_hdr_p16x16_t *ps_mb_hdr = (isvce_mb_hdr_p16x16_t *) ps_proc->pv_mb_header_data;
1258
1259
        /* mb type */
1260
375k
        ps_mb_hdr->common.u1_mb_type_mode = u4_mb_type;
1261
1262
        /* cbp */
1263
375k
        ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
1264
1265
        /* mb qp delta */
1266
375k
        ps_mb_hdr->common.u1_mb_qp = ps_proc->u1_mb_qp;
1267
1268
375k
        ps_mb_hdr->common.u1_residual_prediction_flag =
1269
375k
            ps_proc->ps_mb_info->u1_residual_prediction_flag;
1270
1271
375k
        ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
1272
1273
375k
        ps_mb_hdr->u1_mvp_idx = ps_proc->ps_mb_info->as_pu->au1_mvp_idx[L0];
1274
1275
375k
        if(0 == ps_proc->ps_mb_info->as_pu->au1_mvp_idx[L0])
1276
349k
        {
1277
349k
            ps_mb_hdr->ai2_mvd[0] = ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvx -
1278
349k
                                    ps_proc->ps_pred_mv[L0].s_mv.i2_mvx;
1279
349k
            ps_mb_hdr->ai2_mvd[1] = ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvy -
1280
349k
                                    ps_proc->ps_pred_mv[L0].s_mv.i2_mvy;
1281
349k
        }
1282
26.7k
        else
1283
26.7k
        {
1284
26.7k
            ps_mb_hdr->ai2_mvd[0] = ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvx -
1285
26.7k
                                    ps_proc->ps_ilp_mv->as_mv[0][L0].s_mv.i2_mvx;
1286
26.7k
            ps_mb_hdr->ai2_mvd[1] = ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvy -
1287
26.7k
                                    ps_proc->ps_ilp_mv->as_mv[0][L0].s_mv.i2_mvy;
1288
26.7k
        }
1289
1290
        /* end of mb layer */
1291
375k
        pu1_ptr += sizeof(isvce_mb_hdr_p16x16_t);
1292
375k
        ps_proc->pv_mb_header_data = pu1_ptr;
1293
375k
    }
1294
2.21M
    else if(u4_mb_type == PSKIP)
1295
231k
    {
1296
        /* pointer to mb header storage space */
1297
231k
        UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
1298
231k
        isvce_mb_hdr_pskip_t *ps_mb_hdr = (isvce_mb_hdr_pskip_t *) ps_proc->pv_mb_header_data;
1299
1300
        /* mb type */
1301
231k
        ps_mb_hdr->common.u1_mb_type_mode = u4_mb_type;
1302
1303
231k
        ps_mb_hdr->common.u1_residual_prediction_flag =
1304
231k
            ps_proc->ps_mb_info->u1_residual_prediction_flag;
1305
1306
231k
        ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
1307
1308
        /* end of mb layer */
1309
231k
        pu1_ptr += sizeof(isvce_mb_hdr_pskip_t);
1310
231k
        ps_proc->pv_mb_header_data = pu1_ptr;
1311
231k
    }
1312
1.98M
    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
1.98M
    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
1.98M
    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
1.98M
    else if(u4_mb_type == BASE_MODE)
1416
1.98M
    {
1417
1.98M
        isvce_mb_hdr_base_mode_t *ps_mb_hdr =
1418
1.98M
            (isvce_mb_hdr_base_mode_t *) ps_proc->pv_mb_header_data;
1419
1420
1.98M
        UWORD8 *pu1_ptr = ps_proc->pv_mb_header_data;
1421
1422
1.98M
        ASSERT(ps_proc->ps_mb_info->u1_base_mode_flag == 1);
1423
1424
1.98M
        ps_mb_hdr->common.u1_mb_type_mode = u4_mb_type;
1425
1426
1.98M
        ps_mb_hdr->common.u1_cbp = ps_proc->u4_cbp;
1427
1428
1.98M
        ps_mb_hdr->common.u1_mb_qp = ps_proc->u1_mb_qp;
1429
1430
1.98M
        ps_mb_hdr->common.u1_residual_prediction_flag =
1431
1.98M
            ps_proc->ps_mb_info->u1_residual_prediction_flag;
1432
1433
1.98M
        ps_mb_hdr->common.u1_base_mode_flag = ps_proc->ps_mb_info->u1_base_mode_flag;
1434
1435
1.98M
        pu1_ptr += sizeof(isvce_mb_hdr_base_mode_t);
1436
1.98M
        ps_proc->pv_mb_header_data = pu1_ptr;
1437
1.98M
    }
1438
1439
7.03M
    return IH264E_SUCCESS;
1440
7.03M
}
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
7.09M
{
1471
    /* error status */
1472
7.09M
    WORD32 error_status = IH264_SUCCESS;
1473
1474
    /* codec context */
1475
7.09M
    isvce_codec_t *ps_codec = ps_proc->ps_codec;
1476
7.09M
    isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
1477
7.09M
    mem_fxns_t *ps_mem_fxns = &ps_isa_dependent_fxns->s_mem_fxns;
1478
1479
    /* curr mb indices */
1480
7.09M
    WORD32 i4_mb_x = ps_proc->i4_mb_x;
1481
7.09M
    WORD32 i4_mb_y = ps_proc->i4_mb_y;
1482
1483
    /* mb syntax elements of neighbors */
1484
7.09M
    isvce_mb_info_t *ps_left_syn = ps_proc->s_nbr_info.ps_left_mb_info;
1485
7.09M
    isvce_mb_info_t *ps_top_syn =
1486
7.09M
        ps_proc->s_nbr_info_base.ps_layer_nbr_info[ps_proc->u1_spatial_layer_id]
1487
7.09M
            .ps_top_row_mb_info +
1488
7.09M
        i4_mb_x + i4_mb_y * ps_proc->i4_wd_mbs;
1489
1490
    /* curr mb type */
1491
7.09M
    UWORD32 u4_mb_type = ps_proc->ps_mb_info->u2_mb_type;
1492
1493
    /* curr mb type */
1494
7.09M
    UWORD32 u4_is_intra = ps_proc->ps_mb_info->u1_is_intra;
1495
1496
    /* width in mbs */
1497
7.09M
    WORD32 i4_wd_mbs = ps_proc->i4_wd_mbs;
1498
1499
    /*height in mbs*/
1500
7.09M
    WORD32 i4_ht_mbs = ps_proc->i4_ht_mbs;
1501
1502
    /* proc map */
1503
7.09M
    UWORD8 *pu1_proc_map = ps_proc->pu1_proc_map + (i4_mb_y * i4_wd_mbs);
1504
1505
    /* deblk context */
1506
7.09M
    isvce_deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
1507
1508
    /* deblk bs context */
1509
7.09M
    isvce_bs_ctxt_t *ps_bs = &(ps_deblk->s_bs_ctxt);
1510
1511
    /* sub mb modes */
1512
7.09M
    UWORD8 *pu1_top_mb_intra_modes =
1513
7.09M
        (ps_proc->s_nbr_info_base.ps_layer_nbr_info[ps_proc->u1_spatial_layer_id]
1514
7.09M
             .ps_top_mb_intra_modes +
1515
7.09M
         i4_mb_x + i4_mb_y * ps_proc->i4_wd_mbs)
1516
7.09M
            ->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
7.09M
    ps_left_syn[0] = ps_top_syn[0] = ps_proc->ps_mb_info[0];
1529
7.09M
    ps_left_syn->u2_mb_type = ps_top_syn->u2_mb_type = u4_mb_type;
1530
7.09M
    ps_left_syn->i4_mb_distortion = ps_top_syn->i4_mb_distortion = ps_proc->i4_mb_distortion;
1531
1532
7.09M
    if(u4_is_intra)
1533
6.39M
    {
1534
        /* mb / sub mb modes */
1535
6.39M
        if(I16x16 == u4_mb_type)
1536
4.00M
        {
1537
4.00M
            pu1_top_mb_intra_modes[0] =
1538
4.00M
                ps_proc->s_nbr_info.ps_left_mb_intra_modes->au1_intra_modes[0] =
1539
4.00M
                    ps_proc->u1_l_i16_mode;
1540
4.00M
        }
1541
2.39M
        else if(I4x4 == u4_mb_type)
1542
443k
        {
1543
443k
            ps_mem_fxns->pf_mem_cpy_mul8(
1544
443k
                ps_proc->s_nbr_info.ps_left_mb_intra_modes->au1_intra_modes,
1545
443k
                ps_proc->au1_intra_luma_mb_4x4_modes, 16);
1546
443k
            ps_mem_fxns->pf_mem_cpy_mul8(pu1_top_mb_intra_modes,
1547
443k
                                         ps_proc->au1_intra_luma_mb_4x4_modes, 16);
1548
443k
        }
1549
1.94M
        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
6.39M
        *ps_proc->pu4_mb_pu_cnt = 1;
1557
6.39M
    }
1558
1559
    /*
1560
     * Mark that the MB has been coded intra
1561
     * So that future AIRs can skip it
1562
     */
1563
7.09M
    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
7.09M
    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
7.09M
    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
7.09M
    if(i4_mb_x == i4_wd_mbs - 1)
1584
257k
    {
1585
        /* job structures */
1586
257k
        job_t s_job;
1587
1588
        /* job class */
1589
257k
        s_job.i4_cmd = CMD_ENTROPY;
1590
1591
        /* number of mbs to be processed in the current job */
1592
257k
        s_job.i2_mb_cnt = ps_proc->i4_wd_mbs;
1593
1594
        /* job start index x */
1595
257k
        s_job.i2_mb_x = 0;
1596
1597
        /* job start index y */
1598
257k
        s_job.i2_mb_y = ps_proc->i4_mb_y;
1599
1600
        /* queue the job */
1601
257k
        error_status = ih264_list_queue(ps_proc->pv_entropy_jobq, &s_job, 1);
1602
1603
257k
        if(error_status != IH264_SUCCESS)
1604
0
        {
1605
0
            return error_status;
1606
0
        }
1607
1608
257k
        if(ps_proc->i4_mb_y == (i4_ht_mbs - 1))
1609
50.2k
        {
1610
50.2k
            ih264_list_terminate(ps_codec->pv_entropy_jobq);
1611
50.2k
        }
1612
257k
    }
1613
1614
    /* update proc map */
1615
7.09M
    pu1_proc_map[i4_mb_x] = 1;
1616
7.09M
    ASSERT(i4_mb_x < i4_wd_mbs);
1617
1618
    /**************************************************/
1619
    /* update proc ctxt elements for encoding next mb */
1620
    /**************************************************/
1621
    /* update indices */
1622
7.09M
    i4_mb_x++;
1623
7.07M
    ps_proc->i4_mb_x = i4_mb_x;
1624
1625
7.07M
    if(ps_proc->i4_mb_x == i4_wd_mbs)
1626
257k
    {
1627
257k
        ps_proc->i4_mb_y++;
1628
257k
        ps_proc->i4_mb_x = 0;
1629
257k
    }
1630
1631
    /* update slice index */
1632
7.07M
    ps_proc->i4_cur_slice_idx =
1633
7.07M
        ps_proc->pu1_slice_idx[ps_proc->i4_mb_y * i4_wd_mbs + ps_proc->i4_mb_x];
1634
1635
    /* update buffers pointers */
1636
7.07M
    ps_proc->s_src_buf_props.as_component_bufs[0].pv_data =
1637
7.07M
        ((UWORD8 *) ps_proc->s_src_buf_props.as_component_bufs[0].pv_data) + MB_SIZE;
1638
7.07M
    ps_proc->s_rec_buf_props.as_component_bufs[0].pv_data =
1639
7.07M
        ((UWORD8 *) ps_proc->s_rec_buf_props.as_component_bufs[0].pv_data) + MB_SIZE;
1640
7.07M
    ps_proc->as_ref_buf_props[0].as_component_bufs[0].pv_data =
1641
7.07M
        ((UWORD8 *) ps_proc->as_ref_buf_props[0].as_component_bufs[0].pv_data) + MB_SIZE;
1642
7.07M
    ps_proc->as_ref_buf_props[1].as_component_bufs[0].pv_data =
1643
7.07M
        ((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
7.07M
    ps_proc->s_src_buf_props.as_component_bufs[1].pv_data =
1650
7.07M
        ((UWORD8 *) ps_proc->s_src_buf_props.as_component_bufs[1].pv_data) + MB_SIZE;
1651
7.07M
    ps_proc->s_rec_buf_props.as_component_bufs[1].pv_data =
1652
7.07M
        ((UWORD8 *) ps_proc->s_rec_buf_props.as_component_bufs[1].pv_data) + MB_SIZE;
1653
7.07M
    ps_proc->as_ref_buf_props[0].as_component_bufs[1].pv_data =
1654
7.07M
        ((UWORD8 *) ps_proc->as_ref_buf_props[0].as_component_bufs[1].pv_data) + MB_SIZE;
1655
7.07M
    ps_proc->as_ref_buf_props[1].as_component_bufs[1].pv_data =
1656
7.07M
        ((UWORD8 *) ps_proc->as_ref_buf_props[1].as_component_bufs[1].pv_data) + MB_SIZE;
1657
1658
    /* Reset cost, distortion params */
1659
7.07M
    ps_proc->i4_mb_cost = INT_MAX;
1660
7.07M
    ps_proc->i4_mb_distortion = SHRT_MAX;
1661
1662
7.07M
    ps_proc->ps_mb_info++;
1663
7.07M
    ps_proc->pu4_mb_pu_cnt++;
1664
1665
    /* Update colocated pu */
1666
7.07M
    if(ps_proc->i4_slice_type == BSLICE)
1667
0
    {
1668
0
        ps_proc->ps_col_mb++;
1669
0
    }
1670
1671
7.07M
    if(ps_proc->u4_disable_deblock_level != 1)
1672
5.43M
    {
1673
5.43M
        ps_bs->i4_mb_x = ps_proc->i4_mb_x;
1674
5.43M
        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
5.43M
    }
1689
1690
7.07M
    return error_status;
1691
7.09M
}
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
7.08M
{
1814
7.08M
    WORD32 i;
1815
7.08M
    WORD32 row, col;
1816
1817
7.08M
    n_mb_process_ctxt_t *ps_n_mb_ctxt = &ps_proc->s_n_mb_ctxt;
1818
7.08M
    isvce_deblk_ctxt_t *ps_deblk = &ps_proc->s_deblk_ctxt;
1819
1820
7.08M
    UWORD8 *pu1_deblk_map = ps_proc->pu1_deblk_map + ps_deblk->i4_mb_y * ps_proc->i4_wd_mbs;
1821
7.08M
    UWORD8 *pu1_deblk_map_prev_row = pu1_deblk_map - ps_proc->i4_wd_mbs;
1822
7.08M
    WORD32 u4_deblk_prev_row = 0;
1823
7.08M
    WORD32 i4_n_mbs = ps_n_mb_ctxt->i4_n_mbs;
1824
7.08M
    WORD32 i4_n_mb_process_count = 0;
1825
7.08M
    WORD32 i4_mb_x = ps_proc->i4_mb_x;
1826
7.08M
    WORD32 i4_mb_y = ps_proc->i4_mb_y;
1827
1828
7.08M
    ASSERT(i4_n_mbs == ps_proc->i4_wd_mbs);
1829
1830
7.08M
    if(ps_proc->u4_disable_deblock_level != 1)
1831
5.44M
    {
1832
5.44M
        if((i4_mb_y > 0) || (i4_mb_y == (ps_proc->i4_ht_mbs - 1)))
1833
5.17M
        {
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
5.17M
            if(((i4_mb_x - (ps_n_mb_ctxt->i4_mb_x - 1)) < i4_n_mbs) &&
1837
5.01M
               (i4_mb_x < (ps_proc->i4_wd_mbs - 1)))
1838
5.01M
            {
1839
5.01M
                return IH264E_SUCCESS;
1840
5.01M
            }
1841
165k
            else
1842
165k
            {
1843
165k
                WORD32 i4_num_deblk_rows = 1;
1844
1845
165k
                if(i4_mb_y == (ps_proc->i4_ht_mbs - 1))
1846
33.2k
                {
1847
33.2k
                    i4_num_deblk_rows += (ps_proc->i4_ht_mbs > 1);
1848
33.2k
                }
1849
1850
165k
                if(1 == ps_proc->i4_ht_mbs)
1851
10.0k
                {
1852
10.0k
                    ps_deblk->i4_mb_y = 0;
1853
10.0k
                    pu1_deblk_map_prev_row = pu1_deblk_map;
1854
10.0k
                }
1855
1856
354k
                for(i = 0; i < i4_num_deblk_rows; i++)
1857
189k
                {
1858
189k
                    if(i == 1)
1859
23.2k
                    {
1860
                        /* Deblock last row */
1861
23.2k
                        ps_n_mb_ctxt->i4_mb_x = 0;
1862
23.2k
                        ps_n_mb_ctxt->i4_mb_y = ps_proc->i4_mb_y;
1863
23.2k
                        ps_deblk->i4_mb_x = 0;
1864
23.2k
                        ps_deblk->i4_mb_y = ps_proc->i4_mb_y;
1865
23.2k
                        pu1_deblk_map_prev_row = pu1_deblk_map;
1866
23.2k
                        pu1_deblk_map += ps_proc->i4_wd_mbs;
1867
23.2k
                    }
1868
1869
189k
                    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
189k
                    u4_deblk_prev_row = 1;
1873
1874
                    /* checking whether the top rows are deblocked */
1875
5.64M
                    for(col = 0; col < i4_n_mb_process_count; col++)
1876
5.46M
                    {
1877
5.46M
                        u4_deblk_prev_row &= pu1_deblk_map_prev_row[ps_deblk->i4_mb_x + col];
1878
5.46M
                    }
1879
1880
                    /* checking whether the top right MB is deblocked */
1881
189k
                    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
189k
                    if((u4_deblk_prev_row != 1) && (i4_mb_y > 0))
1889
0
                    {
1890
0
                        return IH264E_SUCCESS;
1891
0
                    }
1892
1893
5.64M
                    for(row = 0; row < i4_n_mb_process_count; row++)
1894
5.46M
                    {
1895
5.46M
                        isvce_deblock_mb(ps_proc, ps_deblk, u1_inter_layer_deblk_flag);
1896
1897
5.46M
                        pu1_deblk_map[ps_deblk->i4_mb_x] = 1;
1898
1899
5.46M
                        ps_deblk->i4_mb_x++;
1900
5.46M
                    }
1901
189k
                }
1902
165k
            }
1903
5.17M
        }
1904
5.44M
    }
1905
1906
2.07M
    return IH264E_SUCCESS;
1907
7.08M
}
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
257k
{
1973
257k
    UWORD32 u4_cbp_l, u4_cbp_c;
1974
257k
    WORD32 i4_mb_idx;
1975
257k
    WORD32 luma_idx, chroma_idx, is_intra;
1976
1977
257k
    isvce_codec_t *ps_codec = ps_proc->ps_codec;
1978
257k
    isa_dependent_fxns_t *ps_isa_dependent_fxns = &ps_codec->s_isa_dependent_fxns;
1979
257k
    enc_loop_fxns_t *ps_enc_loop_fxns = &ps_isa_dependent_fxns->s_enc_loop_fxns;
1980
1981
257k
    WORD32 error_status = IH264_SUCCESS;
1982
257k
    WORD32 i4_wd_mbs = ps_proc->i4_wd_mbs;
1983
257k
    WORD32 i4_mb_cnt = ps_proc->i4_mb_cnt;
1984
257k
    UWORD32 u4_valid_modes = 0;
1985
257k
    WORD32 i4_gate_threshold = 0;
1986
257k
    WORD32 ctxt_sel = ps_proc->i4_encode_api_call_cnt % MAX_CTXT_SETS;
1987
257k
    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
257k
    if(ps_proc->i4_slice_type == ISLICE)
2000
152k
    {
2001
18.4E
        u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_16x16 ? (1 << I16x16) : 0;
2002
2003
        /* enable intra 8x8 */
2004
152k
        u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_8x8 ? (1 << I8x8) : 0;
2005
2006
        /* enable intra 4x4 */
2007
152k
        u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_4x4 ? (1 << I4x4) : 0;
2008
152k
        u4_valid_modes |= (ps_proc->u1_frame_qp <= 10) << I4x4;
2009
152k
    }
2010
104k
    else if(ps_proc->i4_slice_type == PSLICE)
2011
104k
    {
2012
104k
        u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_16x16 ? (1 << I16x16) : 0;
2013
2014
        /* enable intra 4x4 */
2015
104k
        if(ps_codec->s_cfg.u4_enc_speed_preset == IVE_SLOWEST)
2016
13.7k
        {
2017
13.7k
            u4_valid_modes |= ps_codec->s_cfg.u4_enable_intra_4x4 ? (1 << I4x4) : 0;
2018
13.7k
        }
2019
104k
        u4_valid_modes |= (ps_proc->u1_frame_qp <= 10) << I4x4;
2020
2021
        /* enable inter P16x16 */
2022
104k
        u4_valid_modes |= (1 << P16x16);
2023
104k
    }
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
257k
    ps_proc->s_entropy.i4_mb_x = ps_proc->i4_mb_x;
2040
257k
    ps_proc->s_entropy.i4_mb_y = ps_proc->i4_mb_y;
2041
257k
    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
257k
    ps_proc->u4_compute_recon = ((ps_proc->s_svc_params.u1_num_spatial_layers > 1) &&
2048
226k
                                 (ENABLE_RESIDUAL_PREDICTION || ENABLE_IBL_MODE)) ||
2049
30.2k
                                ps_codec->u4_is_curr_frm_ref || ps_codec->s_cfg.u4_enable_recon;
2050
2051
7.31M
    for(i4_mb_idx = 0; i4_mb_idx < i4_mb_cnt; i4_mb_idx++)
2052
7.09M
    {
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
7.09M
        ps_proc->u4_min_sad = ps_codec->s_cfg.i4_min_sad;
2057
7.09M
        ps_proc->u4_min_sad_reached = 0;
2058
2059
7.09M
        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
7.09M
        if(ps_proc->i4_mb_y > 0)
2064
6.53M
        {
2065
6.53M
            UWORD8 *pu1_proc_map_top;
2066
2067
6.53M
            pu1_proc_map_top = ps_proc->pu1_proc_map + ((ps_proc->i4_mb_y - 1) * i4_wd_mbs);
2068
2069
23.6M
            while(1)
2070
23.6M
            {
2071
23.6M
                volatile UWORD8 *pu1_buf;
2072
23.6M
                WORD32 idx = MIN(i4_mb_cnt - 1, i4_mb_idx + 1);
2073
2074
23.6M
                idx = MIN(idx, ((WORD32) ps_codec->s_cfg.i4_wd_mbs - 1));
2075
23.6M
                pu1_buf = pu1_proc_map_top + idx;
2076
23.6M
                if(*pu1_buf) break;
2077
17.1M
                ithread_yield();
2078
17.1M
            }
2079
6.53M
        }
2080
2081
7.09M
        if(ENABLE_ILP_MV && (ps_proc->u1_spatial_layer_id > 0) &&
2082
5.31M
           (ps_proc->i4_slice_type != ISLICE))
2083
728k
        {
2084
728k
            svc_ilp_mv_ctxt_t *ps_svc_ilp_mv_ctxt = ps_proc->ps_svc_ilp_mv_ctxt;
2085
728k
            coordinates_t s_mb_pos = {ps_proc->i4_mb_x, ps_proc->i4_mb_y};
2086
2087
728k
            ps_svc_ilp_mv_ctxt->s_ilp_mv_variables.ps_svc_ilp_data = &ps_codec->s_svc_ilp_data;
2088
728k
            ps_svc_ilp_mv_ctxt->s_ilp_mv_variables.s_mb_pos = s_mb_pos;
2089
728k
            ps_svc_ilp_mv_ctxt->s_ilp_mv_variables.u1_spatial_layer_id =
2090
728k
                ps_proc->u1_spatial_layer_id;
2091
2092
728k
            isvce_get_mb_ilp_mv(ps_svc_ilp_mv_ctxt);
2093
2094
728k
            ps_proc->ps_ilp_mv = &ps_svc_ilp_mv_ctxt->s_ilp_mv_outputs.s_ilp_mv;
2095
728k
            ps_proc->s_me_ctxt.ps_ilp_me_cands =
2096
728k
                &ps_svc_ilp_mv_ctxt->s_ilp_mv_outputs.s_ilp_me_cands;
2097
728k
        }
2098
6.36M
        else
2099
6.36M
        {
2100
6.36M
            ps_proc->ps_ilp_mv = NULL;
2101
6.36M
            ps_proc->s_me_ctxt.ps_ilp_me_cands = NULL;
2102
6.36M
        }
2103
2104
7.09M
        ps_proc->ps_mb_info->u2_mb_type = INVALID_MB_TYPE;
2105
7.09M
        ps_proc->i4_mb_distortion = SHRT_MAX;
2106
2107
7.09M
        {
2108
7.09M
            WORD32 i4_mb_id = ps_proc->i4_mb_x + ps_proc->i4_mb_y * i4_wd_mbs;
2109
2110
7.09M
            WORD32 i4_air_enable_inter =
2111
7.09M
                (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
7.09M
            if((u4_valid_modes & (1 << P16x16)) || (u4_valid_modes & (1 << B16x16)))
2115
974k
            {
2116
974k
                if(ps_proc->i4_mb_x % ps_proc->u4_nmb_me == 0)
2117
974k
                {
2118
974k
                    isvce_compute_me_nmb(
2119
974k
                        ps_proc, MIN((WORD32) ps_proc->u4_nmb_me, i4_wd_mbs - ps_proc->i4_mb_x));
2120
974k
                }
2121
2122
974k
                {
2123
974k
                    UWORD32 u4_mb_index = ps_proc->i4_mb_x % ps_proc->u4_nmb_me;
2124
2125
974k
                    ps_proc->u4_min_sad_reached =
2126
974k
                        ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad_reached;
2127
974k
                    ps_proc->u4_min_sad = ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad;
2128
2129
974k
                    ps_proc->ps_skip_mv = &(ps_proc->ps_nmb_info[u4_mb_index].as_skip_mv[0]);
2130
974k
                    ps_proc->ps_ngbr_avbl = &(ps_proc->ps_nmb_info[u4_mb_index].s_ngbr_avbl);
2131
974k
                    ps_proc->ps_pred_mv = &(ps_proc->ps_nmb_info[u4_mb_index].as_pred_mv[0]);
2132
2133
974k
                    ps_proc->i4_mb_distortion = ps_proc->ps_nmb_info[u4_mb_index].i4_mb_distortion;
2134
2135
974k
                    ps_proc->i4_mb_cost = ps_proc->ps_nmb_info[u4_mb_index].i4_mb_cost;
2136
974k
                    ps_proc->u4_min_sad = ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad;
2137
974k
                    ps_proc->u4_min_sad_reached =
2138
974k
                        ps_proc->ps_nmb_info[u4_mb_index].u4_min_sad_reached;
2139
974k
                    ps_proc->ps_mb_info->u2_mb_type = ps_proc->ps_nmb_info[u4_mb_index].u4_mb_type;
2140
2141
974k
                    ps_proc->pu1_best_subpel_buf =
2142
974k
                        ps_proc->ps_nmb_info[u4_mb_index].pu1_best_sub_pel_buf;
2143
974k
                    ps_proc->u4_bst_spel_buf_strd =
2144
974k
                        ps_proc->ps_nmb_info[u4_mb_index].u4_bst_spel_buf_strd;
2145
974k
                }
2146
2147
974k
                isvce_derive_nghbr_avbl_of_mbs(ps_proc);
2148
974k
            }
2149
6.11M
            else
2150
6.11M
            {
2151
6.11M
                ps_proc->ps_ngbr_avbl = &ps_proc->s_ngbr_avbl;
2152
2153
6.11M
                isvce_derive_nghbr_avbl_of_mbs(ps_proc);
2154
6.11M
            }
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
7.09M
            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
7.09M
            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
7.09M
            if((ps_proc->u4_min_sad_reached == 0) ||
2176
303k
               (ps_codec->s_cfg.u4_enc_speed_preset != IVE_FASTEST))
2177
7.07M
            {
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
7.07M
                if((ps_proc->i4_slice_type != ISLICE) &&
2182
967k
                   (FORCE_DISTORTION_BASED_INTRA_4X4_GATING ||
2183
0
                    (i4_air_enable_inter && ps_codec->u4_inter_gate)))
2184
967k
                {
2185
967k
                    WORD32 i4_distortion[4];
2186
2187
967k
                    if((ps_proc->i4_mb_x > 0) && (ps_proc->i4_mb_y > 0))
2188
569k
                    {
2189
569k
                        i4_distortion[0] = ps_proc->s_nbr_info.ps_left_mb_info->i4_mb_distortion;
2190
2191
569k
                        i4_distortion[1] = ps_proc->s_nbr_info.ps_top_row_mb_info[ps_proc->i4_mb_x]
2192
569k
                                               .i4_mb_distortion;
2193
2194
569k
                        i4_distortion[2] =
2195
569k
                            ps_proc->s_nbr_info.ps_top_row_mb_info[ps_proc->i4_mb_x + 1]
2196
569k
                                .i4_mb_distortion;
2197
2198
569k
                        i4_distortion[3] =
2199
569k
                            ps_proc->s_nbr_info.ps_top_row_mb_info[ps_proc->i4_mb_x - 1]
2200
569k
                                .i4_mb_distortion;
2201
2202
569k
                        i4_gate_threshold = (i4_distortion[0] + i4_distortion[1] +
2203
569k
                                             i4_distortion[2] + i4_distortion[3]) /
2204
569k
                                            4;
2205
569k
                    }
2206
967k
                }
2207
2208
7.07M
                b_enable_intra4x4_eval = true;
2209
2210
7.07M
                if(ENABLE_IBL_MODE && (ps_proc->u1_spatial_layer_id > 0) &&
2211
5.30M
                   (ps_proc->s_svc_params.d_spatial_res_ratio == 2.) && !ps_proc->ps_ilp_mv)
2212
3.63M
                {
2213
3.63M
                    isvce_evaluate_IBL_mode(ps_proc);
2214
3.63M
                }
2215
3.43M
                else
2216
3.43M
                {
2217
3.43M
                    ps_proc->ps_mb_info->u1_base_mode_flag = 0;
2218
3.43M
                }
2219
2220
7.07M
                if(u4_valid_modes & (1 << I16x16))
2221
7.06M
                {
2222
7.06M
                    isvce_evaluate_intra16x16_modes_for_least_cost_rdoptoff(ps_proc);
2223
2224
7.06M
                    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
7.06M
                }
2231
2232
7.07M
                if(u4_valid_modes & (1 << I8x8))
2233
0
                {
2234
0
                    isvce_evaluate_intra8x8_modes_for_least_cost_rdoptoff(ps_proc);
2235
0
                }
2236
2237
7.07M
                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
7.07M
                if((!i4_air_enable_inter) ||
2246
7.08M
                   ((i4_gate_threshold + 16 * ((WORD32) ps_proc->u4_lambda)) <
2247
7.08M
                    ps_proc->i4_mb_distortion))
2248
2.00M
                {
2249
2.00M
                    if(b_enable_intra4x4_eval && (u4_valid_modes & (1 << I4x4)))
2250
705k
                    {
2251
705k
                        if(!FORCE_FAST_INTRA4X4 &&
2252
705k
                           (ps_codec->s_cfg.u4_enc_speed_preset == IVE_SLOWEST))
2253
242k
                        {
2254
242k
                            isvce_evaluate_intra4x4_modes_for_least_cost_rdopton(ps_proc);
2255
242k
                        }
2256
463k
                        else
2257
463k
                        {
2258
463k
                            isvce_evaluate_intra4x4_modes_for_least_cost_rdoptoff(ps_proc);
2259
463k
                        }
2260
705k
                    }
2261
2.00M
                }
2262
7.07M
            }
2263
7.09M
        }
2264
2265
7.09M
        if(ps_proc->ps_mb_info->u2_mb_type == I4x4 || ps_proc->ps_mb_info->u2_mb_type == I16x16 ||
2266
2.61M
           ps_proc->ps_mb_info->u2_mb_type == I8x8)
2267
4.47M
        {
2268
4.47M
            luma_idx = ps_proc->ps_mb_info->u2_mb_type;
2269
4.47M
            chroma_idx = 0;
2270
4.47M
            is_intra = 1;
2271
2272
4.47M
            isvce_evaluate_chroma_intra8x8_modes_for_least_cost_rdoptoff(ps_proc);
2273
4.47M
        }
2274
2.61M
        else if(ps_proc->ps_mb_info->u2_mb_type == BASE_MODE)
2275
1.97M
        {
2276
1.97M
            luma_idx = 3;
2277
1.97M
            chroma_idx = 1;
2278
1.97M
            is_intra = 1;
2279
1.97M
            ps_proc->u4_min_sad_reached = 0;
2280
1.97M
        }
2281
644k
        else
2282
644k
        {
2283
644k
            luma_idx = 3;
2284
644k
            chroma_idx = 1;
2285
644k
            is_intra = 0;
2286
644k
        }
2287
2288
7.09M
        ps_proc->ps_mb_info->u1_is_intra = is_intra;
2289
2290
7.09M
        if(is_intra)
2291
6.45M
        {
2292
6.45M
            ps_proc->ps_mb_info->as_pu->as_me_info[L0].i1_ref_idx = -1;
2293
6.45M
            ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvx = 0;
2294
6.45M
            ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvy = 0;
2295
2296
6.45M
            ps_proc->ps_mb_info->as_pu->as_me_info[L1].i1_ref_idx = -1;
2297
6.45M
            ps_proc->ps_mb_info->as_pu->as_me_info[L1].s_mv.i2_mvx = 0;
2298
6.45M
            ps_proc->ps_mb_info->as_pu->as_me_info[L1].s_mv.i2_mvy = 0;
2299
6.45M
        }
2300
639k
        else
2301
639k
        {
2302
639k
            isvce_mv_pred(ps_proc, ps_proc->i4_slice_type);
2303
639k
        }
2304
2305
7.09M
        if(ENABLE_RESIDUAL_PREDICTION && !is_intra && (ps_proc->u1_spatial_layer_id > 0) &&
2306
431k
           (ps_proc->i4_slice_type == PSLICE) && (ps_proc->ps_mb_info->u2_mb_type != PSKIP))
2307
431k
        {
2308
431k
            svc_res_pred_ctxt_t *ps_res_pred_ctxt = ps_proc->ps_res_pred_ctxt;
2309
2310
431k
            UWORD32 u4_res_pred_sad;
2311
2312
431k
            isvce_me_ctxt_t *ps_me_ctxt = &ps_proc->s_me_ctxt;
2313
431k
            yuv_buf_props_t s_pred = ps_proc->s_src_buf_props;
2314
2315
431k
            if(!(ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvx % 4) &&
2316
403k
               !(ps_proc->ps_mb_info->as_pu->as_me_info[L0].s_mv.i2_mvy % 4))
2317
385k
            {
2318
385k
                s_pred.as_component_bufs[Y].pv_data =
2319
385k
                    ps_me_ctxt->apu1_ref_buf_luma[L0] +
2320
385k
                    (ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvx >> 2) +
2321
385k
                    (ps_me_ctxt->as_mb_part[L0].s_mv_curr.i2_mvy >> 2) *
2322
385k
                        ps_me_ctxt->ai4_rec_strd[L0];
2323
385k
                s_pred.as_component_bufs[Y].i4_data_stride = ps_me_ctxt->ai4_rec_strd[L0];
2324
385k
            }
2325
45.7k
            else
2326
45.7k
            {
2327
45.7k
                s_pred.as_component_bufs[Y].pv_data = ps_proc->pu1_best_subpel_buf;
2328
45.7k
                s_pred.as_component_bufs[Y].i4_data_stride = ps_proc->u4_bst_spel_buf_strd;
2329
45.7k
            }
2330
2331
431k
            s_pred.as_component_bufs[U].pv_data = s_pred.as_component_bufs[V].pv_data = NULL;
2332
2333
431k
            ps_res_pred_ctxt->s_res_pred_variables.ps_svc_ilp_data = &ps_codec->s_svc_ilp_data;
2334
431k
            ps_res_pred_ctxt->s_res_pred_variables.s_mb_pos.i4_abscissa = ps_proc->i4_mb_x;
2335
431k
            ps_res_pred_ctxt->s_res_pred_variables.s_mb_pos.i4_ordinate = ps_proc->i4_mb_y;
2336
431k
            ps_res_pred_ctxt->s_res_pred_variables.u1_spatial_layer_id =
2337
431k
                ps_proc->u1_spatial_layer_id;
2338
2339
431k
            if(ps_proc->s_svc_params.d_spatial_res_ratio == 2.)
2340
129k
            {
2341
129k
                isvce_get_mb_residual_pred(ps_proc->ps_res_pred_ctxt);
2342
129k
            }
2343
301k
            else
2344
301k
            {
2345
301k
                isvce_get_mb_residual_pred_non_dyadic(ps_proc->ps_res_pred_ctxt);
2346
301k
            }
2347
2348
431k
            isvce_residual_pred_eval(ps_proc->ps_res_pred_ctxt, &ps_proc->s_src_buf_props, &s_pred,
2349
431k
                                     ps_proc->ps_mb_res_buf, &u4_res_pred_sad,
2350
431k
                                     &ps_proc->ps_mb_info->u1_residual_prediction_flag,
2351
431k
                                     ps_proc->i4_mb_distortion);
2352
2353
431k
            if(ps_proc->ps_mb_info->u1_residual_prediction_flag)
2354
44.9k
            {
2355
44.9k
                ps_proc->i4_mb_cost -= ps_proc->i4_mb_distortion;
2356
44.9k
                ps_proc->i4_mb_cost += (WORD32) u4_res_pred_sad;
2357
44.9k
                ps_proc->i4_mb_distortion = (WORD32) u4_res_pred_sad;
2358
44.9k
            }
2359
431k
        }
2360
6.65M
        else
2361
6.65M
        {
2362
6.65M
            ps_proc->ps_mb_info->u1_residual_prediction_flag = 0;
2363
6.65M
        }
2364
2365
7.09M
        if(isvce_is_ilp_mv_winning_mv(ps_proc->ps_mb_info, ps_proc->ps_ilp_mv))
2366
42.7k
        {
2367
42.7k
            ps_proc->ps_mb_info->as_pu->as_me_info[L0] = ps_proc->ps_ilp_mv->as_mv[0][L0];
2368
42.7k
            ps_proc->ps_mb_info->as_pu->as_me_info[L1] = ps_proc->ps_ilp_mv->as_mv[0][L1];
2369
2370
42.7k
            ps_proc->ps_mb_info->u1_base_mode_flag = 1;
2371
42.7k
            ps_proc->ps_mb_info->u2_mb_type = BASE_MODE;
2372
42.7k
        }
2373
7.04M
        else if(ps_proc->ps_mb_info->u2_mb_type != BASE_MODE)
2374
5.07M
        {
2375
5.07M
            ps_proc->ps_mb_info->u1_base_mode_flag = 0;
2376
5.07M
        }
2377
2378
7.09M
        isvce_mvp_idx_eval(ps_proc->ps_mb_info, ps_proc->ps_pred_mv,
2379
7.09M
                           ps_proc->ps_ilp_mv ? ps_proc->ps_ilp_mv->as_mv[0] : NULL,
2380
7.09M
                           ps_proc->s_me_ctxt.pu1_mv_bits);
2381
2382
        /* 8x8 Tx is not supported, and I8x8 is also unsupported */
2383
7.09M
        ASSERT((luma_idx == 0) || (luma_idx == 1) || (luma_idx == 3));
2384
7.09M
        ps_proc->ps_mb_info->u1_tx_size = 4;
2385
2386
        /* Perform luma mb core coding */
2387
7.08M
        u4_cbp_l = (ps_enc_loop_fxns->apf_luma_energy_compaction)[luma_idx](ps_proc);
2388
2389
        /* Perform chroma mb core coding */
2390
7.08M
        u4_cbp_c = (ps_enc_loop_fxns->apf_chroma_energy_compaction)[chroma_idx](ps_proc);
2391
2392
7.08M
        ps_proc->u4_cbp = (u4_cbp_c << 4) | u4_cbp_l;
2393
7.08M
        ps_proc->ps_mb_info->u4_cbp = (u4_cbp_c << 4) | u4_cbp_l;
2394
7.08M
        ps_proc->ps_mb_info->u4_csbp = isvce_calculate_csbp(ps_proc);
2395
2396
7.08M
        if(ps_proc->ps_mb_info->u1_is_intra)
2397
6.44M
        {
2398
6.44M
            switch(ps_proc->ps_mb_info->u2_mb_type)
2399
6.44M
            {
2400
4.02M
                case I16x16:
2401
4.02M
                {
2402
4.02M
                    ps_proc->ps_mb_info->s_intra_pu.s_i16x16_mode_data.u1_mode =
2403
4.02M
                        ps_proc->u1_l_i16_mode;
2404
2405
4.02M
                    break;
2406
0
                }
2407
446k
                case I4x4:
2408
446k
                {
2409
446k
                    WORD32 i;
2410
2411
7.56M
                    for(i = 0; i < MAX_TU_IN_MB; i++)
2412
7.12M
                    {
2413
7.12M
                        ps_proc->ps_mb_info->s_intra_pu.as_i4x4_mode_data[i].u1_mode =
2414
7.12M
                            ps_proc->au1_intra_luma_mb_4x4_modes[i];
2415
7.12M
                        ps_proc->ps_mb_info->s_intra_pu.as_i4x4_mode_data[i].u1_predicted_mode =
2416
7.12M
                            ps_proc->au1_predicted_intra_luma_mb_4x4_modes[i];
2417
7.12M
                    }
2418
2419
446k
                    break;
2420
0
                }
2421
1.96M
                case BASE_MODE:
2422
1.96M
                {
2423
1.96M
                    break;
2424
0
                }
2425
0
                default:
2426
0
                {
2427
0
                    ASSERT(false);
2428
0
                }
2429
6.44M
            }
2430
2431
6.44M
            ps_proc->ps_mb_info->s_intra_pu.u1_chroma_intra_mode = ps_proc->u1_c_i8_mode;
2432
6.44M
        }
2433
2434
7.07M
        if(!ps_proc->ps_mb_info->u1_is_intra && !ps_proc->ps_mb_info->u1_residual_prediction_flag)
2435
599k
        {
2436
599k
            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
599k
            else if(!ps_proc->u4_cbp)
2444
256k
            {
2445
256k
                if(isvce_find_pskip_params(ps_proc, L0))
2446
231k
                {
2447
231k
                    ps_proc->ps_mb_info->u2_mb_type = PSKIP;
2448
231k
                }
2449
256k
            }
2450
599k
        }
2451
2452
7.08M
    UPDATE_MB_INFO:
2453
7.08M
        isvce_svc_ilp_buf_update(ps_proc);
2454
2455
7.08M
        isvce_update_ibl_info(
2456
7.08M
            ps_proc->ps_intra_pred_ctxt, ps_proc->s_svc_params.u1_num_spatial_layers,
2457
7.08M
            ps_proc->u1_spatial_layer_id, ps_proc->ps_mb_info->u2_mb_type, ps_proc->i4_mb_x,
2458
7.08M
            ps_proc->i4_mb_y, ps_proc->ps_mb_info->u1_base_mode_flag);
2459
2460
7.08M
        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
7.08M
        isvce_update_rc_mb_info(&ps_proc->s_frame_info, ps_proc);
2464
2465
7.08M
        {
2466
7.08M
            svc_sub_pic_rc_ctxt_t *ps_sub_pic_rc_ctxt = ps_proc->ps_sub_pic_rc_ctxt;
2467
7.08M
            svc_sub_pic_rc_mb_variables_t *ps_sub_pic_rc_variables =
2468
7.08M
                &ps_sub_pic_rc_ctxt->s_sub_pic_rc_variables.s_mb_variables;
2469
2470
7.08M
            ps_sub_pic_rc_variables->ps_mb_info = ps_proc->ps_mb_info;
2471
7.08M
            ps_sub_pic_rc_variables->s_mb_pos.i4_abscissa = ps_proc->i4_mb_x;
2472
7.08M
            ps_sub_pic_rc_variables->s_mb_pos.i4_ordinate = ps_proc->i4_mb_y;
2473
7.08M
            ps_sub_pic_rc_variables->u4_cbp = ps_proc->u4_cbp;
2474
7.08M
            ps_sub_pic_rc_variables->aps_mvps[0] = ps_proc->ps_pred_mv;
2475
7.08M
#if MAX_MVP_IDX == 1
2476
7.08M
            ps_sub_pic_rc_variables->aps_mvps[1] =
2477
7.08M
                ps_proc->ps_ilp_mv ? ps_proc->ps_ilp_mv->as_mv[0] : NULL;
2478
7.08M
#endif
2479
7.08M
            ps_sub_pic_rc_variables->apu1_nnzs[Y] = (UWORD8 *) ps_proc->au4_nnz;
2480
7.08M
            ps_sub_pic_rc_variables->apu1_nnzs[UV] = ps_proc->au1_chroma_nnz;
2481
2482
            /* Quant coeffs are arranged TU by TU */
2483
7.08M
            switch(ps_proc->ps_mb_info->u2_mb_type)
2484
7.08M
            {
2485
4.01M
                case I16x16:
2486
4.45M
                case I4x4:
2487
4.83M
                case P16x16:
2488
4.83M
                case B16x16:
2489
6.83M
                case BASE_MODE:
2490
6.83M
                {
2491
6.83M
                    ps_sub_pic_rc_variables->as_quant_coeffs[Y].pv_data =
2492
6.83M
                        ps_proc->pi2_res_buf_intra_4x4;
2493
6.83M
                    ps_sub_pic_rc_variables->as_quant_coeffs[Y].i4_data_stride =
2494
6.83M
                        ps_proc->i4_res_strd;
2495
6.83M
                    ps_sub_pic_rc_variables->as_quant_coeffs[UV].pv_data = ps_proc->pi2_res_buf;
2496
6.83M
                    ps_sub_pic_rc_variables->as_quant_coeffs[UV].i4_data_stride =
2497
6.83M
                        ps_proc->i4_res_strd;
2498
2499
6.83M
                    break;
2500
4.83M
                }
2501
231k
                case PSKIP:
2502
231k
                case BSKIP:
2503
231k
                {
2504
231k
                    ps_sub_pic_rc_variables->as_quant_coeffs[Y].pv_data = NULL;
2505
231k
                    ps_sub_pic_rc_variables->as_quant_coeffs[UV].pv_data = NULL;
2506
2507
231k
                    break;
2508
231k
                }
2509
0
                default:
2510
0
                {
2511
0
                    ASSERT(false);
2512
2513
0
                    break;
2514
0
                }
2515
7.08M
            }
2516
2517
7.05M
            isvce_sub_pic_rc_ctxt_update(ps_proc->ps_sub_pic_rc_ctxt);
2518
7.05M
        }
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
7.05M
        if(ps_proc->u4_compute_recon)
2544
7.09M
        {
2545
            /* compute blocking strength */
2546
7.09M
            if(ps_proc->u4_disable_deblock_level != 1)
2547
5.45M
            {
2548
5.45M
                isvce_compute_bs(ps_proc, 0);
2549
2550
5.45M
                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
5.45M
            }
2556
            /* nmb deblocking and hpel and padding */
2557
7.09M
            isvce_dblk_n_mbs(ps_proc, 0);
2558
2559
7.09M
            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
7.09M
            if(ps_proc->i4_mb_x == (ps_proc->i4_wd_mbs - 1) &&
2566
257k
               ps_proc->i4_mb_y == (ps_proc->i4_ht_mbs - 1))
2567
50.2k
            {
2568
50.2k
                isvce_svc_pad_frame(ps_proc);
2569
2570
50.2k
                isvce_pad_mb_mode_buf(ps_proc->ps_intra_pred_ctxt, ps_proc->u1_spatial_layer_id,
2571
50.2k
                                      ps_proc->s_svc_params.u1_num_spatial_layers,
2572
50.2k
                                      ps_proc->s_svc_params.d_spatial_res_ratio,
2573
50.2k
                                      ps_codec->s_cfg.u4_wd, ps_codec->s_cfg.u4_ht);
2574
50.2k
            }
2575
7.09M
        }
2576
2577
        /* update the context after for coding next mb */
2578
7.05M
        error_status = isvce_update_proc_ctxt(ps_proc);
2579
2580
7.05M
        if(error_status != IH264E_SUCCESS)
2581
0
        {
2582
0
            return error_status;
2583
0
        }
2584
2585
7.05M
        {
2586
7.05M
            UWORD8 u1_new_mb_qp;
2587
2588
7.05M
            u1_new_mb_qp =
2589
7.05M
                isvce_sub_pic_rc_get_mb_qp(ps_proc->ps_sub_pic_rc_ctxt, ps_proc->u1_mb_qp);
2590
2591
7.05M
            if(u1_new_mb_qp != ps_proc->u1_mb_qp)
2592
356k
            {
2593
356k
                ps_proc->u1_mb_qp = u1_new_mb_qp;
2594
356k
                ps_proc->u4_lambda = gu1_qp0[u1_new_mb_qp];
2595
2596
356k
                isvce_init_quant_params(ps_proc, ps_proc->u1_mb_qp);
2597
356k
            }
2598
7.05M
        }
2599
2600
        /* Once the last row is processed, mark the buffer status appropriately */
2601
7.05M
        if(ps_proc->i4_ht_mbs == ps_proc->i4_mb_y)
2602
50.2k
        {
2603
            /* Pointer to current picture buffer structure */
2604
50.2k
            svc_au_buf_t *ps_cur_pic = ps_proc->ps_cur_pic;
2605
2606
            /* Pointer to current picture's mv buffer structure */
2607
50.2k
            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
50.2k
            error_status = ih264_buf_mgr_release(ps_codec->pv_svc_au_data_store_mgr,
2623
50.2k
                                                 ps_cur_mv_buf->i4_buf_id, BUF_MGR_CODEC);
2624
50.2k
            if(error_status != IH264E_SUCCESS)
2625
0
            {
2626
0
                return error_status;
2627
0
            }
2628
50.2k
            error_status = ih264_buf_mgr_release(ps_codec->pv_ref_buf_mgr, ps_cur_pic->i4_buf_id,
2629
50.2k
                                                 BUF_MGR_CODEC);
2630
50.2k
            if(error_status != IH264E_SUCCESS)
2631
0
            {
2632
0
                return error_status;
2633
0
            }
2634
50.2k
            if(ps_codec->s_cfg.u4_enable_recon)
2635
7.26k
            {
2636
                /* pic cnt */
2637
7.26k
                ps_codec->as_rec_buf[ctxt_sel].i4_pic_cnt = ps_proc->i4_pic_cnt;
2638
2639
                /* rec buffers */
2640
7.26k
                ps_codec->as_rec_buf[ctxt_sel].s_pic_buf = *ps_proc->ps_cur_pic;
2641
2642
                /* is last? */
2643
7.26k
                ps_codec->as_rec_buf[ctxt_sel].u4_is_last = ps_proc->s_entropy.u4_is_last;
2644
2645
                /* frame time stamp */
2646
7.26k
                ps_codec->as_rec_buf[ctxt_sel].u4_timestamp_high =
2647
7.26k
                    ps_proc->s_entropy.u4_timestamp_high;
2648
7.26k
                ps_codec->as_rec_buf[ctxt_sel].u4_timestamp_low =
2649
7.26k
                    ps_proc->s_entropy.u4_timestamp_low;
2650
7.26k
            }
2651
50.2k
        }
2652
7.05M
    }
2653
2654
225k
    DEBUG_HISTOGRAM_DUMP(ps_codec->s_cfg.i4_ht_mbs == ps_proc->i4_mb_y);
2655
2656
225k
    return error_status;
2657
257k
}
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
123k
{
2680
123k
    job_t s_job;
2681
2682
123k
    isvce_process_ctxt_t *ps_proc = pv_proc;
2683
123k
    isvce_codec_t *ps_codec = ps_proc->ps_codec;
2684
2685
123k
    IH264_ERROR_T ret = IH264_SUCCESS;
2686
2687
123k
    WORD32 ctxt_sel = ps_codec->i4_encode_api_call_cnt % MAX_CTXT_SETS;
2688
123k
    WORD32 error_status = IH264_SUCCESS;
2689
123k
    WORD32 is_blocking = 0;
2690
2691
123k
    ps_proc->i4_error_code = IH264_SUCCESS;
2692
2693
2.98M
    while(1)
2694
2.98M
    {
2695
        /* dequeue a job from the entropy queue */
2696
2.98M
        {
2697
2.98M
            bool b_is_entropy_state_invalid = false;
2698
2.98M
            WORD32 retval = ithread_mutex_lock(ps_codec->pv_entropy_mutex);
2699
2.98M
            volatile ISVCE_ENTROPY_THREAD_STATES_T *pe_entropy_thread_state =
2700
2.98M
                &ps_codec->ae_entropy_thread_exit_state[ctxt_sel];
2701
2702
            /* have the lock */
2703
2.98M
            if(retval == 0)
2704
2.98M
            {
2705
2.98M
                if(*pe_entropy_thread_state == INACTIVE)
2706
657k
                {
2707
                    /* no entropy threads are active, try dequeuing a job from the entropy
2708
                     * queue */
2709
657k
                    ret = ih264_list_dequeue(ps_proc->pv_entropy_jobq, &s_job, is_blocking);
2710
2711
657k
                    if(IH264_SUCCESS == ret)
2712
257k
                    {
2713
257k
                        *pe_entropy_thread_state = IN_PROCESS;
2714
257k
                        ithread_mutex_unlock(ps_codec->pv_entropy_mutex);
2715
257k
                        goto WORKER;
2716
257k
                    }
2717
400k
                    else if(is_blocking)
2718
49.8k
                    {
2719
49.8k
                        ithread_mutex_unlock(ps_codec->pv_entropy_mutex);
2720
49.8k
                        break;
2721
49.8k
                    }
2722
657k
                }
2723
2.32M
                else if(*pe_entropy_thread_state == ERRONEOUS_EXIT)
2724
4.07k
                {
2725
4.07k
                    b_is_entropy_state_invalid = true;
2726
4.07k
                }
2727
2728
2.67M
                ithread_mutex_unlock(ps_codec->pv_entropy_mutex);
2729
2.67M
            }
2730
2731
2.67M
            if(b_is_entropy_state_invalid)
2732
4.07k
            {
2733
4.07k
                ps_proc->i4_error_code = IH264_FAIL;
2734
2735
4.07k
                return IH264_FAIL;
2736
4.07k
            }
2737
2.67M
        }
2738
2739
        /* dequeue a job from the process queue */
2740
2.67M
        ret = ih264_list_dequeue(ps_proc->pv_proc_jobq, &s_job, 1);
2741
2.67M
        if(IH264_SUCCESS != ret)
2742
2.41M
        {
2743
2.41M
            if(ps_proc->i4_id)
2744
68.9k
            {
2745
68.9k
                break;
2746
68.9k
            }
2747
2.34M
            else
2748
2.34M
            {
2749
2.34M
                is_blocking = 1;
2750
2.34M
                continue;
2751
2.34M
            }
2752
2.41M
        }
2753
2754
514k
    WORKER:
2755
        /* choose appropriate proc context based on proc_base_idx */
2756
514k
        switch(s_job.i4_cmd)
2757
514k
        {
2758
257k
            case CMD_PROCESS:
2759
257k
            {
2760
257k
                ps_proc->i4_mb_cnt = s_job.i2_mb_cnt;
2761
257k
                ps_proc->i4_mb_x = s_job.i2_mb_x;
2762
257k
                ps_proc->i4_mb_y = s_job.i2_mb_y;
2763
2764
257k
                isvce_init_layer_proc_ctxt(ps_proc);
2765
2766
257k
                error_status = isvce_process(ps_proc);
2767
2768
257k
                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
257k
                break;
2776
257k
            }
2777
257k
            case CMD_ENTROPY:
2778
257k
            {
2779
257k
                ps_proc->s_entropy.i4_mb_x = s_job.i2_mb_x;
2780
257k
                ps_proc->s_entropy.i4_mb_y = s_job.i2_mb_y;
2781
257k
                ps_proc->s_entropy.i4_mb_cnt = s_job.i2_mb_cnt;
2782
2783
257k
                isvce_init_entropy_ctxt(ps_proc);
2784
2785
257k
                error_status = isvce_entropy(ps_proc);
2786
2787
257k
                if(error_status != IH264_SUCCESS)
2788
607
                {
2789
607
                    ps_codec->ae_entropy_thread_exit_state[ctxt_sel] = ERRONEOUS_EXIT;
2790
607
                    ps_proc->i4_error_code = error_status;
2791
607
                    return ret;
2792
607
                }
2793
2794
256k
                break;
2795
257k
            }
2796
256k
            default:
2797
0
            {
2798
0
                ps_proc->i4_error_code = IH264_FAIL;
2799
0
                return ret;
2800
257k
            }
2801
514k
        }
2802
514k
    }
2803
2804
119k
    return ret;
2805
123k
}