Coverage Report

Created: 2025-07-12 06:37

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