Coverage Report

Created: 2025-11-12 06:11

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libavc/decoder/svc/isvcd_thread_parse_decode.c
Line
Count
Source
1
/******************************************************************************
2
 *
3
 * Copyright (C) 2022 The Android Open Source Project
4
 *
5
 * Licensed under the Apache License, Version 2.0 (the "License");
6
 * you may not use this file except in compliance with the License.
7
 * You may obtain a copy of the License at:
8
 *
9
 * http://www.apache.org/licenses/LICENSE-2.0
10
 *
11
 * Unless required by applicable law or agreed to in writing, software
12
 * distributed under the License is distributed on an "AS IS" BASIS,
13
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
 * See the License for the specific language governing permissions and
15
 * limitations under the License.
16
 *
17
 *****************************************************************************
18
 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19
 */
20
/**
21
 *******************************************************************************
22
 * @file
23
 *  isvcd_thread_parse_decode.c
24
 *
25
 * @brief
26
 *  Contains routines that for multi-thread decoder
27
 *
28
 * @author
29
 *  Kishore
30
 *
31
 * @remarks
32
 *  None
33
 *
34
 *******************************************************************************
35
 */
36
37
#include <string.h>
38
#include "ih264d_error_handler.h"
39
#include "ih264d_debug.h"
40
#include "ithread.h"
41
#include "ih264d_defs.h"
42
#include "ih264d_debug.h"
43
#include "ih264d_tables.h"
44
#include "isvcd_structs.h"
45
#include "ih264d_defs.h"
46
#include "ih264d_mb_utils.h"
47
#include "ih264d_thread_parse_decode.h"
48
#include "ih264d_inter_pred.h"
49
#include "ih264d_process_pslice.h"
50
#include "isvcd_process_epslice.h"
51
#include "ih264d_process_intra_mb.h"
52
#include "ih264d_deblocking.h"
53
#include "ih264d_format_conv.h"
54
#include "isvcd_thread_parse_decode.h"
55
56
/*****************************************************************************/
57
/*                                                                           */
58
/*  Function Name : isvcd_decode_recon_tfr_nmb_thread                        */
59
/*                                                                           */
60
/*  Description   :                                                          */
61
/*                :                                                          */
62
/*                :                                                          */
63
/*  Inputs        :                                                          */
64
/*  Processing    :Only for Target Layer processing                          */
65
/*                                                                           */
66
/*  Outputs       :                                                          */
67
/*  Returns       : None                                                     */
68
/*                                                                           */
69
/*  Revision History:                                                        */
70
/*                                                                           */
71
/*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
72
/*                      ITTIAM                                               */
73
/*****************************************************************************/
74
WORD32 isvcd_decode_recon_tfr_nmb_thread(svc_dec_lyr_struct_t *ps_svc_lyr_dec, UWORD32 u4_num_mbs,
75
                                         UWORD32 u4_num_mbs_next, UWORD32 u4_end_of_row)
76
192k
{
77
192k
    WORD32 i, j;
78
192k
    dec_mb_info_t *ps_cur_mb_info;
79
192k
    dec_svc_mb_info_t *ps_svc_cur_mb_info;
80
192k
    dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
81
192k
    const UWORD32 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag;
82
192k
    UWORD32 u1_slice_type, u1_B;
83
192k
    WORD32 u1_skip_th;
84
192k
    UWORD32 u1_ipcm_th;
85
192k
    UWORD32 u4_cond;
86
192k
    UWORD16 u2_slice_num, u2_cur_dec_mb_num;
87
192k
    UWORD32 u4_mb_num;
88
192k
    WORD32 nop_cnt = 8 * 128;
89
192k
    UWORD16 *pu2_res_luma_csbp;
90
192k
    WORD32 ret;
91
192k
    u1_slice_type = ps_dec->ps_decode_cur_slice->slice_type;
92
93
192k
    u1_B = (u1_slice_type == B_SLICE);
94
192k
    u1_skip_th = ((u1_slice_type != I_SLICE) ? (u1_B ? B_8x8 : PRED_8x8R0) : -1);
95
192k
    u1_ipcm_th = ((u1_slice_type != I_SLICE) ? (u1_B ? 23 : 5) : 0);
96
192k
    u2_cur_dec_mb_num = ps_dec->cur_dec_mb_num;
97
98
256k
    while(1)
99
256k
    {
100
256k
        UWORD32 u4_max_mb =
101
256k
            (UWORD32) (ps_dec->i2_dec_thread_mb_y + (1 << u1_mbaff)) * ps_dec->u2_frm_wd_in_mbs - 1;
102
256k
        u4_mb_num = u2_cur_dec_mb_num;
103
        /*introducing 1 MB delay*/
104
256k
        u4_mb_num = MIN(u4_mb_num + u4_num_mbs + 1, u4_max_mb);
105
106
256k
        CHECK_MB_MAP_BYTE(u4_mb_num, ps_dec->pu1_dec_mb_map, u4_cond);
107
256k
        if(u4_cond)
108
191k
        {
109
191k
            break;
110
191k
        }
111
64.9k
        else
112
64.9k
        {
113
64.9k
            if(nop_cnt > 0)
114
55.9k
            {
115
55.9k
                nop_cnt -= 128;
116
55.9k
                NOP(128);
117
55.9k
            }
118
9.01k
            else
119
9.01k
            {
120
9.01k
                if(ps_dec->u4_output_present && (2 == ps_dec->u4_num_cores) &&
121
7.98k
                   (ps_dec->u4_fmt_conv_cur_row < ps_dec->s_disp_frame_info.u4_y_ht))
122
3.83k
                {
123
3.83k
                    ps_dec->u4_fmt_conv_num_rows =
124
3.83k
                        MIN(FMT_CONV_NUM_ROWS,
125
3.83k
                            (ps_dec->s_disp_frame_info.u4_y_ht - ps_dec->u4_fmt_conv_cur_row));
126
3.83k
                    ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op), ps_dec->u4_fmt_conv_cur_row,
127
3.83k
                                          ps_dec->u4_fmt_conv_num_rows);
128
3.83k
                    ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows;
129
3.83k
                }
130
5.17k
                else
131
5.17k
                {
132
5.17k
                    nop_cnt = 8 * 128;
133
5.17k
                    ithread_yield();
134
5.17k
                }
135
9.01k
                if(1 == ps_svc_lyr_dec->u1_error_in_cur_frame)
136
1.00k
                {
137
1.00k
                    return NOT_OK;
138
1.00k
                }
139
9.01k
            }
140
64.9k
        }
141
256k
    }
142
143
    /* N Mb MC Loop */
144
812k
    for(i = 0; i < u4_num_mbs; i++)
145
627k
    {
146
627k
        u4_mb_num = u2_cur_dec_mb_num;
147
627k
        GET_SLICE_NUM_MAP(ps_dec->pu2_slice_num_map, u2_cur_dec_mb_num, u2_slice_num);
148
149
627k
        if(u2_slice_num != ps_dec->u2_cur_slice_num_dec_thread)
150
7.33k
        {
151
7.33k
            ps_dec->u4_cur_slice_decode_done = 1;
152
7.33k
            break;
153
7.33k
        }
154
155
620k
        ps_cur_mb_info = &ps_dec->ps_frm_mb_info[u2_cur_dec_mb_num];
156
157
620k
        ps_dec->u4_dma_buf_idx = 0;
158
620k
        ps_dec->u4_pred_info_idx = 0;
159
160
        /*Pointer assignment for Residual NNZ */
161
620k
        pu2_res_luma_csbp = ps_svc_lyr_dec->pu2_frm_res_luma_csbp + ps_cur_mb_info->u2_mbx;
162
620k
        pu2_res_luma_csbp += ps_cur_mb_info->u2_mby * ps_svc_lyr_dec->i4_frm_res_luma_csbp_stride;
163
164
620k
        if(ps_cur_mb_info->u1_mb_type <= u1_skip_th)
165
139k
        {
166
139k
            WORD32 pred_cnt = 0;
167
139k
            pred_info_pkd_t *ps_pred_pkd;
168
139k
            UWORD32 u4_pred_info_pkd_idx;
169
170
139k
            u4_pred_info_pkd_idx = ps_cur_mb_info->u4_pred_info_pkd_idx;
171
172
399k
            while(pred_cnt < ps_cur_mb_info->u1_num_pred_parts)
173
260k
            {
174
260k
                ps_pred_pkd = ps_dec->ps_pred_pkd + u4_pred_info_pkd_idx;
175
176
260k
                ps_dec->p_form_mb_part_info_thread(ps_pred_pkd, ps_dec, ps_cur_mb_info->u2_mbx,
177
260k
                                                   ps_cur_mb_info->u2_mby, (i >> u1_mbaff),
178
260k
                                                   ps_cur_mb_info);
179
180
260k
                u4_pred_info_pkd_idx++;
181
260k
                pred_cnt++;
182
260k
            }
183
139k
            ps_dec->p_mc_dec_thread(ps_dec, ps_cur_mb_info);
184
139k
        }
185
481k
        else if(ps_cur_mb_info->u1_mb_type == MB_SKIP)
186
410k
        {
187
410k
            WORD32 pred_cnt = 0;
188
410k
            pred_info_pkd_t *ps_pred_pkd;
189
410k
            UWORD32 u4_pred_info_pkd_idx;
190
191
410k
            u4_pred_info_pkd_idx = ps_cur_mb_info->u4_pred_info_pkd_idx;
192
193
860k
            while(pred_cnt < ps_cur_mb_info->u1_num_pred_parts)
194
450k
            {
195
450k
                ps_pred_pkd = ps_dec->ps_pred_pkd + u4_pred_info_pkd_idx;
196
197
450k
                ps_dec->p_form_mb_part_info_thread(ps_pred_pkd, ps_dec, ps_cur_mb_info->u2_mbx,
198
450k
                                                   ps_cur_mb_info->u2_mby, (i >> u1_mbaff),
199
450k
                                                   ps_cur_mb_info);
200
201
450k
                u4_pred_info_pkd_idx++;
202
450k
                pred_cnt++;
203
450k
            }
204
            /* Decode MB skip */
205
410k
            ps_dec->p_mc_dec_thread(ps_dec, ps_cur_mb_info);
206
207
410k
            *pu2_res_luma_csbp = 0;
208
410k
            ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb =
209
410k
                ps_svc_lyr_dec->ps_inter_lyr_mb_prms_frm_start + ps_cur_mb_info->u2_mbx +
210
410k
                (ps_svc_lyr_dec->u2_inter_lyr_mb_prms_stride * (ps_cur_mb_info->u2_mby));
211
410k
            ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_mb_mode = SVC_INTER_MB;
212
410k
            ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_tx_size =
213
410k
                ps_cur_mb_info->u1_tran_form8x8;
214
410k
            ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u2_luma_nnz = 0;
215
410k
            ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u1_chroma_nnz = 0;
216
410k
        }
217
218
620k
        u2_cur_dec_mb_num++;
219
620k
    }
220
221
    /* N Mb IQ IT RECON  Loop */
222
812k
    for(j = 0; j < i; j++)
223
620k
    {
224
620k
        ps_cur_mb_info = &ps_dec->ps_frm_mb_info[ps_dec->cur_dec_mb_num];
225
620k
        ps_svc_cur_mb_info = &ps_svc_lyr_dec->ps_svc_frm_mb_info[ps_dec->cur_dec_mb_num];
226
227
620k
        if(NULL == ps_cur_mb_info->ps_curmb)
228
0
        {
229
0
            return NOT_OK;
230
0
        }
231
232
        /*Pointer assignment for Residual NNZ */
233
620k
        pu2_res_luma_csbp = ps_svc_lyr_dec->pu2_frm_res_luma_csbp + ps_cur_mb_info->u2_mbx;
234
620k
        pu2_res_luma_csbp += ps_cur_mb_info->u2_mby * ps_svc_lyr_dec->i4_frm_res_luma_csbp_stride;
235
236
620k
        ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb =
237
620k
            ps_svc_lyr_dec->ps_inter_lyr_mb_prms_frm_start + ps_cur_mb_info->u2_mbx +
238
620k
            (ps_svc_lyr_dec->u2_inter_lyr_mb_prms_stride * (ps_cur_mb_info->u2_mby));
239
240
620k
        ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_slice_id = (WORD8) ps_dec->u2_cur_slice_num;
241
242
620k
        if((ps_dec->u4_num_cores == 2) || !ps_dec->i1_recon_in_thread3_flag)
243
620k
        {
244
620k
            if(ps_cur_mb_info->u1_mb_type <= u1_skip_th)
245
139k
            {
246
139k
                {
247
                    /* inter intra pred generation */
248
139k
                    if(SVCD_FALSE == ps_svc_lyr_dec->u1_dyadic_flag)
249
100k
                    {
250
100k
                        ret = isvcd_process_ii_mb(ps_svc_lyr_dec, ps_cur_mb_info,
251
100k
                                                  ps_svc_cur_mb_info, j);
252
100k
                        if(ret != OK) return ret;
253
100k
                    }
254
139k
                    if(0 == ps_svc_cur_mb_info->u1_residual_prediction_flag)
255
29.1k
                    {
256
                        /* IT + Recon */
257
29.1k
                        ih264d_process_inter_mb(ps_dec, ps_cur_mb_info, j);
258
29.1k
                        isvcd_update_inter_mb_inter_layer_info(ps_svc_lyr_dec, ps_cur_mb_info, 0);
259
29.1k
                        *pu2_res_luma_csbp = ps_cur_mb_info->u2_luma_csbp;
260
29.1k
                    }
261
110k
                    else
262
110k
                    {
263
                        /* IT + Residual + Recon */
264
110k
                        ret = isvcd_process_inter_mb_rsd_pred_target_lyr(
265
110k
                            ps_svc_lyr_dec, ps_cur_mb_info, j, 0, pu2_res_luma_csbp);
266
110k
                        if(ret != OK) return ret;
267
110k
                    }
268
139k
                }
269
139k
            }
270
271
481k
            else if((ps_cur_mb_info->u1_mb_type != MB_SKIP) &&
272
70.6k
                    (ps_cur_mb_info->u1_mb_type != MB_INFER))
273
12.6k
            {
274
12.6k
                if((u1_ipcm_th + 25) != ps_cur_mb_info->u1_mb_type)
275
12.4k
                {
276
12.4k
                    ps_cur_mb_info->u1_mb_type -= (u1_skip_th + 1);
277
12.4k
                    ih264d_process_intra_mb(ps_dec, ps_cur_mb_info, j);
278
12.4k
                    isvcd_update_intra_mb_inter_layer_info(ps_svc_lyr_dec, ps_cur_mb_info);
279
12.4k
                }
280
197
                else
281
197
                {
282
197
                    isvcd_update_ipcm_mb_inter_layer_info(ps_svc_lyr_dec, ps_cur_mb_info);
283
197
                }
284
12.6k
                *pu2_res_luma_csbp = 0;
285
12.6k
            }
286
468k
            else if(ps_cur_mb_info->u1_mb_type == MB_INFER)
287
57.9k
            {
288
                /* inter layer intra prediction : intra upsample, IQ, IT ,deblock */
289
57.9k
                {
290
                    /* Intra resample for IBL mode */
291
57.9k
                    ret = isvcd_process_ibl_mb(ps_svc_lyr_dec, ps_cur_mb_info, j, 0);
292
57.9k
                    if(ret != OK) return ret;
293
                    /* Pass intra resample as pred to Recon generation */
294
57.9k
                    ih264d_process_inter_mb(ps_dec, ps_cur_mb_info, j);
295
57.9k
                    isvcd_update_inter_mb_inter_layer_info(ps_svc_lyr_dec, ps_cur_mb_info, 1);
296
57.9k
                    *pu2_res_luma_csbp = ps_cur_mb_info->u2_luma_csbp;
297
57.9k
                }
298
57.9k
                ps_dec->pi1_left_pred_mode[0] = DC;
299
57.9k
                ps_dec->pi1_left_pred_mode[1] = DC;
300
57.9k
                ps_dec->pi1_left_pred_mode[2] = DC;
301
57.9k
                ps_dec->pi1_left_pred_mode[3] = DC;
302
303
57.9k
                ps_cur_mb_info->ps_curmb->pi1_intrapredmodes[0] = DC;
304
57.9k
                ps_cur_mb_info->ps_curmb->pi1_intrapredmodes[1] = DC;
305
57.9k
                ps_cur_mb_info->ps_curmb->pi1_intrapredmodes[2] = DC;
306
57.9k
                ps_cur_mb_info->ps_curmb->pi1_intrapredmodes[3] = DC;
307
308
57.9k
                isvcd_update_ibl_mb_inter_layer_info(ps_svc_lyr_dec, ps_cur_mb_info);
309
57.9k
            }
310
311
620k
            if(ps_dec->u4_use_intrapred_line_copy == 1)
312
620k
                ih264d_copy_intra_pred_line(ps_dec, ps_cur_mb_info, j);
313
620k
        }
314
315
620k
        DATA_SYNC();
316
317
620k
        u4_mb_num = ps_cur_mb_info->u2_mbx + ps_dec->u2_frm_wd_in_mbs * ps_cur_mb_info->u2_mby;
318
620k
        UPDATE_MB_MAP_MBNUM_BYTE(ps_dec->pu1_recon_mb_map, u4_mb_num);
319
620k
        ps_dec->cur_dec_mb_num++;
320
620k
    }
321
322
    /*N MB deblocking*/
323
191k
    if(ps_dec->u4_nmb_deblk == 1)
324
0
    {
325
0
        UWORD32 u4_wd_y, u4_wd_uv;
326
0
        tfr_ctxt_t *ps_tfr_cxt = &(ps_dec->s_tran_addrecon);
327
0
        UWORD8 u1_field_pic_flag = ps_dec->ps_cur_slice->u1_field_pic_flag;
328
0
        const WORD32 i4_cb_qp_idx_ofst = ps_dec->ps_cur_pps->i1_chroma_qp_index_offset;
329
0
        const WORD32 i4_cr_qp_idx_ofst = ps_dec->ps_cur_pps->i1_second_chroma_qp_index_offset;
330
331
0
        u4_wd_y = ps_dec->u2_frm_wd_y << u1_field_pic_flag;
332
0
        u4_wd_uv = ps_dec->u2_frm_wd_uv << u1_field_pic_flag;
333
334
0
        ps_cur_mb_info = &ps_dec->ps_frm_mb_info[ps_dec->u4_cur_deblk_mb_num];
335
336
0
        ps_dec->u4_deblk_mb_x = ps_cur_mb_info->u2_mbx;
337
0
        ps_dec->u4_deblk_mb_y = ps_cur_mb_info->u2_mby;
338
339
0
        for(j = 0; j < i; j++)
340
0
        {
341
0
            ih264d_deblock_mb_nonmbaff(ps_dec, ps_tfr_cxt, i4_cb_qp_idx_ofst, i4_cr_qp_idx_ofst,
342
0
                                       u4_wd_y, u4_wd_uv);
343
0
        }
344
0
    }
345
346
    /*handle the last mb in picture case*/
347
191k
    if(ps_dec->cur_dec_mb_num > ps_dec->ps_cur_sps->u4_max_mb_addr)
348
19.6k
        ps_dec->u4_cur_slice_decode_done = 1;
349
350
191k
    if(i != u4_num_mbs)
351
7.33k
    {
352
7.33k
        u4_end_of_row = 0;
353
        /*Number of MB's left in row*/
354
7.33k
        u4_num_mbs_next = u4_num_mbs_next + ((u4_num_mbs - i) >> u1_mbaff);
355
7.33k
    }
356
357
191k
    ih264d_decode_tfr_nmb(ps_dec, (i), u4_num_mbs_next, u4_end_of_row);
358
359
191k
    return OK;
360
191k
}
361
362
/*****************************************************************************/
363
/*                                                                           */
364
/*  Function Name : isvcd_decode_slice_thread                                */
365
/*                                                                           */
366
/*  Description   :                                                          */
367
/*                :                                                          */
368
/*                :                                                          */
369
/*  Inputs        :                                                          */
370
/*  Processing    :                                                          */
371
/*                                                                           */
372
/*  Outputs       :                                                          */
373
/*  Returns       : 0 on success                                             */
374
/*                                                                           */
375
/*  Revision History:                                                        */
376
/*                                                                           */
377
/*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
378
/*                      ITTIAM                                               */
379
/*****************************************************************************/
380
WORD32 isvcd_decode_slice_thread(svc_dec_lyr_struct_t *ps_svc_lyr_dec)
381
28.8k
{
382
28.8k
    UWORD32 u4_num_mbs_next, u4_num_mbsleft, u4_end_of_row = 0;
383
28.8k
    dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
384
28.8k
    const UWORD32 i2_pic_wdin_mbs = ps_dec->u2_frm_wd_in_mbs;
385
28.8k
    UWORD32 u4_mbaff, u4_num_mbs;
386
387
28.8k
    UWORD16 u2_first_mb_in_slice;
388
28.8k
    UWORD16 i16_mb_x, i16_mb_y;
389
28.8k
    UWORD8 u1_field_pic;
390
28.8k
    UWORD32 u4_frame_stride, x_offset, y_offset;
391
28.8k
    WORD32 ret;
392
28.8k
    tfr_ctxt_t *ps_trns_addr;
393
394
    /*check for mb map of first mb in slice to ensure slice header is parsed*/
395
172k
    while(1)
396
172k
    {
397
172k
        UWORD32 u4_mb_num = ps_dec->cur_dec_mb_num;
398
172k
        UWORD32 u4_cond = 0;
399
172k
        WORD32 nop_cnt = 8 * 128;
400
172k
        CHECK_MB_MAP_BYTE(u4_mb_num, ps_dec->pu1_dec_mb_map, u4_cond);
401
172k
        if(u4_cond)
402
27.9k
        {
403
27.9k
            break;
404
27.9k
        }
405
144k
        else
406
144k
        {
407
144k
            if(nop_cnt > 0)
408
144k
            {
409
144k
                nop_cnt -= 128;
410
144k
                NOP(128);
411
144k
            }
412
0
            else if(ps_dec->u4_output_present && (2 == ps_dec->u4_num_cores) &&
413
0
                    (ps_dec->u4_fmt_conv_cur_row < ps_dec->s_disp_frame_info.u4_y_ht))
414
0
            {
415
0
                ps_dec->u4_fmt_conv_num_rows =
416
0
                    MIN(FMT_CONV_NUM_ROWS,
417
0
                        (ps_dec->s_disp_frame_info.u4_y_ht - ps_dec->u4_fmt_conv_cur_row));
418
0
                ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op), ps_dec->u4_fmt_conv_cur_row,
419
0
                                      ps_dec->u4_fmt_conv_num_rows);
420
0
                ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows;
421
0
            }
422
0
            else
423
0
            {
424
0
                nop_cnt = 8 * 128;
425
0
                ithread_yield();
426
0
            }
427
144k
            if(1 == ps_svc_lyr_dec->u1_error_in_cur_frame)
428
861
            {
429
861
                return NOT_OK;
430
861
            }
431
144k
            DEBUG_THREADS_PRINTF(
432
144k
                "waiting for mb mapcur_dec_mb_num = %d,ps_dec->u2_cur_mb_addr  = "
433
144k
                "%d\n",
434
144k
                u2_cur_dec_mb_num, ps_dec->u2_cur_mb_addr);
435
144k
        }
436
172k
    }
437
438
27.9k
    u4_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag;
439
27.9k
    u2_first_mb_in_slice = ps_dec->ps_decode_cur_slice->u4_first_mb_in_slice;
440
27.9k
    i16_mb_x = MOD(u2_first_mb_in_slice, i2_pic_wdin_mbs);
441
27.9k
    i16_mb_y = DIV(u2_first_mb_in_slice, i2_pic_wdin_mbs);
442
27.9k
    i16_mb_y <<= u4_mbaff;
443
27.9k
    ps_dec->i2_dec_thread_mb_y = i16_mb_y;
444
27.9k
    ps_dec->cur_dec_mb_num = u2_first_mb_in_slice << u4_mbaff;
445
446
27.9k
    if((ps_dec->u4_num_cores == 2) || !ps_dec->i1_recon_in_thread3_flag)
447
27.9k
    {
448
27.9k
        ps_dec->pv_proc_tu_coeff_data =
449
27.9k
            (void *) ps_dec->ps_decode_cur_slice->pv_tu_coeff_data_start;
450
27.9k
    }
451
452
    // recalculate recon pointers
453
27.9k
    u1_field_pic = ps_dec->ps_cur_slice->u1_field_pic_flag;
454
27.9k
    u4_frame_stride = ps_dec->u2_frm_wd_y << u1_field_pic;
455
27.9k
    x_offset = i16_mb_x << 4;
456
27.9k
    y_offset = (i16_mb_y * u4_frame_stride) << 4;
457
458
27.9k
    ps_trns_addr = &(ps_dec->s_tran_addrecon);
459
460
27.9k
    ps_trns_addr->pu1_dest_y = ps_dec->s_cur_pic.pu1_buf1 + x_offset + y_offset;
461
462
27.9k
    u4_frame_stride = ps_dec->u2_frm_wd_uv << u1_field_pic;
463
27.9k
    x_offset >>= 1;
464
27.9k
    y_offset = (i16_mb_y * u4_frame_stride) << 3;
465
27.9k
    x_offset *= YUV420SP_FACTOR;
466
467
27.9k
    ps_trns_addr->pu1_dest_u = ps_dec->s_cur_pic.pu1_buf2 + x_offset + y_offset;
468
27.9k
    ps_trns_addr->pu1_dest_v = ps_dec->s_cur_pic.pu1_buf3 + x_offset + y_offset;
469
470
27.9k
    ps_trns_addr->pu1_mb_y = ps_trns_addr->pu1_dest_y;
471
27.9k
    ps_trns_addr->pu1_mb_u = ps_trns_addr->pu1_dest_u;
472
27.9k
    ps_trns_addr->pu1_mb_v = ps_trns_addr->pu1_dest_v;
473
474
    /* Initialise MC and formMbPartInfo fn ptrs one time based on profile_idc */
475
27.9k
    {
476
27.9k
        ps_dec->p_mc_dec_thread = ih264d_motion_compensate_bp;
477
27.9k
        ps_dec->p_form_mb_part_info_thread = ih264d_form_mb_part_info_bp;
478
27.9k
    }
479
27.9k
    {
480
27.9k
        UWORD8 uc_nofield_nombaff;
481
27.9k
        uc_nofield_nombaff = ((ps_dec->ps_cur_slice->u1_field_pic_flag == 0) &&
482
27.9k
                              (ps_dec->ps_cur_slice->u1_mbaff_frame_flag == 0) &&
483
27.9k
                              (ps_dec->ps_decode_cur_slice->slice_type != B_SLICE) &&
484
24.3k
                              (ps_dec->ps_cur_pps->u1_wted_pred_flag == 0));
485
486
27.9k
        if(uc_nofield_nombaff == 0)
487
7.83k
        {
488
7.83k
            ps_dec->p_mc_dec_thread = ih264d_motion_compensate_mp;
489
7.83k
            ps_dec->p_form_mb_part_info_thread = ih264d_form_mb_part_info_mp;
490
7.83k
        }
491
27.9k
    }
492
493
27.9k
    ps_dec->u4_cur_slice_decode_done = 0;
494
495
219k
    while(ps_dec->u4_cur_slice_decode_done != 1)
496
192k
    {
497
192k
        u4_num_mbsleft = ((i2_pic_wdin_mbs - i16_mb_x) << u4_mbaff);
498
499
192k
        if(u4_num_mbsleft <= ps_dec->u4_recon_mb_grp)
500
192k
        {
501
192k
            u4_num_mbs = u4_num_mbsleft;
502
503
            /*Indicate number of mb's left in a row*/
504
192k
            u4_num_mbs_next = 0;
505
192k
            u4_end_of_row = 1;
506
192k
            i16_mb_x = 0;
507
192k
        }
508
0
        else
509
0
        {
510
0
            u4_num_mbs = ps_dec->u4_recon_mb_grp;
511
512
            /*Indicate number of mb's left in a row*/
513
0
            u4_num_mbs_next = i2_pic_wdin_mbs - i16_mb_x - (ps_dec->u4_recon_mb_grp >> u4_mbaff);
514
0
            i16_mb_x += (u4_num_mbs >> u4_mbaff);
515
0
            u4_end_of_row = 0;
516
0
        }
517
192k
        if(ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER)
518
192k
        {
519
192k
            ret = isvcd_decode_recon_tfr_nmb_thread(ps_svc_lyr_dec, u4_num_mbs, u4_num_mbs_next,
520
192k
                                                    u4_end_of_row);
521
192k
        }
522
192k
        if(ret != OK) return ret;
523
192k
    }
524
26.9k
    return OK;
525
27.9k
}
526
527
/*****************************************************************************/
528
/*                                                                           */
529
/*  Function Name : isvcd_decode_picture_thread                              */
530
/*                                                                           */
531
/*  Description   :                                                          */
532
/*                :                                                          */
533
/*                :                                                          */
534
/*  Inputs        :                                                          */
535
/*  Processing    :                                                          */
536
/*                                                                           */
537
/*  Outputs       :                                                          */
538
/*  Returns       : None                                                     */
539
/*                                                                           */
540
/*  Revision History:                                                        */
541
/*                                                                           */
542
/*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
543
/*                      ITTIAM                                               */
544
/*****************************************************************************/
545
void isvcd_decode_picture_thread(svc_dec_lyr_struct_t *ps_svc_lyr_dec)
546
21.5k
{
547
21.5k
    dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
548
21.5k
    WORD32 ret;
549
21.5k
    ithread_set_name("isvcd_decode_picture_thread");
550
21.5k
    while(1)
551
21.5k
    {
552
#ifdef KEEP_THREADS_ACTIVE
553
        ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[0]);
554
        if(OK != ret) break;
555
556
        while(ps_dec->ai4_process_start[0] != PROC_START)
557
        {
558
            ithread_cond_wait(ps_dec->apv_proc_start_condition[0], ps_dec->apv_proc_start_mutex[0]);
559
        }
560
        ps_dec->ai4_process_start[0] = PROC_IN_PROGRESS;
561
562
        ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[0]);
563
        if(OK != ret || ps_dec->i4_break_threads == 1) break;
564
#endif
565
28.8k
        while(1)
566
28.8k
        {
567
            /*Complete all writes before processing next slice*/
568
569
28.8k
            DEBUG_THREADS_PRINTF(" Entering decode slice svc ext\n");
570
571
28.8k
            ret = isvcd_decode_slice_thread(ps_svc_lyr_dec);
572
28.8k
            if(OK != ret) break;
573
26.9k
            DEBUG_THREADS_PRINTF(" Exit  isvcd_decode_slice_thread\n");
574
575
26.9k
            if(ps_dec->cur_dec_mb_num > ps_dec->ps_cur_sps->u4_max_mb_addr)
576
19.6k
            {
577
                /*Last slice in frame*/
578
19.6k
                break;
579
19.6k
            }
580
7.33k
            else
581
7.33k
            {
582
7.33k
                ps_dec->ps_decode_cur_slice++;
583
7.33k
                ps_dec->u2_cur_slice_num_dec_thread++;
584
7.33k
            }
585
26.9k
        }
586
21.5k
        if(ps_dec->u4_output_present && (2 == ps_dec->u4_num_cores) &&
587
8.78k
           (ps_dec->u4_fmt_conv_cur_row < ps_dec->s_disp_frame_info.u4_y_ht))
588
8.49k
        {
589
8.49k
            ps_dec->u4_fmt_conv_num_rows =
590
8.49k
                (ps_dec->s_disp_frame_info.u4_y_ht - ps_dec->u4_fmt_conv_cur_row);
591
8.49k
            ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op), ps_dec->u4_fmt_conv_cur_row,
592
8.49k
                                  ps_dec->u4_fmt_conv_num_rows);
593
8.49k
            ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows;
594
8.49k
        }
595
#ifdef KEEP_THREADS_ACTIVE
596
        ret = ithread_mutex_lock(ps_dec->apv_proc_done_mutex[0]);
597
        if(OK != ret) break;
598
599
        ps_dec->ai4_process_done[0] = PROC_DONE;
600
        ithread_cond_signal(ps_dec->apv_proc_done_condition[0]);
601
602
        ret = ithread_mutex_unlock(ps_dec->apv_proc_done_mutex[0]);
603
        if(OK != ret) break;
604
#else
605
21.5k
        break;
606
21.5k
#endif
607
21.5k
    }
608
21.5k
}