Coverage Report

Created: 2026-08-14 07:07

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