Coverage Report

Created: 2025-12-29 07:02

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libhevc/decoder/ihevcd_decode.c
Line
Count
Source
1
/******************************************************************************
2
*
3
* Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
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
/**
19
 *******************************************************************************
20
 * @file
21
 *  ihevcd_decode.c
22
 *
23
 * @brief
24
 *  Contains codecs main decode function
25
 *
26
 * @author
27
 *  Harish
28
 *
29
 * @par List of Functions:
30
 * - fill_outargs()
31
 * - ihevcd_decode
32
 * @remarks
33
 *  None
34
 *
35
 *******************************************************************************
36
 */
37
/*****************************************************************************/
38
/* File Includes                                                             */
39
/*****************************************************************************/
40
#include <stdio.h>
41
#include <stddef.h>
42
#include <stdlib.h>
43
#include <string.h>
44
#include <assert.h>
45
46
#include "ihevc_typedefs.h"
47
#include "iv.h"
48
#include "ivd.h"
49
#include "ihevcd_cxa.h"
50
#include "ithread.h"
51
52
#include "ihevc_defs.h"
53
#include "ihevc_debug.h"
54
#include "ihevc_structs.h"
55
#include "ihevc_macros.h"
56
#include "ihevc_platform_macros.h"
57
#include "ihevc_cabac_tables.h"
58
#include "ihevc_disp_mgr.h"
59
#include "ihevc_buf_mgr.h"
60
#include "ihevc_dpb_mgr.h"
61
#include "ihevc_error.h"
62
63
#include "ihevcd_defs.h"
64
#include "ihevcd_function_selector.h"
65
#include "ihevcd_structs.h"
66
#include "ihevcd_error.h"
67
#include "ihevcd_nal.h"
68
#include "ihevcd_bitstream.h"
69
#include "ihevcd_fmt_conv.h"
70
#include "ihevcd_job_queue.h"
71
#include "ihevcd_debug.h"
72
#include "ihevcd_parse_slice.h"
73
#include "ihevcd_process_slice.h"
74
#include "ihevcd_ittiam_logo.h"
75
#include "ihevcd_profile.h"
76
77
#define NUM_FRAMES_LIMIT_ENABLED 0
78
79
#if NUM_FRAMES_LIMIT_ENABLED
80
#define NUM_FRAMES_LIMIT 10000
81
#else
82
90.6k
#define NUM_FRAMES_LIMIT 0x7FFFFFFF
83
#endif
84
85
IHEVCD_ERROR_T ihevcd_check_out_buf_size(codec_t *ps_codec);
86
IHEVCD_ERROR_T ihevcd_fmt_conv(codec_t *ps_codec,
87
                               process_ctxt_t *ps_proc,
88
                               UWORD8 *pu1_y_dst,
89
                               UWORD8 *pu1_u_dst,
90
                               UWORD8 *pu1_v_dst,
91
                               WORD32 cur_row,
92
                               WORD32 num_rows);
93
WORD32 ihevcd_init(codec_t *ps_codec);
94
95
WORD32 ihevcd_allocate_dynamic_bufs(codec_t *ps_codec);
96
WORD32 ihevcd_free_dynamic_bufs(codec_t *ps_codec);
97
/*****************************************************************************/
98
/* Function Prototypes                                                       */
99
/*****************************************************************************/
100
101
102
/**
103
 *******************************************************************************
104
 *
105
 * @brief Fills output arguments for decode process
106
 *
107
 * @par   Description
108
 * Fills elements in the output structure based on the current state
109
 *
110
 * @param[in] ps_codec
111
 * Codec context
112
 *
113
 * @param[in] ps_dec_ip
114
 * Pointer to input structure
115
 *
116
 * @param[in] ps_dec_op
117
 * Pointer to output structure
118
 *
119
 * @returns none
120
 *
121
 * @remarks
122
 *
123
 *******************************************************************************
124
 */
125
static UWORD32 ihevcd_map_error(IHEVCD_ERROR_T e_error)
126
90.6k
{
127
90.6k
    UWORD32 error_code = 0;
128
90.6k
    error_code = e_error;
129
90.6k
    switch(error_code)
130
90.6k
    {
131
62.5k
        case IHEVCD_SUCCESS :
132
62.5k
            break;
133
0
        case IHEVCD_INIT_NOT_DONE:
134
0
        case IHEVCD_LEVEL_UNSUPPORTED:
135
0
        case IHEVCD_NUM_REF_UNSUPPORTED:
136
0
        case IHEVCD_NUM_REORDER_UNSUPPORTED:
137
0
        case IHEVCD_NUM_EXTRA_DISP_UNSUPPORTED:
138
0
        case IHEVCD_INSUFFICIENT_MEM_MVBANK:
139
0
        case IHEVCD_INSUFFICIENT_MEM_PICBUF:
140
3.95k
        case IHEVCD_UNSUPPORTED_CHROMA_FMT_IDC:
141
5.60k
        case IHEVCD_UNSUPPORTED_BIT_DEPTH:
142
5.60k
        case IVD_MEM_ALLOC_FAILED:
143
6.66k
        case IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED:
144
6.66k
            error_code |= 1 << IVD_FATALERROR;
145
6.66k
            break;
146
0
        case IHEVCD_INVALID_DISP_STRD:
147
0
        case IHEVCD_CXA_VERS_BUF_INSUFFICIENT:
148
0
        case IHEVCD_UNSUPPORTED_VPS_ID:
149
6.08k
        case IHEVCD_UNSUPPORTED_SPS_ID:
150
6.80k
        case IHEVCD_UNSUPPORTED_PPS_ID:
151
6.80k
        case IHEVCD_BUF_MGR_ERROR:
152
6.80k
        case IHEVCD_NO_FREE_MVBANK:
153
6.81k
        case IHEVCD_NO_FREE_PICBUF:
154
6.81k
        case IHEVCD_SLICE_IN_HEADER_MODE:
155
6.81k
        case IHEVCD_END_OF_SEQUENCE:
156
6.81k
            break;
157
14.5k
        default:
158
14.5k
            break;
159
90.6k
    }
160
90.6k
    return error_code;
161
90.6k
}
162
/**
163
 *******************************************************************************
164
 *
165
 * @brief Fills output arguments for decode process
166
 *
167
 * @par   Description
168
 * Fills elements in the output structure based on the current state
169
 *
170
 * @param[in] ps_codec
171
 * Codec context
172
 *
173
 * @param[in] ps_dec_ip
174
 * Pointer to input structure
175
 *
176
 * @param[in] ps_dec_op
177
 * Pointer to output structure
178
 *
179
 * @returns none
180
 *
181
 * @remarks
182
 *
183
 *******************************************************************************
184
 */
185
static void ihevcd_fill_outargs(codec_t *ps_codec,
186
                                void *pv_api_ip,
187
                                void *pv_api_op)
188
90.6k
{
189
190
90.6k
    ihevcd_cxa_video_decode_ip_t *ps_hevcd_dec_ip;
191
90.6k
    ihevcd_cxa_video_decode_op_t *ps_hevcd_dec_op;
192
90.6k
    ivd_video_decode_ip_t *ps_dec_ip;
193
90.6k
    ivd_video_decode_op_t *ps_dec_op;
194
195
90.6k
    ps_hevcd_dec_ip = (ihevcd_cxa_video_decode_ip_t *)pv_api_ip;
196
90.6k
    ps_hevcd_dec_op = (ihevcd_cxa_video_decode_op_t *)pv_api_op;
197
90.6k
    ps_dec_ip = &ps_hevcd_dec_ip->s_ivd_video_decode_ip_t;
198
90.6k
    ps_dec_op = &ps_hevcd_dec_op->s_ivd_video_decode_op_t;
199
200
90.6k
    ps_dec_op->u4_error_code = ihevcd_map_error((IHEVCD_ERROR_T)ps_codec->i4_error_code);
201
90.6k
    ps_dec_op->u4_num_bytes_consumed = ps_dec_ip->u4_num_Bytes
202
90.6k
                    - ps_codec->i4_bytes_remaining;
203
90.6k
    if(ps_codec->i4_sps_done)
204
52.1k
    {
205
52.1k
        ps_dec_op->u4_pic_wd = ps_codec->i4_disp_wd;
206
52.1k
        ps_dec_op->u4_pic_ht = ps_codec->i4_disp_ht;
207
52.1k
    }
208
38.5k
    else
209
38.5k
    {
210
38.5k
        ps_dec_op->u4_pic_wd = 0;
211
38.5k
        ps_dec_op->u4_pic_ht = 0;
212
38.5k
    }
213
214
90.6k
    ps_dec_op->e_pic_type = ps_codec->e_dec_pic_type;
215
90.6k
    ps_dec_op->u4_frame_decoded_flag = ps_codec->i4_pic_present;
216
90.6k
    ps_dec_op->u4_new_seq = 0;
217
218
90.6k
    ps_dec_op->u4_output_present = 0;
219
90.6k
    ps_dec_op->u4_progressive_frame_flag = 1;
220
90.6k
    ps_dec_op->i4_display_index = -1;
221
90.6k
    ps_dec_op->i4_reorder_depth = -1;
222
90.6k
    if(ps_codec->i4_sps_done)
223
52.1k
    {
224
52.1k
        sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id);
225
52.1k
        profile_tier_lvl_info_t *ps_ptl;
226
52.1k
        ps_ptl = &ps_sps->s_ptl;
227
52.1k
        if((0 == ps_ptl->s_ptl_gen.i1_general_progressive_source_flag) &&
228
13.9k
           (1 == ps_ptl->s_ptl_gen.i1_general_interlaced_source_flag))
229
820
        {
230
820
            ps_dec_op->u4_progressive_frame_flag = 0;
231
820
        }
232
52.1k
        ps_dec_op->i4_reorder_depth =
233
52.1k
                        ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1];
234
52.1k
    }
235
236
90.6k
    ps_dec_op->u4_is_ref_flag = 1;
237
90.6k
    ps_dec_op->e_output_format = ps_codec->e_chroma_fmt;
238
90.6k
    ps_dec_op->u4_is_ref_flag = 1;
239
240
90.6k
    ps_dec_op->e4_fld_type = IV_FLD_TYPE_DEFAULT;
241
90.6k
    ps_dec_op->u4_ts = (UWORD32)(-1);
242
90.6k
    ps_dec_op->u4_disp_buf_id = ps_codec->i4_disp_buf_id;
243
90.6k
    if(ps_codec->i4_flush_mode)
244
71
    {
245
71
        ps_dec_op->u4_num_bytes_consumed = 0;
246
        /*In the case of flush ,since no frame is decoded set pic type as invalid*/
247
71
        ps_dec_op->u4_is_ref_flag = 0;
248
71
        ps_dec_op->e_pic_type = IV_NA_FRAME;
249
71
        ps_dec_op->u4_frame_decoded_flag = 0;
250
251
71
    }
252
    /* If there is a display buffer */
253
90.6k
    if(ps_codec->ps_disp_buf)
254
15.4k
    {
255
15.4k
        pic_buf_t *ps_disp_buf = ps_codec->ps_disp_buf;
256
15.4k
#ifndef DISABLE_SEI
257
15.4k
        sei_params_t *ps_sei = &ps_disp_buf->s_sei_params;
258
259
15.4k
        if(ps_sei->i1_sei_parameters_present_flag &&
260
454
           ps_sei->i1_pic_timing_params_present_flag)
261
112
        {
262
112
            UWORD32 u4_pic_struct;
263
112
            u4_pic_struct = ps_sei->s_pic_timing_sei_params.u4_pic_struct;
264
112
            switch(u4_pic_struct)
265
112
            {
266
0
                case 1:
267
0
                    ps_dec_op->e4_fld_type = IV_TOP_FLD;
268
0
                    ps_dec_op->u4_progressive_frame_flag = 0;
269
0
                    break;
270
0
                case 2:
271
0
                    ps_dec_op->e4_fld_type = IV_BOT_FLD;
272
0
                    ps_dec_op->u4_progressive_frame_flag = 0;
273
0
                    break;
274
112
                case 0:
275
112
                default:
276
112
                    ps_dec_op->e4_fld_type = IV_FLD_TYPE_DEFAULT;
277
112
                    ps_dec_op->u4_progressive_frame_flag = 1;
278
112
                    break;
279
112
            }
280
112
        }
281
15.4k
#endif
282
15.4k
        ps_dec_op->i4_display_index = ps_disp_buf->i4_abs_poc;
283
15.4k
        ps_dec_op->u4_output_present = 1;
284
15.4k
        ps_dec_op->u4_ts = ps_disp_buf->u4_ts;
285
15.4k
        if((ps_codec->i4_flush_mode == 0) && (ps_codec->s_parse.i4_end_of_frame == 0))
286
0
            ps_dec_op->u4_output_present = 0;
287
15.4k
        ps_dec_op->s_disp_frm_buf.u4_y_wd = ps_codec->i4_disp_wd;
288
15.4k
        ps_dec_op->s_disp_frm_buf.u4_y_ht = ps_codec->i4_disp_ht;
289
290
15.4k
        if(ps_codec->i4_share_disp_buf)
291
0
        {
292
0
            ps_dec_op->s_disp_frm_buf.pv_y_buf = ps_disp_buf->pu1_luma;
293
0
            if(ps_codec->e_chroma_fmt != IV_YUV_420P)
294
0
            {
295
0
                ps_dec_op->s_disp_frm_buf.pv_u_buf = ps_disp_buf->pu1_chroma;
296
0
                ps_dec_op->s_disp_frm_buf.pv_v_buf = NULL;
297
0
            }
298
0
            else
299
0
            {
300
0
                WORD32 i;
301
0
                UWORD8 *pu1_u_dst = NULL, *pu1_v_dst = NULL;
302
0
                for(i = 0; i < ps_codec->i4_share_disp_buf_cnt; i++)
303
0
                {
304
0
                    WORD32 diff = ps_disp_buf->pu1_luma - ps_codec->s_disp_buffer[i].pu1_bufs[0];
305
0
                    if(diff == (ps_codec->i4_strd * PAD_TOP + PAD_LEFT))
306
0
                    {
307
0
                        pu1_u_dst = ps_codec->s_disp_buffer[i].pu1_bufs[1];
308
0
                        pu1_u_dst += (ps_codec->i4_strd * PAD_TOP) / 4 + (PAD_LEFT / 2);
309
310
0
                        pu1_v_dst = ps_codec->s_disp_buffer[i].pu1_bufs[2];
311
0
                        pu1_v_dst += (ps_codec->i4_strd * PAD_TOP) / 4 + (PAD_LEFT / 2);
312
0
                        break;
313
0
                    }
314
0
                }
315
0
                ps_dec_op->s_disp_frm_buf.pv_u_buf = pu1_u_dst;
316
0
                ps_dec_op->s_disp_frm_buf.pv_v_buf = pu1_v_dst;
317
0
            }
318
0
            ps_dec_op->s_disp_frm_buf.u4_y_strd = ps_codec->i4_strd;
319
0
        }
320
15.4k
        else
321
15.4k
        {
322
15.4k
            ps_dec_op->s_disp_frm_buf.pv_y_buf =
323
15.4k
                            ps_dec_ip->s_out_buffer.pu1_bufs[0];
324
15.4k
            ps_dec_op->s_disp_frm_buf.pv_u_buf =
325
15.4k
                            ps_dec_ip->s_out_buffer.pu1_bufs[1];
326
15.4k
            ps_dec_op->s_disp_frm_buf.pv_v_buf =
327
15.4k
                            ps_dec_ip->s_out_buffer.pu1_bufs[2];
328
15.4k
            ps_dec_op->s_disp_frm_buf.u4_y_strd = ps_codec->i4_disp_strd;
329
15.4k
        }
330
331
15.4k
        if((IV_YUV_420SP_VU == ps_codec->e_chroma_fmt)
332
14.0k
                        || (IV_YUV_420SP_UV == ps_codec->e_chroma_fmt))
333
5.28k
        {
334
5.28k
            ps_dec_op->s_disp_frm_buf.u4_u_strd =
335
5.28k
                            ps_dec_op->s_disp_frm_buf.u4_y_strd;
336
5.28k
            ps_dec_op->s_disp_frm_buf.u4_v_strd = 0;
337
5.28k
            ps_dec_op->s_disp_frm_buf.u4_u_wd =
338
5.28k
                            ps_dec_op->s_disp_frm_buf.u4_y_wd;
339
5.28k
            ps_dec_op->s_disp_frm_buf.u4_v_wd = 0;
340
5.28k
            ps_dec_op->s_disp_frm_buf.u4_u_ht =
341
5.28k
                            ps_dec_op->s_disp_frm_buf.u4_y_ht / 2;
342
5.28k
            ps_dec_op->s_disp_frm_buf.u4_v_ht = 0;
343
5.28k
        }
344
10.1k
        else if(IV_YUV_420P == ps_codec->e_chroma_fmt)
345
5.76k
        {
346
5.76k
            ps_dec_op->s_disp_frm_buf.u4_u_strd =
347
5.76k
                            ps_dec_op->s_disp_frm_buf.u4_y_strd / 2;
348
5.76k
            ps_dec_op->s_disp_frm_buf.u4_v_strd =
349
5.76k
                            ps_dec_op->s_disp_frm_buf.u4_y_strd / 2;
350
5.76k
            ps_dec_op->s_disp_frm_buf.u4_u_wd =
351
5.76k
                            ps_dec_op->s_disp_frm_buf.u4_y_wd / 2;
352
5.76k
            ps_dec_op->s_disp_frm_buf.u4_v_wd =
353
5.76k
                            ps_dec_op->s_disp_frm_buf.u4_y_wd / 2;
354
5.76k
            ps_dec_op->s_disp_frm_buf.u4_u_ht =
355
5.76k
                            ps_dec_op->s_disp_frm_buf.u4_y_ht / 2;
356
5.76k
            ps_dec_op->s_disp_frm_buf.u4_v_ht =
357
5.76k
                            ps_dec_op->s_disp_frm_buf.u4_y_ht / 2;
358
5.76k
        }
359
4.37k
        else if(IV_GRAY == ps_codec->e_chroma_fmt)
360
2.35k
        {
361
2.35k
            ps_dec_op->s_disp_frm_buf.u4_u_strd = 0;
362
2.35k
            ps_dec_op->s_disp_frm_buf.u4_v_strd = 0;
363
2.35k
            ps_dec_op->s_disp_frm_buf.u4_u_wd = 0;
364
2.35k
            ps_dec_op->s_disp_frm_buf.u4_v_wd = 0;
365
2.35k
            ps_dec_op->s_disp_frm_buf.u4_u_ht = 0;
366
2.35k
            ps_dec_op->s_disp_frm_buf.u4_v_ht = 0;
367
2.35k
        }
368
369
15.4k
    }
370
75.2k
    else if(ps_codec->i4_flush_mode)
371
71
    {
372
71
        ps_dec_op->u4_error_code = IHEVCD_END_OF_SEQUENCE;
373
        /* Come out of flush mode */
374
71
        ps_codec->i4_flush_mode = 0;
375
71
    }
376
377
90.6k
    if(ps_codec->u1_enable_cu_info && ps_dec_op->u4_output_present)
378
0
    {
379
0
        WORD32 info_map_dst_strd = ALIGN8(ps_codec->i4_wd) >> 3;
380
0
        WORD32 info_map_src_strd = ALIGN64(ps_codec->i4_wd) >> 3;
381
0
        WORD32 info_map_ht = ALIGN8(ps_codec->i4_ht);
382
0
        UWORD32 info_map_size = (ALIGN8(ps_codec->i4_wd) * info_map_ht) >> 6;
383
0
        WORD32 vert_8x8;
384
0
        UWORD8 *pu1_out_qp_map, *pu1_qp_map;
385
0
        UWORD8 *pu1_out_blk_type_map, *pu1_type_map;
386
387
0
        if(ps_hevcd_dec_ip->pu1_8x8_blk_qp_map)
388
0
        {
389
0
            ps_hevcd_dec_op->pu1_8x8_blk_qp_map = ps_hevcd_dec_ip->pu1_8x8_blk_qp_map;
390
0
            ps_hevcd_dec_op->u4_8x8_blk_qp_map_size = info_map_size;
391
392
0
            pu1_out_qp_map = ps_hevcd_dec_op->pu1_8x8_blk_qp_map;
393
0
            pu1_qp_map = ps_codec->as_buf_id_info_map[ps_codec->i4_disp_buf_id].pu1_qp_map;
394
0
            for(vert_8x8 = 0; vert_8x8 < info_map_ht; vert_8x8++)
395
0
            {
396
0
                memcpy(pu1_out_qp_map, pu1_qp_map, info_map_dst_strd);
397
0
                pu1_out_qp_map += info_map_dst_strd;
398
0
                pu1_qp_map += info_map_src_strd;
399
0
            }
400
0
        }
401
402
0
        if(ps_hevcd_dec_ip->pu1_8x8_blk_type_map)
403
0
        {
404
0
            ps_hevcd_dec_op->pu1_8x8_blk_type_map = ps_hevcd_dec_ip->pu1_8x8_blk_type_map;
405
0
            ps_hevcd_dec_op->u4_8x8_blk_type_map_size = info_map_size;
406
407
0
            pu1_out_blk_type_map = ps_hevcd_dec_op->pu1_8x8_blk_type_map;
408
0
            pu1_type_map =
409
0
                ps_codec->as_buf_id_info_map[ps_codec->i4_disp_buf_id].pu1_cu_type_map;
410
0
            for(vert_8x8 = 0; vert_8x8 < info_map_ht; vert_8x8++)
411
0
            {
412
0
                memcpy(pu1_out_blk_type_map, pu1_type_map, info_map_dst_strd);
413
0
                pu1_out_blk_type_map += info_map_dst_strd;
414
0
                pu1_type_map += info_map_src_strd;
415
0
            }
416
0
        }
417
0
    }
418
90.6k
}
419
420
/**
421
 *******************************************************************************
422
 *
423
 * @brief
424
 *  Codec process call
425
 *
426
 * @par Description:
427
 *  Codec process call  Tests for few error checks  Handle flush and decode
428
 * header related code  Parse bitstream for start codes  For each NAL unit
429
 * call decode NAL function  Once a complete frame is decoded (in frame
430
 * decode mode)  Fill output arguments and return
431
 *
432
 * @param[in] ps_codec_obj
433
 *  Pointer to codec object at API level
434
 *
435
 * @param[in] pv_api_ip
436
 *  Pointer to input argument structure
437
 *
438
 * @param[in] pv_api_op
439
 *  Pointer to output argument structure
440
 *
441
 * @returns  Status
442
 *
443
 * @remarks
444
 *
445
 *
446
 *******************************************************************************
447
 */
448
WORD32 ihevcd_decode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
449
90.6k
{
450
90.6k
    WORD32 ret = IV_SUCCESS;
451
90.6k
    codec_t *ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
452
90.6k
    ihevcd_cxa_video_decode_ip_t s_hevcd_dec_ip = {};
453
90.6k
    ihevcd_cxa_video_decode_ip_t *ps_hevcd_dec_ip;
454
90.6k
    ihevcd_cxa_video_decode_op_t *ps_hevcd_dec_op;
455
90.6k
    ivd_video_decode_ip_t *ps_dec_ip;
456
90.6k
    ivd_video_decode_op_t *ps_dec_op;
457
458
90.6k
    WORD32 proc_idx = 0;
459
90.6k
    WORD32 prev_proc_idx = 0;
460
461
    /* Initialize error code */
462
90.6k
    ps_codec->i4_error_code = 0;
463
    /* Initialize bytes remaining */
464
90.6k
    ps_codec->i4_bytes_remaining = 0;
465
466
90.6k
    ps_dec_ip = (ivd_video_decode_ip_t *)pv_api_ip;
467
90.6k
    memcpy(&s_hevcd_dec_ip, ps_dec_ip, ps_dec_ip->u4_size);
468
90.6k
    s_hevcd_dec_ip.s_ivd_video_decode_ip_t.u4_size = sizeof(ihevcd_cxa_video_decode_ip_t);
469
470
90.6k
    ps_hevcd_dec_ip = &s_hevcd_dec_ip;
471
90.6k
    ps_dec_ip = &ps_hevcd_dec_ip->s_ivd_video_decode_ip_t;
472
473
90.6k
    ps_hevcd_dec_op = (ihevcd_cxa_video_decode_op_t *)pv_api_op;
474
90.6k
    ps_dec_op = &ps_hevcd_dec_op->s_ivd_video_decode_op_t;
475
476
90.6k
    {
477
90.6k
        UWORD32 u4_size = ps_dec_op->u4_size;
478
90.6k
        memset(ps_hevcd_dec_op, 0, u4_size);
479
90.6k
        ps_dec_op->u4_size = u4_size; //Restore size field
480
90.6k
    }
481
90.6k
    if(ps_codec->i4_init_done != 1)
482
0
    {
483
0
        ps_dec_op->u4_error_code |= 1 << IVD_FATALERROR;
484
0
        ps_dec_op->u4_error_code |= IHEVCD_INIT_NOT_DONE;
485
0
        return IV_FAIL;
486
0
    }
487
488
90.6k
    if(ps_codec->u4_pic_cnt >= NUM_FRAMES_LIMIT)
489
0
    {
490
0
        ps_dec_op->u4_error_code |= 1 << IVD_FATALERROR;
491
0
        ps_dec_op->u4_error_code |= IHEVCD_NUM_FRAMES_LIMIT_REACHED;
492
0
        return IV_FAIL;
493
0
    }
494
495
90.6k
    if(ps_codec->u1_enable_cu_info && ps_codec->i4_sps_done)
496
0
    {
497
0
        UWORD32 blk_qp_map_size = ps_hevcd_dec_ip->u4_8x8_blk_qp_map_size;
498
0
        UWORD32 blk_type_map_size = ps_hevcd_dec_ip->u4_8x8_blk_type_map_size;
499
0
        UWORD32 blk_8x8_map_size = (ALIGN8(ps_codec->i4_wd) * ALIGN8(ps_codec->i4_ht)) >> 6;
500
501
0
        if ((ps_hevcd_dec_ip->pu1_8x8_blk_qp_map && blk_qp_map_size < blk_8x8_map_size) ||
502
0
            (ps_hevcd_dec_ip->pu1_8x8_blk_type_map && blk_type_map_size < blk_8x8_map_size))
503
0
        {
504
0
            ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
505
0
            ps_dec_op->u4_error_code |= IHEVCD_INSUFFICIENT_METADATA_BUFFER;
506
0
            return IV_FAIL;
507
0
        }
508
0
     }
509
510
    /* If reset flag is set, flush the existing buffers */
511
90.6k
    if(ps_codec->i4_reset_flag)
512
71
    {
513
71
        ps_codec->i4_flush_mode = 1;
514
71
    }
515
516
    /*Data memory barries instruction,so that bitstream write by the application is complete*/
517
    //arm_dsb();
518
    /* In case the decoder is not in flush mode check for input buffer validity */
519
90.6k
    if(0 == ps_codec->i4_flush_mode)
520
90.6k
    {
521
90.6k
        if(ps_dec_ip->pv_stream_buffer == NULL)
522
0
        {
523
0
            ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
524
0
            ps_dec_op->u4_error_code |= IVD_DEC_FRM_BS_BUF_NULL;
525
0
            return IV_FAIL;
526
0
        }
527
90.6k
        if(ps_dec_ip->u4_num_Bytes <= MIN_START_CODE_LEN)
528
17
        {
529
17
            if((WORD32)ps_dec_ip->u4_num_Bytes > 0)
530
17
                ps_dec_op->u4_num_bytes_consumed = ps_dec_ip->u4_num_Bytes;
531
0
            else
532
0
                ps_dec_op->u4_num_bytes_consumed = 0;
533
534
17
            ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
535
17
            ps_dec_op->u4_error_code |= IVD_DEC_NUMBYTES_INV;
536
17
            return IV_FAIL;
537
538
17
        }
539
90.6k
    }
540
541
#ifdef APPLY_CONCEALMENT
542
    {
543
        WORD32 num_mbs;
544
545
        num_mbs = (ps_codec->i4_wd * ps_codec->i4_ht + 255) >> 8;
546
        /* Reset MB Count at the beginning of every process call */
547
        ps_codec->mb_count = 0;
548
        memset(ps_codec->mb_map, 0, ((num_mbs + 7) >> 3));
549
    }
550
#endif
551
552
90.6k
    if(0 == ps_codec->i4_share_disp_buf && ps_codec->i4_header_mode == 0)
553
53.4k
    {
554
53.4k
        UWORD32 i;
555
53.4k
        if((ps_dec_ip->s_out_buffer.u4_num_bufs <= 0) ||
556
53.4k
           (ps_dec_ip->s_out_buffer.u4_num_bufs > IVD_VIDDEC_MAX_IO_BUFFERS))
557
0
        {
558
0
            ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
559
0
            ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUFS;
560
0
            return IV_FAIL;
561
0
        }
562
563
171k
        for(i = 0; i < ps_dec_ip->s_out_buffer.u4_num_bufs; i++)
564
117k
        {
565
117k
            if(ps_dec_ip->s_out_buffer.pu1_bufs[i] == NULL)
566
0
            {
567
0
                ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
568
0
                ps_dec_op->u4_error_code |= IVD_DISP_FRM_OP_BUF_NULL;
569
0
                return IV_FAIL;
570
0
            }
571
572
117k
            if(ps_dec_ip->s_out_buffer.u4_min_out_buf_size[i] == 0)
573
0
            {
574
0
                ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
575
0
                ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
576
0
                return IV_FAIL;
577
0
            }
578
117k
        }
579
53.4k
    }
580
581
90.6k
    ps_codec->ps_out_buffer = &ps_dec_ip->s_out_buffer;
582
90.6k
    ps_codec->u4_ts = ps_dec_ip->u4_ts;
583
90.6k
    if(ps_codec->i4_flush_mode)
584
71
    {
585
586
71
        ps_dec_op->u4_pic_wd = ps_codec->i4_disp_wd;
587
71
        ps_dec_op->u4_pic_ht = ps_codec->i4_disp_ht;
588
589
71
        ps_dec_op->u4_new_seq = 0;
590
591
71
        ps_codec->ps_disp_buf = (pic_buf_t *)ihevc_disp_mgr_get(
592
71
                        (disp_mgr_t *)ps_codec->pv_disp_buf_mgr, &ps_codec->i4_disp_buf_id);
593
        /* In case of non-shared mode, then convert/copy the frame to output buffer */
594
        /* Only if the codec is in non-shared mode or in shared mode but needs 420P output */
595
71
        if((ps_codec->ps_disp_buf)
596
0
                        && ((0 == ps_codec->i4_share_disp_buf)
597
0
                                        || (IV_YUV_420P
598
0
                                                        == ps_codec->e_chroma_fmt)))
599
0
        {
600
601
0
            process_ctxt_t *ps_proc = &ps_codec->as_process[prev_proc_idx];
602
0
            if(0 == ps_proc->i4_init_done)
603
0
            {
604
0
                ihevcd_init_proc_ctxt(ps_proc, 0);
605
0
            }
606
607
            /* Output buffer check */
608
0
            ret = ihevcd_check_out_buf_size(ps_codec);
609
0
            RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
610
611
            /* Set remaining number of rows to be processed */
612
0
            ret = ihevcd_fmt_conv(ps_codec, &ps_codec->as_process[prev_proc_idx],
613
0
                                  ps_dec_ip->s_out_buffer.pu1_bufs[0],
614
0
                                  ps_dec_ip->s_out_buffer.pu1_bufs[1],
615
0
                                  ps_dec_ip->s_out_buffer.pu1_bufs[2], 0,
616
0
                                  ps_codec->i4_disp_ht);
617
618
0
            ihevc_buf_mgr_release((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
619
0
                                  ps_codec->i4_disp_buf_id, BUF_MGR_DISP);
620
0
        }
621
622
71
        ihevcd_fill_outargs(ps_codec, ps_hevcd_dec_ip, ps_hevcd_dec_op);
623
624
71
        if(1 == ps_dec_op->u4_output_present)
625
0
        {
626
0
            WORD32 xpos = ps_codec->i4_disp_wd - 32 - LOGO_WD;
627
0
            WORD32 ypos = ps_codec->i4_disp_ht - 32 - LOGO_HT;
628
629
0
            if(ypos < 0)
630
0
                ypos = 0;
631
632
0
            if(xpos < 0)
633
0
                xpos = 0;
634
635
0
            INSERT_LOGO(ps_dec_ip->s_out_buffer.pu1_bufs[0],
636
0
                        ps_dec_ip->s_out_buffer.pu1_bufs[1],
637
0
                        ps_dec_ip->s_out_buffer.pu1_bufs[2], ps_codec->i4_disp_strd,
638
0
                        xpos,
639
0
                        ypos,
640
0
                        ps_codec->e_chroma_fmt,
641
0
                        ps_codec->i4_disp_wd,
642
0
                        ps_codec->i4_disp_ht);
643
0
        }
644
645
646
71
        if(NULL == ps_codec->ps_disp_buf)
647
71
        {
648
            /* If in flush mode and there are no more buffers to flush,
649
             * check for the reset flag and reset the decoder */
650
71
            if(ps_codec->i4_reset_flag)
651
71
            {
652
71
                ihevcd_init(ps_codec);
653
71
            }
654
71
            return (IV_FAIL);
655
71
        }
656
657
0
        return (IV_SUCCESS);
658
659
71
    }
660
    /* In case of shared mode, check if there is a free buffer for reconstruction */
661
90.5k
    if((0 == ps_codec->i4_header_mode) && (1 == ps_codec->i4_share_disp_buf))
662
0
    {
663
0
        WORD32 buf_status;
664
0
        buf_status = 1;
665
0
        if(ps_codec->pv_pic_buf_mgr)
666
0
            buf_status = ihevc_buf_mgr_check_free((buf_mgr_t *)ps_codec->pv_pic_buf_mgr);
667
668
        /* If there is no free buffer, then return with an error code */
669
0
        if(0 == buf_status)
670
0
        {
671
0
            ps_dec_op->u4_error_code = IVD_DEC_REF_BUF_NULL;
672
0
            ps_dec_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
673
0
            return IV_FAIL;
674
0
        }
675
0
    }
676
90.5k
    ps_codec->i4_bytes_remaining = ps_dec_ip->u4_num_Bytes;
677
90.5k
    ps_codec->pu1_inp_bitsbuf = (UWORD8 *)ps_dec_ip->pv_stream_buffer;
678
90.5k
    ps_codec->s_parse.i4_end_of_frame = 0;
679
680
90.5k
    ps_codec->i4_pic_present = 0;
681
90.5k
    ps_codec->i4_slice_error = 0;
682
90.5k
    ps_codec->ps_disp_buf = NULL;
683
684
90.5k
    if(ps_codec->i4_num_cores > 1)
685
72.7k
    {
686
72.7k
        ithread_set_affinity(0);
687
72.7k
    }
688
200k
    while(MIN_START_CODE_LEN < ps_codec->i4_bytes_remaining)
689
200k
    {
690
200k
        WORD32 nal_len;
691
200k
        WORD32 nal_ofst;
692
200k
        WORD32 bits_len;
693
694
200k
        if(ps_codec->i4_slice_error)
695
6.33k
        {
696
6.33k
            slice_header_t *ps_slice_hdr_next = ps_codec->s_parse.ps_slice_hdr_base + (ps_codec->s_parse.i4_cur_slice_idx & (MAX_SLICE_HDR_CNT - 1));
697
6.33k
            WORD32 next_slice_addr = ps_slice_hdr_next->i2_ctb_x +
698
6.33k
                            ps_slice_hdr_next->i2_ctb_y * ps_codec->s_parse.ps_sps->i2_pic_wd_in_ctb;
699
6.33k
            if(ps_codec->s_parse.i4_next_ctb_indx == next_slice_addr)
700
0
                ps_codec->i4_slice_error = 0;
701
6.33k
        }
702
703
200k
        if(ps_codec->pu1_bitsbuf_dynamic)
704
65.7k
        {
705
65.7k
            ps_codec->pu1_bitsbuf = ps_codec->pu1_bitsbuf_dynamic;
706
65.7k
            ps_codec->u4_bitsbuf_size = ps_codec->u4_bitsbuf_size_dynamic;
707
65.7k
        }
708
134k
        else
709
134k
        {
710
134k
            ps_codec->pu1_bitsbuf = ps_codec->pu1_bitsbuf_static;
711
134k
            ps_codec->u4_bitsbuf_size = ps_codec->u4_bitsbuf_size_static;
712
134k
        }
713
714
200k
        nal_ofst = ihevcd_nal_search_start_code(ps_codec->pu1_inp_bitsbuf,
715
200k
                                                ps_codec->i4_bytes_remaining);
716
        /* If there is no start code found, consume the data and break */
717
200k
        if(nal_ofst == ps_codec->i4_bytes_remaining)
718
23
        {
719
23
            ps_codec->pu1_inp_bitsbuf += nal_ofst;
720
23
            ps_codec->i4_bytes_remaining -= nal_ofst;
721
23
            break;
722
23
        }
723
724
200k
        ps_codec->i4_nal_ofst = nal_ofst;
725
200k
        {
726
200k
            WORD32 bytes_remaining = ps_codec->i4_bytes_remaining - nal_ofst;
727
728
200k
            bytes_remaining = MIN((UWORD32)bytes_remaining, ps_codec->u4_bitsbuf_size);
729
200k
            ihevcd_nal_remv_emuln_bytes(ps_codec->pu1_inp_bitsbuf + nal_ofst,
730
200k
                                        ps_codec->pu1_bitsbuf,
731
200k
                                        bytes_remaining,
732
200k
                                        &nal_len, &bits_len);
733
734
            /* Decoder may read upto 8 extra bytes at the end of frame */
735
            /* These are not used, but still set them to zero to avoid uninitialized reads */
736
200k
            if(bits_len < (WORD32)(ps_codec->u4_bitsbuf_size - 8))
737
200k
            {
738
200k
                memset(ps_codec->pu1_bitsbuf + bits_len, 0, 2 * sizeof(UWORD32));
739
200k
            }
740
200k
        }
741
        /* This may be used to update the offsets for tiles and entropy sync row offsets */
742
200k
        ps_codec->i4_num_emln_bytes = nal_len - bits_len;
743
200k
        ps_codec->i4_nal_len = nal_len;
744
745
200k
        ihevcd_bits_init(&ps_codec->s_parse.s_bitstrm, ps_codec->pu1_bitsbuf,
746
200k
                         bits_len);
747
748
200k
        ret = ihevcd_nal_unit(ps_codec);
749
750
        /* If the frame is incomplete and
751
         * the bytes remaining is zero or a header is received,
752
         * complete the frame treating it to be in error */
753
200k
        if(ps_codec->i4_pic_present &&
754
52.6k
                        (ps_codec->s_parse.i4_next_ctb_indx != ps_codec->s_parse.ps_sps->i4_pic_size_in_ctb))
755
40.2k
        {
756
40.2k
            if((ps_codec->i4_bytes_remaining - (nal_len + nal_ofst) <= MIN_START_CODE_LEN) ||
757
39.8k
                            (ps_codec->i4_header_in_slice_mode))
758
5.46k
            {
759
5.46k
                slice_header_t *ps_slice_hdr_next;
760
761
5.46k
                ps_codec->s_parse.i4_cur_slice_idx--;
762
5.46k
                if(ps_codec->s_parse.i4_cur_slice_idx < 0)
763
1
                    ps_codec->s_parse.i4_cur_slice_idx = 0;
764
765
5.46k
                ps_slice_hdr_next = ps_codec->s_parse.ps_slice_hdr_base + ((ps_codec->s_parse.i4_cur_slice_idx + 1) & (MAX_SLICE_HDR_CNT - 1));
766
5.46k
                ps_slice_hdr_next->i2_ctb_x = 0;
767
5.46k
                ps_slice_hdr_next->i2_ctb_y = ps_codec->s_parse.ps_sps->i2_pic_ht_in_ctb;
768
5.46k
                ps_codec->i4_slice_error = 1;
769
5.46k
                continue;
770
5.46k
            }
771
40.2k
        }
772
773
195k
        if(IHEVCD_IGNORE_SLICE == ret)
774
24.0k
        {
775
24.0k
            ps_codec->pu1_inp_bitsbuf += (nal_ofst + nal_len);
776
24.0k
            ps_codec->i4_bytes_remaining -= (nal_ofst + nal_len);
777
778
24.0k
            continue;
779
24.0k
        }
780
781
171k
        if(IVD_RES_CHANGED == ret)
782
1.84k
        {
783
1.84k
            break;
784
1.84k
        }
785
786
        /* Update bytes remaining and bytes consumed and input bitstream pointer */
787
        /* Do not consume the NAL in the following cases */
788
        /* Slice header reached during header decode mode */
789
        /* TODO: Next picture's slice reached */
790
169k
        if(ret != IHEVCD_SLICE_IN_HEADER_MODE)
791
140k
        {
792
140k
            if((0 == ps_codec->i4_slice_error) ||
793
12
                            (ps_codec->i4_bytes_remaining - (nal_len + nal_ofst) <= MIN_START_CODE_LEN))
794
140k
            {
795
140k
                ps_codec->pu1_inp_bitsbuf += (nal_ofst + nal_len);
796
140k
                ps_codec->i4_bytes_remaining -= (nal_ofst + nal_len);
797
140k
            }
798
140k
            if(ret != IHEVCD_SUCCESS)
799
47.3k
                break;
800
801
93.3k
            if(ps_codec->s_parse.i4_end_of_frame)
802
12.4k
                break;
803
93.3k
        }
804
28.7k
        else
805
28.7k
        {
806
28.7k
            ret = IHEVCD_SUCCESS;
807
28.7k
            break;
808
28.7k
        }
809
810
        /* Allocate dynamic bitstream buffer once SPS is decoded */
811
80.8k
        if((ps_codec->u4_allocate_dynamic_done == 0) && ps_codec->i4_sps_done)
812
2.74k
        {
813
2.74k
            WORD32 ret;
814
2.74k
            ret = ihevcd_allocate_dynamic_bufs(ps_codec);
815
2.74k
            if(ret != IV_SUCCESS)
816
0
            {
817
                /* Free any dynamic buffers that are allocated */
818
0
                ihevcd_free_dynamic_bufs(ps_codec);
819
0
                ps_codec->i4_error_code = IVD_MEM_ALLOC_FAILED;
820
0
                ps_dec_op->u4_error_code = 1 << IVD_FATALERROR;
821
0
                ps_dec_op->u4_error_code |= IVD_MEM_ALLOC_FAILED;
822
823
0
                return IV_FAIL;
824
0
            }
825
2.74k
        }
826
827
80.8k
        BREAK_AFTER_SLICE_NAL();
828
80.8k
    }
829
830
90.5k
    if(1 == ps_codec->i4_pic_present && 0 == ps_codec->s_parse.i4_end_of_frame)
831
3.66k
    {
832
3.66k
        slice_header_t *ps_slice_hdr_next;
833
3.66k
        ps_codec->i4_slice_error = 1;
834
3.66k
        ps_codec->s_parse.i4_cur_slice_idx--;
835
3.66k
        if(ps_codec->s_parse.i4_cur_slice_idx < 0)
836
0
            ps_codec->s_parse.i4_cur_slice_idx = 0;
837
838
3.66k
        ps_slice_hdr_next = ps_codec->s_parse.ps_slice_hdr_base + ((ps_codec->s_parse.i4_cur_slice_idx + 1) & (MAX_SLICE_HDR_CNT - 1));
839
3.66k
        ps_slice_hdr_next->i2_ctb_x = -1;
840
3.66k
        ps_slice_hdr_next->i2_ctb_y = -1;
841
842
3.66k
        ihevcd_parse_slice_data(ps_codec);
843
3.66k
        ASSERT(ps_codec->s_parse.i4_end_of_frame != 0);
844
3.66k
    }
845
846
90.5k
    if(1 == ps_codec->i4_pic_present)
847
16.1k
    {
848
16.1k
        WORD32 i;
849
16.1k
        sps_t *ps_sps = ps_codec->s_parse.ps_sps;
850
16.1k
        ps_codec->i4_first_pic_done = 1;
851
852
        /*TODO temporary fix: end_of_frame is checked before adding format conversion to job queue         */
853
16.1k
        if(ps_codec->i4_num_cores > 1 && ps_codec->s_parse.i4_end_of_frame)
854
10.9k
        {
855
856
            /* Add job queue for format conversion / frame copy for each ctb row */
857
            /* Only if the codec is in non-shared mode or in shared mode but needs 420P output */
858
10.9k
            process_ctxt_t *ps_proc;
859
860
            /* i4_num_cores - 1 contexts are currently being used by other threads */
861
10.9k
            ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1];
862
863
10.9k
            if((ps_codec->ps_disp_buf) &&
864
10.6k
               ((0 == ps_codec->i4_share_disp_buf) || (IV_YUV_420P == ps_codec->e_chroma_fmt)))
865
10.6k
            {
866
                /* If format conversion jobs were not issued in pic_init() add them here */
867
10.6k
                if((0 == ps_codec->u4_enable_fmt_conv_ahead) ||
868
0
                                (ps_codec->i4_disp_buf_id == ps_proc->i4_cur_pic_buf_id))
869
122k
                    for(i = 0; i < ps_sps->i2_pic_ht_in_ctb; i++)
870
111k
                    {
871
111k
                        proc_job_t s_job;
872
111k
                        IHEVCD_ERROR_T ret;
873
111k
                        s_job.i4_cmd = CMD_FMTCONV;
874
111k
                        s_job.i2_ctb_cnt = 0;
875
111k
                        s_job.i2_ctb_x = 0;
876
111k
                        s_job.i2_ctb_y = i;
877
111k
                        s_job.i2_slice_idx = 0;
878
111k
                        s_job.i4_tu_coeff_data_ofst = 0;
879
111k
                        ret = ihevcd_jobq_queue((jobq_t *)ps_codec->s_parse.pv_proc_jobq,
880
111k
                                                &s_job, sizeof(proc_job_t), 1);
881
111k
                        if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
882
0
                            return (WORD32)ret;
883
111k
                    }
884
10.6k
            }
885
            /* Reached end of frame : Signal terminate */
886
            /* The terminate flag is checked only after all the jobs are dequeued */
887
10.9k
            ret = ihevcd_jobq_terminate((jobq_t *)ps_codec->s_parse.pv_proc_jobq);
888
889
83.4k
            while(1)
890
83.4k
            {
891
83.4k
                IHEVCD_ERROR_T ret;
892
83.4k
                proc_job_t s_job;
893
83.4k
                process_ctxt_t *ps_proc;
894
895
                /* i4_num_cores - 1 contexts are currently being used by other threads */
896
83.4k
                ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1];
897
898
83.4k
                ret = ihevcd_jobq_dequeue((jobq_t *)ps_proc->pv_proc_jobq, &s_job,
899
83.4k
                                          sizeof(proc_job_t), 1);
900
83.4k
                if((IHEVCD_ERROR_T)IHEVCD_SUCCESS != ret)
901
10.9k
                    break;
902
903
72.5k
                ps_proc->i4_ctb_cnt = s_job.i2_ctb_cnt;
904
72.5k
                ps_proc->i4_ctb_x = s_job.i2_ctb_x;
905
72.5k
                ps_proc->i4_ctb_y = s_job.i2_ctb_y;
906
72.5k
                ps_proc->i4_cur_slice_idx = s_job.i2_slice_idx;
907
908
72.5k
                if(CMD_PROCESS == s_job.i4_cmd)
909
37.2k
                {
910
37.2k
                    ihevcd_init_proc_ctxt(ps_proc, s_job.i4_tu_coeff_data_ofst);
911
912
37.2k
                    ihevcd_process(ps_proc);
913
37.2k
                }
914
35.3k
                else if(CMD_FMTCONV == s_job.i4_cmd)
915
35.3k
                {
916
35.3k
                    sps_t *ps_sps = ps_codec->s_parse.ps_sps;
917
35.3k
                    WORD32 num_rows = 1 << ps_sps->i1_log2_ctb_size;
918
35.3k
                    if(0 == ps_proc->i4_init_done)
919
220
                    {
920
220
                        ihevcd_init_proc_ctxt(ps_proc, 0);
921
220
                    }
922
923
35.3k
                    num_rows = MIN(num_rows, (ps_codec->i4_disp_ht - (s_job.i2_ctb_y << ps_sps->i1_log2_ctb_size)));
924
35.3k
                    if(num_rows < 0)
925
0
                        num_rows = 0;
926
927
35.3k
                    ihevcd_fmt_conv(ps_codec, ps_proc,
928
35.3k
                                    ps_dec_ip->s_out_buffer.pu1_bufs[0],
929
35.3k
                                    ps_dec_ip->s_out_buffer.pu1_bufs[1],
930
35.3k
                                    ps_dec_ip->s_out_buffer.pu1_bufs[2],
931
35.3k
                                    s_job.i2_ctb_y << ps_sps->i1_log2_ctb_size,
932
35.3k
                                    num_rows);
933
35.3k
                }
934
72.5k
            }
935
10.9k
        }
936
        /* In case of non-shared mode and while running in single core mode, then convert/copy the frame to output buffer */
937
        /* Only if the codec is in non-shared mode or in shared mode but needs 420P output */
938
5.18k
        else if((ps_codec->ps_disp_buf) && ((0 == ps_codec->i4_share_disp_buf) ||
939
0
                                            (IV_YUV_420P == ps_codec->e_chroma_fmt)) &&
940
4.81k
                        (ps_codec->s_parse.i4_end_of_frame))
941
4.81k
        {
942
4.81k
            process_ctxt_t *ps_proc = &ps_codec->as_process[proc_idx];
943
            /* Set remaining number of rows to be processed */
944
4.81k
            ps_codec->s_fmt_conv.i4_num_rows = ps_codec->i4_disp_ht
945
4.81k
                            - ps_codec->s_fmt_conv.i4_cur_row;
946
4.81k
            if(0 == ps_proc->i4_init_done)
947
0
            {
948
0
                ihevcd_init_proc_ctxt(ps_proc, 0);
949
0
            }
950
951
4.81k
            if(ps_codec->s_fmt_conv.i4_num_rows < 0)
952
0
                ps_codec->s_fmt_conv.i4_num_rows = 0;
953
954
4.81k
            ret = ihevcd_fmt_conv(ps_codec, ps_proc,
955
4.81k
                                  ps_dec_ip->s_out_buffer.pu1_bufs[0],
956
4.81k
                                  ps_dec_ip->s_out_buffer.pu1_bufs[1],
957
4.81k
                                  ps_dec_ip->s_out_buffer.pu1_bufs[2],
958
4.81k
                                  ps_codec->s_fmt_conv.i4_cur_row,
959
4.81k
                                  ps_codec->s_fmt_conv.i4_num_rows);
960
4.81k
            ps_codec->s_fmt_conv.i4_cur_row += ps_codec->s_fmt_conv.i4_num_rows;
961
962
4.81k
        }
963
964
965
16.1k
        DEBUG_DUMP_MV_MAP(ps_codec);
966
967
        /* Mark MV Buf as needed for reference */
968
16.1k
        ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_mv_buf_mgr,
969
16.1k
                                 ps_codec->as_process[proc_idx].i4_cur_mv_bank_buf_id,
970
16.1k
                                 BUF_MGR_REF);
971
972
        /* Mark pic buf as needed for reference */
973
16.1k
        ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
974
16.1k
                                 ps_codec->as_process[proc_idx].i4_cur_pic_buf_id,
975
16.1k
                                 BUF_MGR_REF);
976
977
        /* Mark pic buf as needed for display */
978
16.1k
        ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
979
16.1k
                                 ps_codec->as_process[proc_idx].i4_cur_pic_buf_id,
980
16.1k
                                 BUF_MGR_DISP);
981
982
        /* Insert the current picture as short term reference */
983
16.1k
        ihevc_dpb_mgr_insert_ref((dpb_mgr_t *)ps_codec->pv_dpb_mgr,
984
16.1k
                                 ps_codec->as_process[proc_idx].ps_cur_pic,
985
16.1k
                                 ps_codec->as_process[proc_idx].i4_cur_pic_buf_id);
986
987
        /* If a frame was displayed (in non-shared mode), then release it from display manager */
988
16.1k
        if((0 == ps_codec->i4_share_disp_buf) && (ps_codec->ps_disp_buf))
989
15.4k
            ihevc_buf_mgr_release((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
990
15.4k
                                  ps_codec->i4_disp_buf_id, BUF_MGR_DISP);
991
992
        /* Wait for threads */
993
37.3k
        for(i = 0; i < (ps_codec->i4_num_cores - 1); i++)
994
21.2k
        {
995
21.2k
            if(ps_codec->ai4_process_thread_created[i])
996
21.2k
            {
997
21.2k
                if(ps_codec->i4_threads_active)
998
21.2k
                {
999
21.2k
                    ret = ithread_mutex_lock(ps_codec->apv_proc_done_mutex[i]);
1000
21.2k
                    RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
1001
1002
28.8k
                    while(!ps_codec->ai4_process_done[i])
1003
7.57k
                    {
1004
7.57k
                        ithread_cond_wait(ps_codec->apv_proc_done_condition[i],
1005
7.57k
                                          ps_codec->apv_proc_done_mutex[i]);
1006
7.57k
                    }
1007
21.2k
                    ps_codec->ai4_process_done[i] = 0;
1008
21.2k
                    ret = ithread_mutex_unlock(ps_codec->apv_proc_done_mutex[i]);
1009
21.2k
                    RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
1010
21.2k
                }
1011
0
                else
1012
0
                {
1013
0
                    ithread_join(ps_codec->apv_process_thread_handle[i], NULL);
1014
0
                    ps_codec->ai4_process_thread_created[i] = 0;
1015
0
                }
1016
21.2k
            }
1017
21.2k
        }
1018
1019
16.1k
        DEBUG_VALIDATE_PADDED_REGION(&ps_codec->as_process[proc_idx]);
1020
16.1k
        if(ps_codec->u4_pic_cnt > 0)
1021
13.9k
        {
1022
13.9k
            DEBUG_DUMP_PIC_PU(ps_codec);
1023
13.9k
        }
1024
16.1k
        DEBUG_DUMP_PIC_BUFFERS(ps_codec);
1025
1026
        /* Increment the number of pictures decoded */
1027
16.1k
        ps_codec->u4_pic_cnt++;
1028
16.1k
    }
1029
90.5k
    ihevcd_fill_outargs(ps_codec, ps_hevcd_dec_ip, ps_hevcd_dec_op);
1030
1031
90.5k
    if(1 == ps_dec_op->u4_output_present)
1032
15.4k
    {
1033
15.4k
        WORD32 xpos = ps_codec->i4_disp_wd - 32 - LOGO_WD;
1034
15.4k
        WORD32 ypos = ps_codec->i4_disp_ht - 32 - LOGO_HT;
1035
1036
15.4k
        if(ypos < 0)
1037
2.65k
            ypos = 0;
1038
1039
15.4k
        if(xpos < 0)
1040
3.41k
            xpos = 0;
1041
1042
15.4k
        INSERT_LOGO(ps_dec_ip->s_out_buffer.pu1_bufs[0],
1043
15.4k
                    ps_dec_ip->s_out_buffer.pu1_bufs[1],
1044
15.4k
                    ps_dec_ip->s_out_buffer.pu1_bufs[2], ps_codec->i4_disp_strd,
1045
15.4k
                    xpos,
1046
15.4k
                    ypos,
1047
15.4k
                    ps_codec->e_chroma_fmt,
1048
15.4k
                    ps_codec->i4_disp_wd,
1049
15.4k
                    ps_codec->i4_disp_ht);
1050
15.4k
    }
1051
1052
1053
90.5k
    return ret;
1054
90.5k
}
1055