Coverage Report

Created: 2026-01-09 07:04

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
83.9k
#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
83.8k
{
127
83.8k
    UWORD32 error_code = 0;
128
83.8k
    error_code = e_error;
129
83.8k
    switch(error_code)
130
83.8k
    {
131
59.8k
        case IHEVCD_SUCCESS :
132
59.8k
            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
2.87k
        case IHEVCD_UNSUPPORTED_CHROMA_FMT_IDC:
141
4.23k
        case IHEVCD_UNSUPPORTED_BIT_DEPTH:
142
4.23k
        case IVD_MEM_ALLOC_FAILED:
143
5.19k
        case IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED:
144
5.19k
            error_code |= 1 << IVD_FATALERROR;
145
5.19k
            break;
146
0
        case IHEVCD_INVALID_DISP_STRD:
147
0
        case IHEVCD_CXA_VERS_BUF_INSUFFICIENT:
148
0
        case IHEVCD_UNSUPPORTED_VPS_ID:
149
5.72k
        case IHEVCD_UNSUPPORTED_SPS_ID:
150
6.11k
        case IHEVCD_UNSUPPORTED_PPS_ID:
151
6.11k
        case IHEVCD_BUF_MGR_ERROR:
152
6.11k
        case IHEVCD_NO_FREE_MVBANK:
153
6.12k
        case IHEVCD_NO_FREE_PICBUF:
154
6.12k
        case IHEVCD_SLICE_IN_HEADER_MODE:
155
6.12k
        case IHEVCD_END_OF_SEQUENCE:
156
6.12k
            break;
157
12.6k
        default:
158
12.6k
            break;
159
83.8k
    }
160
83.8k
    return error_code;
161
83.8k
}
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
83.8k
{
189
190
83.8k
    ihevcd_cxa_video_decode_ip_t *ps_hevcd_dec_ip;
191
83.8k
    ihevcd_cxa_video_decode_op_t *ps_hevcd_dec_op;
192
83.8k
    ivd_video_decode_ip_t *ps_dec_ip;
193
83.8k
    ivd_video_decode_op_t *ps_dec_op;
194
195
83.8k
    ps_hevcd_dec_ip = (ihevcd_cxa_video_decode_ip_t *)pv_api_ip;
196
83.8k
    ps_hevcd_dec_op = (ihevcd_cxa_video_decode_op_t *)pv_api_op;
197
83.8k
    ps_dec_ip = &ps_hevcd_dec_ip->s_ivd_video_decode_ip_t;
198
83.8k
    ps_dec_op = &ps_hevcd_dec_op->s_ivd_video_decode_op_t;
199
200
83.8k
    ps_dec_op->u4_error_code = ihevcd_map_error((IHEVCD_ERROR_T)ps_codec->i4_error_code);
201
83.8k
    ps_dec_op->u4_num_bytes_consumed = ps_dec_ip->u4_num_Bytes
202
83.8k
                    - ps_codec->i4_bytes_remaining;
203
83.8k
    if(ps_codec->i4_sps_done)
204
48.9k
    {
205
48.9k
        ps_dec_op->u4_pic_wd = ps_codec->i4_disp_wd;
206
48.9k
        ps_dec_op->u4_pic_ht = ps_codec->i4_disp_ht;
207
48.9k
    }
208
34.9k
    else
209
34.9k
    {
210
34.9k
        ps_dec_op->u4_pic_wd = 0;
211
34.9k
        ps_dec_op->u4_pic_ht = 0;
212
34.9k
    }
213
214
83.8k
    ps_dec_op->e_pic_type = ps_codec->e_dec_pic_type;
215
83.8k
    ps_dec_op->u4_frame_decoded_flag = ps_codec->i4_pic_present;
216
83.8k
    ps_dec_op->u4_new_seq = 0;
217
218
83.8k
    ps_dec_op->u4_output_present = 0;
219
83.8k
    ps_dec_op->u4_progressive_frame_flag = 1;
220
83.8k
    ps_dec_op->i4_display_index = -1;
221
83.8k
    ps_dec_op->i4_reorder_depth = -1;
222
83.8k
    if(ps_codec->i4_sps_done)
223
48.9k
    {
224
48.9k
        sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id);
225
48.9k
        profile_tier_lvl_info_t *ps_ptl;
226
48.9k
        ps_ptl = &ps_sps->s_ptl;
227
48.9k
        if((0 == ps_ptl->s_ptl_gen.i1_general_progressive_source_flag) &&
228
12.6k
           (1 == ps_ptl->s_ptl_gen.i1_general_interlaced_source_flag))
229
868
        {
230
868
            ps_dec_op->u4_progressive_frame_flag = 0;
231
868
        }
232
48.9k
        ps_dec_op->i4_reorder_depth =
233
48.9k
                        ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1];
234
48.9k
    }
235
236
83.8k
    ps_dec_op->u4_is_ref_flag = 1;
237
83.8k
    ps_dec_op->e_output_format = ps_codec->e_chroma_fmt;
238
83.8k
    ps_dec_op->u4_is_ref_flag = 1;
239
240
83.8k
    ps_dec_op->e4_fld_type = IV_FLD_TYPE_DEFAULT;
241
83.8k
    ps_dec_op->u4_ts = (UWORD32)(-1);
242
83.8k
    ps_dec_op->u4_disp_buf_id = ps_codec->i4_disp_buf_id;
243
83.8k
    if(ps_codec->i4_flush_mode)
244
76
    {
245
76
        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
76
        ps_dec_op->u4_is_ref_flag = 0;
248
76
        ps_dec_op->e_pic_type = IV_NA_FRAME;
249
76
        ps_dec_op->u4_frame_decoded_flag = 0;
250
251
76
    }
252
    /* If there is a display buffer */
253
83.8k
    if(ps_codec->ps_disp_buf)
254
15.7k
    {
255
15.7k
        pic_buf_t *ps_disp_buf = ps_codec->ps_disp_buf;
256
15.7k
#ifndef DISABLE_SEI
257
15.7k
        sei_params_t *ps_sei = &ps_disp_buf->s_sei_params;
258
259
15.7k
        if(ps_sei->i1_sei_parameters_present_flag &&
260
407
           ps_sei->i1_pic_timing_params_present_flag)
261
100
        {
262
100
            UWORD32 u4_pic_struct;
263
100
            u4_pic_struct = ps_sei->s_pic_timing_sei_params.u4_pic_struct;
264
100
            switch(u4_pic_struct)
265
100
            {
266
1
                case 1:
267
1
                    ps_dec_op->e4_fld_type = IV_TOP_FLD;
268
1
                    ps_dec_op->u4_progressive_frame_flag = 0;
269
1
                    break;
270
1
                case 2:
271
1
                    ps_dec_op->e4_fld_type = IV_BOT_FLD;
272
1
                    ps_dec_op->u4_progressive_frame_flag = 0;
273
1
                    break;
274
98
                case 0:
275
98
                default:
276
98
                    ps_dec_op->e4_fld_type = IV_FLD_TYPE_DEFAULT;
277
98
                    ps_dec_op->u4_progressive_frame_flag = 1;
278
98
                    break;
279
100
            }
280
100
        }
281
15.7k
#endif
282
15.7k
        ps_dec_op->i4_display_index = ps_disp_buf->i4_abs_poc;
283
15.7k
        ps_dec_op->u4_output_present = 1;
284
15.7k
        ps_dec_op->u4_ts = ps_disp_buf->u4_ts;
285
15.7k
        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.7k
        ps_dec_op->s_disp_frm_buf.u4_y_wd = ps_codec->i4_disp_wd;
288
15.7k
        ps_dec_op->s_disp_frm_buf.u4_y_ht = ps_codec->i4_disp_ht;
289
290
15.7k
        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.7k
        else
321
15.7k
        {
322
15.7k
            ps_dec_op->s_disp_frm_buf.pv_y_buf =
323
15.7k
                            ps_dec_ip->s_out_buffer.pu1_bufs[0];
324
15.7k
            ps_dec_op->s_disp_frm_buf.pv_u_buf =
325
15.7k
                            ps_dec_ip->s_out_buffer.pu1_bufs[1];
326
15.7k
            ps_dec_op->s_disp_frm_buf.pv_v_buf =
327
15.7k
                            ps_dec_ip->s_out_buffer.pu1_bufs[2];
328
15.7k
            ps_dec_op->s_disp_frm_buf.u4_y_strd = ps_codec->i4_disp_strd;
329
15.7k
        }
330
331
15.7k
        if((IV_YUV_420SP_VU == ps_codec->e_chroma_fmt)
332
14.7k
                        || (IV_YUV_420SP_UV == ps_codec->e_chroma_fmt))
333
4.77k
        {
334
4.77k
            ps_dec_op->s_disp_frm_buf.u4_u_strd =
335
4.77k
                            ps_dec_op->s_disp_frm_buf.u4_y_strd;
336
4.77k
            ps_dec_op->s_disp_frm_buf.u4_v_strd = 0;
337
4.77k
            ps_dec_op->s_disp_frm_buf.u4_u_wd =
338
4.77k
                            ps_dec_op->s_disp_frm_buf.u4_y_wd;
339
4.77k
            ps_dec_op->s_disp_frm_buf.u4_v_wd = 0;
340
4.77k
            ps_dec_op->s_disp_frm_buf.u4_u_ht =
341
4.77k
                            ps_dec_op->s_disp_frm_buf.u4_y_ht / 2;
342
4.77k
            ps_dec_op->s_disp_frm_buf.u4_v_ht = 0;
343
4.77k
        }
344
10.9k
        else if(IV_YUV_420P == ps_codec->e_chroma_fmt)
345
7.17k
        {
346
7.17k
            ps_dec_op->s_disp_frm_buf.u4_u_strd =
347
7.17k
                            ps_dec_op->s_disp_frm_buf.u4_y_strd / 2;
348
7.17k
            ps_dec_op->s_disp_frm_buf.u4_v_strd =
349
7.17k
                            ps_dec_op->s_disp_frm_buf.u4_y_strd / 2;
350
7.17k
            ps_dec_op->s_disp_frm_buf.u4_u_wd =
351
7.17k
                            ps_dec_op->s_disp_frm_buf.u4_y_wd / 2;
352
7.17k
            ps_dec_op->s_disp_frm_buf.u4_v_wd =
353
7.17k
                            ps_dec_op->s_disp_frm_buf.u4_y_wd / 2;
354
7.17k
            ps_dec_op->s_disp_frm_buf.u4_u_ht =
355
7.17k
                            ps_dec_op->s_disp_frm_buf.u4_y_ht / 2;
356
7.17k
            ps_dec_op->s_disp_frm_buf.u4_v_ht =
357
7.17k
                            ps_dec_op->s_disp_frm_buf.u4_y_ht / 2;
358
7.17k
        }
359
3.82k
        else if(IV_GRAY == ps_codec->e_chroma_fmt)
360
1.96k
        {
361
1.96k
            ps_dec_op->s_disp_frm_buf.u4_u_strd = 0;
362
1.96k
            ps_dec_op->s_disp_frm_buf.u4_v_strd = 0;
363
1.96k
            ps_dec_op->s_disp_frm_buf.u4_u_wd = 0;
364
1.96k
            ps_dec_op->s_disp_frm_buf.u4_v_wd = 0;
365
1.96k
            ps_dec_op->s_disp_frm_buf.u4_u_ht = 0;
366
1.96k
            ps_dec_op->s_disp_frm_buf.u4_v_ht = 0;
367
1.96k
        }
368
369
15.7k
    }
370
68.1k
    else if(ps_codec->i4_flush_mode)
371
76
    {
372
76
        ps_dec_op->u4_error_code = IHEVCD_END_OF_SEQUENCE;
373
        /* Come out of flush mode */
374
76
        ps_codec->i4_flush_mode = 0;
375
76
    }
376
377
83.8k
    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
83.8k
}
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
83.9k
{
450
83.9k
    WORD32 ret = IV_SUCCESS;
451
83.9k
    codec_t *ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
452
83.9k
    ihevcd_cxa_video_decode_ip_t s_hevcd_dec_ip = {};
453
83.9k
    ihevcd_cxa_video_decode_ip_t *ps_hevcd_dec_ip;
454
83.9k
    ihevcd_cxa_video_decode_op_t *ps_hevcd_dec_op;
455
83.9k
    ivd_video_decode_ip_t *ps_dec_ip;
456
83.9k
    ivd_video_decode_op_t *ps_dec_op;
457
458
83.9k
    WORD32 proc_idx = 0;
459
83.9k
    WORD32 prev_proc_idx = 0;
460
461
    /* Initialize error code */
462
83.9k
    ps_codec->i4_error_code = 0;
463
    /* Initialize bytes remaining */
464
83.9k
    ps_codec->i4_bytes_remaining = 0;
465
466
83.9k
    ps_dec_ip = (ivd_video_decode_ip_t *)pv_api_ip;
467
83.9k
    memcpy(&s_hevcd_dec_ip, ps_dec_ip, ps_dec_ip->u4_size);
468
83.9k
    s_hevcd_dec_ip.s_ivd_video_decode_ip_t.u4_size = sizeof(ihevcd_cxa_video_decode_ip_t);
469
470
83.9k
    ps_hevcd_dec_ip = &s_hevcd_dec_ip;
471
83.9k
    ps_dec_ip = &ps_hevcd_dec_ip->s_ivd_video_decode_ip_t;
472
473
83.9k
    ps_hevcd_dec_op = (ihevcd_cxa_video_decode_op_t *)pv_api_op;
474
83.9k
    ps_dec_op = &ps_hevcd_dec_op->s_ivd_video_decode_op_t;
475
476
83.9k
    {
477
83.9k
        UWORD32 u4_size = ps_dec_op->u4_size;
478
83.9k
        memset(ps_hevcd_dec_op, 0, u4_size);
479
83.9k
        ps_dec_op->u4_size = u4_size; //Restore size field
480
83.9k
    }
481
83.9k
    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
83.9k
    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
83.9k
    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
83.9k
    if(ps_codec->i4_reset_flag)
512
76
    {
513
76
        ps_codec->i4_flush_mode = 1;
514
76
    }
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
83.9k
    if(0 == ps_codec->i4_flush_mode)
520
83.8k
    {
521
83.8k
        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
83.8k
        if(ps_dec_ip->u4_num_Bytes <= MIN_START_CODE_LEN)
528
15
        {
529
15
            if((WORD32)ps_dec_ip->u4_num_Bytes > 0)
530
15
                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
15
            ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
535
15
            ps_dec_op->u4_error_code |= IVD_DEC_NUMBYTES_INV;
536
15
            return IV_FAIL;
537
538
15
        }
539
83.8k
    }
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
83.8k
    if(0 == ps_codec->i4_share_disp_buf && ps_codec->i4_header_mode == 0)
553
50.6k
    {
554
50.6k
        UWORD32 i;
555
50.6k
        if((ps_dec_ip->s_out_buffer.u4_num_bufs <= 0) ||
556
50.6k
           (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
162k
        for(i = 0; i < ps_dec_ip->s_out_buffer.u4_num_bufs; i++)
564
111k
        {
565
111k
            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
111k
            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
111k
        }
579
50.6k
    }
580
581
83.8k
    ps_codec->ps_out_buffer = &ps_dec_ip->s_out_buffer;
582
83.8k
    ps_codec->u4_ts = ps_dec_ip->u4_ts;
583
83.8k
    if(ps_codec->i4_flush_mode)
584
76
    {
585
586
76
        ps_dec_op->u4_pic_wd = ps_codec->i4_disp_wd;
587
76
        ps_dec_op->u4_pic_ht = ps_codec->i4_disp_ht;
588
589
76
        ps_dec_op->u4_new_seq = 0;
590
591
76
        ps_codec->ps_disp_buf = (pic_buf_t *)ihevc_disp_mgr_get(
592
76
                        (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
76
        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
76
        ihevcd_fill_outargs(ps_codec, ps_hevcd_dec_ip, ps_hevcd_dec_op);
623
624
76
        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
76
        if(NULL == ps_codec->ps_disp_buf)
647
76
        {
648
            /* If in flush mode and there are no more buffers to flush,
649
             * check for the reset flag and reset the decoder */
650
76
            if(ps_codec->i4_reset_flag)
651
76
            {
652
76
                ihevcd_init(ps_codec);
653
76
            }
654
76
            return (IV_FAIL);
655
76
        }
656
657
0
        return (IV_SUCCESS);
658
659
76
    }
660
    /* In case of shared mode, check if there is a free buffer for reconstruction */
661
83.8k
    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
83.8k
    ps_codec->i4_bytes_remaining = ps_dec_ip->u4_num_Bytes;
677
83.8k
    ps_codec->pu1_inp_bitsbuf = (UWORD8 *)ps_dec_ip->pv_stream_buffer;
678
83.8k
    ps_codec->s_parse.i4_end_of_frame = 0;
679
680
83.8k
    ps_codec->i4_pic_present = 0;
681
83.8k
    ps_codec->i4_slice_error = 0;
682
83.8k
    ps_codec->ps_disp_buf = NULL;
683
684
83.8k
    if(ps_codec->i4_num_cores > 1)
685
67.3k
    {
686
67.3k
        ithread_set_affinity(0);
687
67.3k
    }
688
185k
    while(MIN_START_CODE_LEN < ps_codec->i4_bytes_remaining)
689
185k
    {
690
185k
        WORD32 nal_len;
691
185k
        WORD32 nal_ofst;
692
185k
        WORD32 bits_len;
693
694
185k
        if(ps_codec->i4_slice_error)
695
7.25k
        {
696
7.25k
            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
7.25k
            WORD32 next_slice_addr = ps_slice_hdr_next->i2_ctb_x +
698
7.25k
                            ps_slice_hdr_next->i2_ctb_y * ps_codec->s_parse.ps_sps->i2_pic_wd_in_ctb;
699
7.25k
            if(ps_codec->s_parse.i4_next_ctb_indx == next_slice_addr)
700
0
                ps_codec->i4_slice_error = 0;
701
7.25k
        }
702
703
185k
        if(ps_codec->pu1_bitsbuf_dynamic)
704
62.8k
        {
705
62.8k
            ps_codec->pu1_bitsbuf = ps_codec->pu1_bitsbuf_dynamic;
706
62.8k
            ps_codec->u4_bitsbuf_size = ps_codec->u4_bitsbuf_size_dynamic;
707
62.8k
        }
708
122k
        else
709
122k
        {
710
122k
            ps_codec->pu1_bitsbuf = ps_codec->pu1_bitsbuf_static;
711
122k
            ps_codec->u4_bitsbuf_size = ps_codec->u4_bitsbuf_size_static;
712
122k
        }
713
714
185k
        nal_ofst = ihevcd_nal_search_start_code(ps_codec->pu1_inp_bitsbuf,
715
185k
                                                ps_codec->i4_bytes_remaining);
716
        /* If there is no start code found, consume the data and break */
717
185k
        if(nal_ofst == ps_codec->i4_bytes_remaining)
718
18
        {
719
18
            ps_codec->pu1_inp_bitsbuf += nal_ofst;
720
18
            ps_codec->i4_bytes_remaining -= nal_ofst;
721
18
            break;
722
18
        }
723
724
185k
        ps_codec->i4_nal_ofst = nal_ofst;
725
185k
        {
726
185k
            WORD32 bytes_remaining = ps_codec->i4_bytes_remaining - nal_ofst;
727
728
185k
            bytes_remaining = MIN((UWORD32)bytes_remaining, ps_codec->u4_bitsbuf_size);
729
185k
            ihevcd_nal_remv_emuln_bytes(ps_codec->pu1_inp_bitsbuf + nal_ofst,
730
185k
                                        ps_codec->pu1_bitsbuf,
731
185k
                                        bytes_remaining,
732
185k
                                        &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
185k
            if(bits_len < (WORD32)(ps_codec->u4_bitsbuf_size - 8))
737
185k
            {
738
185k
                memset(ps_codec->pu1_bitsbuf + bits_len, 0, 2 * sizeof(UWORD32));
739
185k
            }
740
185k
        }
741
        /* This may be used to update the offsets for tiles and entropy sync row offsets */
742
185k
        ps_codec->i4_num_emln_bytes = nal_len - bits_len;
743
185k
        ps_codec->i4_nal_len = nal_len;
744
745
185k
        ihevcd_bits_init(&ps_codec->s_parse.s_bitstrm, ps_codec->pu1_bitsbuf,
746
185k
                         bits_len);
747
748
185k
        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
185k
        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
39.9k
        {
756
39.9k
            if((ps_codec->i4_bytes_remaining - (nal_len + nal_ofst) <= MIN_START_CODE_LEN) ||
757
39.6k
                            (ps_codec->i4_header_in_slice_mode))
758
6.24k
            {
759
6.24k
                slice_header_t *ps_slice_hdr_next;
760
761
6.24k
                ps_codec->s_parse.i4_cur_slice_idx--;
762
6.24k
                if(ps_codec->s_parse.i4_cur_slice_idx < 0)
763
6
                    ps_codec->s_parse.i4_cur_slice_idx = 0;
764
765
6.24k
                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
6.24k
                ps_slice_hdr_next->i2_ctb_x = 0;
767
6.24k
                ps_slice_hdr_next->i2_ctb_y = ps_codec->s_parse.ps_sps->i2_pic_ht_in_ctb;
768
6.24k
                ps_codec->i4_slice_error = 1;
769
6.24k
                continue;
770
6.24k
            }
771
39.9k
        }
772
773
178k
        if(IHEVCD_IGNORE_SLICE == ret)
774
22.6k
        {
775
22.6k
            ps_codec->pu1_inp_bitsbuf += (nal_ofst + nal_len);
776
22.6k
            ps_codec->i4_bytes_remaining -= (nal_ofst + nal_len);
777
778
22.6k
            continue;
779
22.6k
        }
780
781
156k
        if(IVD_RES_CHANGED == ret)
782
1.86k
        {
783
1.86k
            break;
784
1.86k
        }
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
154k
        if(ret != IHEVCD_SLICE_IN_HEADER_MODE)
791
128k
        {
792
128k
            if((0 == ps_codec->i4_slice_error) ||
793
11
                            (ps_codec->i4_bytes_remaining - (nal_len + nal_ofst) <= MIN_START_CODE_LEN))
794
128k
            {
795
128k
                ps_codec->pu1_inp_bitsbuf += (nal_ofst + nal_len);
796
128k
                ps_codec->i4_bytes_remaining -= (nal_ofst + nal_len);
797
128k
            }
798
128k
            if(ret != IHEVCD_SUCCESS)
799
42.8k
                break;
800
801
85.4k
            if(ps_codec->s_parse.i4_end_of_frame)
802
12.7k
                break;
803
85.4k
        }
804
26.2k
        else
805
26.2k
        {
806
26.2k
            ret = IHEVCD_SUCCESS;
807
26.2k
            break;
808
26.2k
        }
809
810
        /* Allocate dynamic bitstream buffer once SPS is decoded */
811
72.7k
        if((ps_codec->u4_allocate_dynamic_done == 0) && ps_codec->i4_sps_done)
812
2.62k
        {
813
2.62k
            WORD32 ret;
814
2.62k
            ret = ihevcd_allocate_dynamic_bufs(ps_codec);
815
2.62k
            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.62k
        }
826
827
72.7k
        BREAK_AFTER_SLICE_NAL();
828
72.7k
    }
829
830
83.8k
    if(1 == ps_codec->i4_pic_present && 0 == ps_codec->s_parse.i4_end_of_frame)
831
3.68k
    {
832
3.68k
        slice_header_t *ps_slice_hdr_next;
833
3.68k
        ps_codec->i4_slice_error = 1;
834
3.68k
        ps_codec->s_parse.i4_cur_slice_idx--;
835
3.68k
        if(ps_codec->s_parse.i4_cur_slice_idx < 0)
836
0
            ps_codec->s_parse.i4_cur_slice_idx = 0;
837
838
3.68k
        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.68k
        ps_slice_hdr_next->i2_ctb_x = -1;
840
3.68k
        ps_slice_hdr_next->i2_ctb_y = -1;
841
842
3.68k
        ihevcd_parse_slice_data(ps_codec);
843
3.68k
        ASSERT(ps_codec->s_parse.i4_end_of_frame != 0);
844
3.68k
    }
845
846
83.8k
    if(1 == ps_codec->i4_pic_present)
847
16.4k
    {
848
16.4k
        WORD32 i;
849
16.4k
        sps_t *ps_sps = ps_codec->s_parse.ps_sps;
850
16.4k
        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.4k
        if(ps_codec->i4_num_cores > 1 && ps_codec->s_parse.i4_end_of_frame)
854
11.8k
        {
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
11.8k
            process_ctxt_t *ps_proc;
859
860
            /* i4_num_cores - 1 contexts are currently being used by other threads */
861
11.8k
            ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1];
862
863
11.8k
            if((ps_codec->ps_disp_buf) &&
864
11.5k
               ((0 == ps_codec->i4_share_disp_buf) || (IV_YUV_420P == ps_codec->e_chroma_fmt)))
865
11.5k
            {
866
                /* If format conversion jobs were not issued in pic_init() add them here */
867
11.5k
                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
127k
                    for(i = 0; i < ps_sps->i2_pic_ht_in_ctb; i++)
870
115k
                    {
871
115k
                        proc_job_t s_job;
872
115k
                        IHEVCD_ERROR_T ret;
873
115k
                        s_job.i4_cmd = CMD_FMTCONV;
874
115k
                        s_job.i2_ctb_cnt = 0;
875
115k
                        s_job.i2_ctb_x = 0;
876
115k
                        s_job.i2_ctb_y = i;
877
115k
                        s_job.i2_slice_idx = 0;
878
115k
                        s_job.i4_tu_coeff_data_ofst = 0;
879
115k
                        ret = ihevcd_jobq_queue((jobq_t *)ps_codec->s_parse.pv_proc_jobq,
880
115k
                                                &s_job, sizeof(proc_job_t), 1);
881
115k
                        if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
882
0
                            return (WORD32)ret;
883
115k
                    }
884
11.5k
            }
885
            /* Reached end of frame : Signal terminate */
886
            /* The terminate flag is checked only after all the jobs are dequeued */
887
11.8k
            ret = ihevcd_jobq_terminate((jobq_t *)ps_codec->s_parse.pv_proc_jobq);
888
889
80.8k
            while(1)
890
80.8k
            {
891
80.8k
                IHEVCD_ERROR_T ret;
892
80.8k
                proc_job_t s_job;
893
80.8k
                process_ctxt_t *ps_proc;
894
895
                /* i4_num_cores - 1 contexts are currently being used by other threads */
896
80.8k
                ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1];
897
898
80.8k
                ret = ihevcd_jobq_dequeue((jobq_t *)ps_proc->pv_proc_jobq, &s_job,
899
80.8k
                                          sizeof(proc_job_t), 1);
900
80.8k
                if((IHEVCD_ERROR_T)IHEVCD_SUCCESS != ret)
901
11.8k
                    break;
902
903
68.9k
                ps_proc->i4_ctb_cnt = s_job.i2_ctb_cnt;
904
68.9k
                ps_proc->i4_ctb_x = s_job.i2_ctb_x;
905
68.9k
                ps_proc->i4_ctb_y = s_job.i2_ctb_y;
906
68.9k
                ps_proc->i4_cur_slice_idx = s_job.i2_slice_idx;
907
908
68.9k
                if(CMD_PROCESS == s_job.i4_cmd)
909
37.3k
                {
910
37.3k
                    ihevcd_init_proc_ctxt(ps_proc, s_job.i4_tu_coeff_data_ofst);
911
912
37.3k
                    ihevcd_process(ps_proc);
913
37.3k
                }
914
31.5k
                else if(CMD_FMTCONV == s_job.i4_cmd)
915
31.5k
                {
916
31.5k
                    sps_t *ps_sps = ps_codec->s_parse.ps_sps;
917
31.5k
                    WORD32 num_rows = 1 << ps_sps->i1_log2_ctb_size;
918
31.5k
                    if(0 == ps_proc->i4_init_done)
919
359
                    {
920
359
                        ihevcd_init_proc_ctxt(ps_proc, 0);
921
359
                    }
922
923
31.5k
                    num_rows = MIN(num_rows, (ps_codec->i4_disp_ht - (s_job.i2_ctb_y << ps_sps->i1_log2_ctb_size)));
924
31.5k
                    if(num_rows < 0)
925
0
                        num_rows = 0;
926
927
31.5k
                    ihevcd_fmt_conv(ps_codec, ps_proc,
928
31.5k
                                    ps_dec_ip->s_out_buffer.pu1_bufs[0],
929
31.5k
                                    ps_dec_ip->s_out_buffer.pu1_bufs[1],
930
31.5k
                                    ps_dec_ip->s_out_buffer.pu1_bufs[2],
931
31.5k
                                    s_job.i2_ctb_y << ps_sps->i1_log2_ctb_size,
932
31.5k
                                    num_rows);
933
31.5k
                }
934
68.9k
            }
935
11.8k
        }
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
4.50k
        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.19k
                        (ps_codec->s_parse.i4_end_of_frame))
941
4.19k
        {
942
4.19k
            process_ctxt_t *ps_proc = &ps_codec->as_process[proc_idx];
943
            /* Set remaining number of rows to be processed */
944
4.19k
            ps_codec->s_fmt_conv.i4_num_rows = ps_codec->i4_disp_ht
945
4.19k
                            - ps_codec->s_fmt_conv.i4_cur_row;
946
4.19k
            if(0 == ps_proc->i4_init_done)
947
0
            {
948
0
                ihevcd_init_proc_ctxt(ps_proc, 0);
949
0
            }
950
951
4.19k
            if(ps_codec->s_fmt_conv.i4_num_rows < 0)
952
0
                ps_codec->s_fmt_conv.i4_num_rows = 0;
953
954
4.19k
            ret = ihevcd_fmt_conv(ps_codec, ps_proc,
955
4.19k
                                  ps_dec_ip->s_out_buffer.pu1_bufs[0],
956
4.19k
                                  ps_dec_ip->s_out_buffer.pu1_bufs[1],
957
4.19k
                                  ps_dec_ip->s_out_buffer.pu1_bufs[2],
958
4.19k
                                  ps_codec->s_fmt_conv.i4_cur_row,
959
4.19k
                                  ps_codec->s_fmt_conv.i4_num_rows);
960
4.19k
            ps_codec->s_fmt_conv.i4_cur_row += ps_codec->s_fmt_conv.i4_num_rows;
961
962
4.19k
        }
963
964
965
16.4k
        DEBUG_DUMP_MV_MAP(ps_codec);
966
967
        /* Mark MV Buf as needed for reference */
968
16.4k
        ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_mv_buf_mgr,
969
16.4k
                                 ps_codec->as_process[proc_idx].i4_cur_mv_bank_buf_id,
970
16.4k
                                 BUF_MGR_REF);
971
972
        /* Mark pic buf as needed for reference */
973
16.4k
        ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
974
16.4k
                                 ps_codec->as_process[proc_idx].i4_cur_pic_buf_id,
975
16.4k
                                 BUF_MGR_REF);
976
977
        /* Mark pic buf as needed for display */
978
16.4k
        ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
979
16.4k
                                 ps_codec->as_process[proc_idx].i4_cur_pic_buf_id,
980
16.4k
                                 BUF_MGR_DISP);
981
982
        /* Insert the current picture as short term reference */
983
16.4k
        ihevc_dpb_mgr_insert_ref((dpb_mgr_t *)ps_codec->pv_dpb_mgr,
984
16.4k
                                 ps_codec->as_process[proc_idx].ps_cur_pic,
985
16.4k
                                 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.4k
        if((0 == ps_codec->i4_share_disp_buf) && (ps_codec->ps_disp_buf))
989
15.7k
            ihevc_buf_mgr_release((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
990
15.7k
                                  ps_codec->i4_disp_buf_id, BUF_MGR_DISP);
991
992
        /* Wait for threads */
993
40.4k
        for(i = 0; i < (ps_codec->i4_num_cores - 1); i++)
994
24.0k
        {
995
24.0k
            if(ps_codec->ai4_process_thread_created[i])
996
24.0k
            {
997
24.0k
                if(ps_codec->i4_threads_active)
998
24.0k
                {
999
24.0k
                    ret = ithread_mutex_lock(ps_codec->apv_proc_done_mutex[i]);
1000
24.0k
                    RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
1001
1002
32.3k
                    while(!ps_codec->ai4_process_done[i])
1003
8.32k
                    {
1004
8.32k
                        ithread_cond_wait(ps_codec->apv_proc_done_condition[i],
1005
8.32k
                                          ps_codec->apv_proc_done_mutex[i]);
1006
8.32k
                    }
1007
24.0k
                    ps_codec->ai4_process_done[i] = 0;
1008
24.0k
                    ret = ithread_mutex_unlock(ps_codec->apv_proc_done_mutex[i]);
1009
24.0k
                    RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
1010
24.0k
                }
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
24.0k
            }
1017
24.0k
        }
1018
1019
16.4k
        DEBUG_VALIDATE_PADDED_REGION(&ps_codec->as_process[proc_idx]);
1020
16.4k
        if(ps_codec->u4_pic_cnt > 0)
1021
14.3k
        {
1022
14.3k
            DEBUG_DUMP_PIC_PU(ps_codec);
1023
14.3k
        }
1024
16.4k
        DEBUG_DUMP_PIC_BUFFERS(ps_codec);
1025
1026
        /* Increment the number of pictures decoded */
1027
16.4k
        ps_codec->u4_pic_cnt++;
1028
16.4k
    }
1029
83.8k
    ihevcd_fill_outargs(ps_codec, ps_hevcd_dec_ip, ps_hevcd_dec_op);
1030
1031
83.8k
    if(1 == ps_dec_op->u4_output_present)
1032
15.7k
    {
1033
15.7k
        WORD32 xpos = ps_codec->i4_disp_wd - 32 - LOGO_WD;
1034
15.7k
        WORD32 ypos = ps_codec->i4_disp_ht - 32 - LOGO_HT;
1035
1036
15.7k
        if(ypos < 0)
1037
2.41k
            ypos = 0;
1038
1039
15.7k
        if(xpos < 0)
1040
2.95k
            xpos = 0;
1041
1042
15.7k
        INSERT_LOGO(ps_dec_ip->s_out_buffer.pu1_bufs[0],
1043
15.7k
                    ps_dec_ip->s_out_buffer.pu1_bufs[1],
1044
15.7k
                    ps_dec_ip->s_out_buffer.pu1_bufs[2], ps_codec->i4_disp_strd,
1045
15.7k
                    xpos,
1046
15.7k
                    ypos,
1047
15.7k
                    ps_codec->e_chroma_fmt,
1048
15.7k
                    ps_codec->i4_disp_wd,
1049
15.7k
                    ps_codec->i4_disp_ht);
1050
15.7k
    }
1051
1052
1053
83.8k
    return ret;
1054
83.8k
}
1055