Coverage Report

Created: 2026-02-26 07:08

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
62.4k
#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
62.4k
{
127
62.4k
    UWORD32 error_code = 0;
128
62.4k
    error_code = e_error;
129
62.4k
    switch(error_code)
130
62.4k
    {
131
47.7k
        case IHEVCD_SUCCESS :
132
47.7k
            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
595
        case IHEVCD_UNSUPPORTED_CHROMA_FMT_IDC:
141
802
        case IHEVCD_UNSUPPORTED_BIT_DEPTH:
142
802
        case IVD_MEM_ALLOC_FAILED:
143
1.06k
        case IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED:
144
1.06k
            error_code |= 1 << IVD_FATALERROR;
145
1.06k
            break;
146
0
        case IHEVCD_INVALID_DISP_STRD:
147
0
        case IHEVCD_CXA_VERS_BUF_INSUFFICIENT:
148
0
        case IHEVCD_UNSUPPORTED_VPS_ID:
149
2.73k
        case IHEVCD_UNSUPPORTED_SPS_ID:
150
3.03k
        case IHEVCD_UNSUPPORTED_PPS_ID:
151
3.03k
        case IHEVCD_BUF_MGR_ERROR:
152
3.03k
        case IHEVCD_NO_FREE_MVBANK:
153
3.03k
        case IHEVCD_NO_FREE_PICBUF:
154
3.03k
        case IHEVCD_SLICE_IN_HEADER_MODE:
155
3.03k
        case IHEVCD_END_OF_SEQUENCE:
156
3.03k
            break;
157
10.5k
        default:
158
10.5k
            break;
159
62.4k
    }
160
62.4k
    return error_code;
161
62.4k
}
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
62.4k
{
189
190
62.4k
    ihevcd_cxa_video_decode_ip_t *ps_hevcd_dec_ip;
191
62.4k
    ihevcd_cxa_video_decode_op_t *ps_hevcd_dec_op;
192
62.4k
    ivd_video_decode_ip_t *ps_dec_ip;
193
62.4k
    ivd_video_decode_op_t *ps_dec_op;
194
195
62.4k
    ps_hevcd_dec_ip = (ihevcd_cxa_video_decode_ip_t *)pv_api_ip;
196
62.4k
    ps_hevcd_dec_op = (ihevcd_cxa_video_decode_op_t *)pv_api_op;
197
62.4k
    ps_dec_ip = &ps_hevcd_dec_ip->s_ivd_video_decode_ip_t;
198
62.4k
    ps_dec_op = &ps_hevcd_dec_op->s_ivd_video_decode_op_t;
199
200
62.4k
    ps_dec_op->u4_error_code = ihevcd_map_error((IHEVCD_ERROR_T)ps_codec->i4_error_code);
201
62.4k
    ps_dec_op->u4_num_bytes_consumed = ps_dec_ip->u4_num_Bytes
202
62.4k
                    - ps_codec->i4_bytes_remaining;
203
62.4k
    if(ps_codec->i4_sps_done)
204
28.7k
    {
205
28.7k
        ps_dec_op->u4_pic_wd = ps_codec->i4_disp_wd;
206
28.7k
        ps_dec_op->u4_pic_ht = ps_codec->i4_disp_ht;
207
28.7k
    }
208
33.6k
    else
209
33.6k
    {
210
33.6k
        ps_dec_op->u4_pic_wd = 0;
211
33.6k
        ps_dec_op->u4_pic_ht = 0;
212
33.6k
    }
213
214
62.4k
    ps_dec_op->e_pic_type = ps_codec->e_dec_pic_type;
215
62.4k
    ps_dec_op->u4_frame_decoded_flag = ps_codec->i4_pic_present;
216
62.4k
    ps_dec_op->u4_new_seq = 0;
217
218
62.4k
    ps_dec_op->u4_output_present = 0;
219
62.4k
    ps_dec_op->u4_progressive_frame_flag = 1;
220
62.4k
    ps_dec_op->i4_display_index = -1;
221
62.4k
    ps_dec_op->i4_reorder_depth = -1;
222
62.4k
    if(ps_codec->i4_sps_done)
223
28.7k
    {
224
28.7k
        sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id);
225
28.7k
        profile_tier_lvl_info_t *ps_ptl;
226
28.7k
        ps_ptl = &ps_sps->s_ptl;
227
28.7k
        if((0 == ps_ptl->s_ptl_gen.i1_general_progressive_source_flag) &&
228
17.2k
           (1 == ps_ptl->s_ptl_gen.i1_general_interlaced_source_flag))
229
1.03k
        {
230
1.03k
            ps_dec_op->u4_progressive_frame_flag = 0;
231
1.03k
        }
232
28.7k
        ps_dec_op->i4_reorder_depth =
233
28.7k
                        ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1];
234
28.7k
    }
235
236
62.4k
    ps_dec_op->u4_is_ref_flag = 1;
237
62.4k
    ps_dec_op->e_output_format = ps_codec->e_chroma_fmt;
238
62.4k
    ps_dec_op->u4_is_ref_flag = 1;
239
240
62.4k
    ps_dec_op->e4_fld_type = IV_FLD_TYPE_DEFAULT;
241
62.4k
    ps_dec_op->u4_ts = (UWORD32)(-1);
242
62.4k
    ps_dec_op->u4_disp_buf_id = ps_codec->i4_disp_buf_id;
243
62.4k
    if(ps_codec->i4_flush_mode)
244
149
    {
245
149
        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
149
        ps_dec_op->u4_is_ref_flag = 0;
248
149
        ps_dec_op->e_pic_type = IV_NA_FRAME;
249
149
        ps_dec_op->u4_frame_decoded_flag = 0;
250
251
149
    }
252
    /* If there is a display buffer */
253
62.4k
    if(ps_codec->ps_disp_buf)
254
9.46k
    {
255
9.46k
        pic_buf_t *ps_disp_buf = ps_codec->ps_disp_buf;
256
9.46k
#ifndef DISABLE_SEI
257
9.46k
        sei_params_t *ps_sei = &ps_disp_buf->s_sei_params;
258
259
9.46k
        if(ps_sei->i1_sei_parameters_present_flag &&
260
184
           ps_sei->i1_pic_timing_params_present_flag)
261
78
        {
262
78
            UWORD32 u4_pic_struct;
263
78
            u4_pic_struct = ps_sei->s_pic_timing_sei_params.u4_pic_struct;
264
78
            switch(u4_pic_struct)
265
78
            {
266
16
                case 1:
267
16
                    ps_dec_op->e4_fld_type = IV_TOP_FLD;
268
16
                    ps_dec_op->u4_progressive_frame_flag = 0;
269
16
                    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
62
                case 0:
275
62
                default:
276
62
                    ps_dec_op->e4_fld_type = IV_FLD_TYPE_DEFAULT;
277
62
                    ps_dec_op->u4_progressive_frame_flag = 1;
278
62
                    break;
279
78
            }
280
78
        }
281
9.46k
#endif
282
9.46k
        ps_dec_op->i4_display_index = ps_disp_buf->i4_abs_poc;
283
9.46k
        ps_dec_op->u4_output_present = 1;
284
9.46k
        ps_dec_op->u4_ts = ps_disp_buf->u4_ts;
285
9.46k
        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
9.46k
        ps_dec_op->s_disp_frm_buf.u4_y_wd = ps_codec->i4_disp_wd;
288
9.46k
        ps_dec_op->s_disp_frm_buf.u4_y_ht = ps_codec->i4_disp_ht;
289
290
9.46k
        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
9.46k
        else
321
9.46k
        {
322
9.46k
            ps_dec_op->s_disp_frm_buf.pv_y_buf =
323
9.46k
                            ps_dec_ip->s_out_buffer.pu1_bufs[0];
324
9.46k
            ps_dec_op->s_disp_frm_buf.pv_u_buf =
325
9.46k
                            ps_dec_ip->s_out_buffer.pu1_bufs[1];
326
9.46k
            ps_dec_op->s_disp_frm_buf.pv_v_buf =
327
9.46k
                            ps_dec_ip->s_out_buffer.pu1_bufs[2];
328
9.46k
            ps_dec_op->s_disp_frm_buf.u4_y_strd = ps_codec->i4_disp_strd;
329
9.46k
        }
330
331
9.46k
        if((IV_YUV_420SP_VU == ps_codec->e_chroma_fmt)
332
7.86k
                        || (IV_YUV_420SP_UV == ps_codec->e_chroma_fmt))
333
4.03k
        {
334
4.03k
            ps_dec_op->s_disp_frm_buf.u4_u_strd =
335
4.03k
                            ps_dec_op->s_disp_frm_buf.u4_y_strd;
336
4.03k
            ps_dec_op->s_disp_frm_buf.u4_v_strd = 0;
337
4.03k
            ps_dec_op->s_disp_frm_buf.u4_u_wd =
338
4.03k
                            ps_dec_op->s_disp_frm_buf.u4_y_wd;
339
4.03k
            ps_dec_op->s_disp_frm_buf.u4_v_wd = 0;
340
4.03k
            ps_dec_op->s_disp_frm_buf.u4_u_ht =
341
4.03k
                            ps_dec_op->s_disp_frm_buf.u4_y_ht / 2;
342
4.03k
            ps_dec_op->s_disp_frm_buf.u4_v_ht = 0;
343
4.03k
        }
344
5.42k
        else if(IV_YUV_420P == ps_codec->e_chroma_fmt)
345
2.99k
        {
346
2.99k
            ps_dec_op->s_disp_frm_buf.u4_u_strd =
347
2.99k
                            ps_dec_op->s_disp_frm_buf.u4_y_strd / 2;
348
2.99k
            ps_dec_op->s_disp_frm_buf.u4_v_strd =
349
2.99k
                            ps_dec_op->s_disp_frm_buf.u4_y_strd / 2;
350
2.99k
            ps_dec_op->s_disp_frm_buf.u4_u_wd =
351
2.99k
                            ps_dec_op->s_disp_frm_buf.u4_y_wd / 2;
352
2.99k
            ps_dec_op->s_disp_frm_buf.u4_v_wd =
353
2.99k
                            ps_dec_op->s_disp_frm_buf.u4_y_wd / 2;
354
2.99k
            ps_dec_op->s_disp_frm_buf.u4_u_ht =
355
2.99k
                            ps_dec_op->s_disp_frm_buf.u4_y_ht / 2;
356
2.99k
            ps_dec_op->s_disp_frm_buf.u4_v_ht =
357
2.99k
                            ps_dec_op->s_disp_frm_buf.u4_y_ht / 2;
358
2.99k
        }
359
2.43k
        else if(IV_YUV_444P == ps_codec->e_chroma_fmt)
360
0
        {
361
0
            ps_dec_op->s_disp_frm_buf.u4_u_strd = ps_dec_op->s_disp_frm_buf.u4_y_strd;
362
0
            ps_dec_op->s_disp_frm_buf.u4_v_strd = ps_dec_op->s_disp_frm_buf.u4_y_strd;
363
0
            ps_dec_op->s_disp_frm_buf.u4_u_wd = ps_dec_op->s_disp_frm_buf.u4_y_wd;
364
0
            ps_dec_op->s_disp_frm_buf.u4_v_wd = ps_dec_op->s_disp_frm_buf.u4_y_wd;
365
0
            ps_dec_op->s_disp_frm_buf.u4_u_ht = ps_dec_op->s_disp_frm_buf.u4_y_ht;
366
0
            ps_dec_op->s_disp_frm_buf.u4_v_ht = ps_dec_op->s_disp_frm_buf.u4_y_ht;
367
0
        }
368
2.43k
        else if(IV_GRAY == ps_codec->e_chroma_fmt)
369
2.43k
        {
370
2.43k
            ps_dec_op->s_disp_frm_buf.u4_u_strd = 0;
371
2.43k
            ps_dec_op->s_disp_frm_buf.u4_v_strd = 0;
372
2.43k
            ps_dec_op->s_disp_frm_buf.u4_u_wd = 0;
373
2.43k
            ps_dec_op->s_disp_frm_buf.u4_v_wd = 0;
374
2.43k
            ps_dec_op->s_disp_frm_buf.u4_u_ht = 0;
375
2.43k
            ps_dec_op->s_disp_frm_buf.u4_v_ht = 0;
376
2.43k
        }
377
378
9.46k
    }
379
52.9k
    else if(ps_codec->i4_flush_mode)
380
149
    {
381
149
        ps_dec_op->u4_error_code = IHEVCD_END_OF_SEQUENCE;
382
        /* Come out of flush mode */
383
149
        ps_codec->i4_flush_mode = 0;
384
149
    }
385
386
62.4k
    if(ps_codec->u1_enable_cu_info && ps_dec_op->u4_output_present)
387
0
    {
388
0
        WORD32 info_map_dst_strd = ALIGN8(ps_codec->i4_wd) >> 3;
389
0
        WORD32 info_map_src_strd = ALIGN64(ps_codec->i4_wd) >> 3;
390
0
        WORD32 info_map_ht = ALIGN8(ps_codec->i4_ht);
391
0
        UWORD32 info_map_size = (ALIGN8(ps_codec->i4_wd) * info_map_ht) >> 6;
392
0
        WORD32 vert_8x8;
393
0
        UWORD8 *pu1_out_qp_map, *pu1_qp_map;
394
0
        UWORD8 *pu1_out_blk_type_map, *pu1_type_map;
395
396
0
        if(ps_hevcd_dec_ip->pu1_8x8_blk_qp_map)
397
0
        {
398
0
            ps_hevcd_dec_op->pu1_8x8_blk_qp_map = ps_hevcd_dec_ip->pu1_8x8_blk_qp_map;
399
0
            ps_hevcd_dec_op->u4_8x8_blk_qp_map_size = info_map_size;
400
401
0
            pu1_out_qp_map = ps_hevcd_dec_op->pu1_8x8_blk_qp_map;
402
0
            pu1_qp_map = ps_codec->as_buf_id_info_map[ps_codec->i4_disp_buf_id].pu1_qp_map;
403
0
            for(vert_8x8 = 0; vert_8x8 < info_map_ht; vert_8x8++)
404
0
            {
405
0
                memcpy(pu1_out_qp_map, pu1_qp_map, info_map_dst_strd);
406
0
                pu1_out_qp_map += info_map_dst_strd;
407
0
                pu1_qp_map += info_map_src_strd;
408
0
            }
409
0
        }
410
411
0
        if(ps_hevcd_dec_ip->pu1_8x8_blk_type_map)
412
0
        {
413
0
            ps_hevcd_dec_op->pu1_8x8_blk_type_map = ps_hevcd_dec_ip->pu1_8x8_blk_type_map;
414
0
            ps_hevcd_dec_op->u4_8x8_blk_type_map_size = info_map_size;
415
416
0
            pu1_out_blk_type_map = ps_hevcd_dec_op->pu1_8x8_blk_type_map;
417
0
            pu1_type_map =
418
0
                ps_codec->as_buf_id_info_map[ps_codec->i4_disp_buf_id].pu1_cu_type_map;
419
0
            for(vert_8x8 = 0; vert_8x8 < info_map_ht; vert_8x8++)
420
0
            {
421
0
                memcpy(pu1_out_blk_type_map, pu1_type_map, info_map_dst_strd);
422
0
                pu1_out_blk_type_map += info_map_dst_strd;
423
0
                pu1_type_map += info_map_src_strd;
424
0
            }
425
0
        }
426
0
    }
427
62.4k
}
428
429
/**
430
 *******************************************************************************
431
 *
432
 * @brief
433
 *  Codec process call
434
 *
435
 * @par Description:
436
 *  Codec process call  Tests for few error checks  Handle flush and decode
437
 * header related code  Parse bitstream for start codes  For each NAL unit
438
 * call decode NAL function  Once a complete frame is decoded (in frame
439
 * decode mode)  Fill output arguments and return
440
 *
441
 * @param[in] ps_codec_obj
442
 *  Pointer to codec object at API level
443
 *
444
 * @param[in] pv_api_ip
445
 *  Pointer to input argument structure
446
 *
447
 * @param[in] pv_api_op
448
 *  Pointer to output argument structure
449
 *
450
 * @returns  Status
451
 *
452
 * @remarks
453
 *
454
 *
455
 *******************************************************************************
456
 */
457
WORD32 ihevcd_decode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
458
62.4k
{
459
62.4k
    WORD32 ret = IV_SUCCESS;
460
62.4k
    codec_t *ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
461
62.4k
    ihevcd_cxa_video_decode_ip_t s_hevcd_dec_ip = {};
462
62.4k
    ihevcd_cxa_video_decode_ip_t *ps_hevcd_dec_ip;
463
62.4k
    ihevcd_cxa_video_decode_op_t *ps_hevcd_dec_op;
464
62.4k
    ivd_video_decode_ip_t *ps_dec_ip;
465
62.4k
    ivd_video_decode_op_t *ps_dec_op;
466
467
62.4k
    WORD32 proc_idx = 0;
468
62.4k
    WORD32 prev_proc_idx = 0;
469
470
    /* Initialize error code */
471
62.4k
    ps_codec->i4_error_code = 0;
472
    /* Initialize bytes remaining */
473
62.4k
    ps_codec->i4_bytes_remaining = 0;
474
475
62.4k
    ps_dec_ip = (ivd_video_decode_ip_t *)pv_api_ip;
476
62.4k
    memcpy(&s_hevcd_dec_ip, ps_dec_ip, ps_dec_ip->u4_size);
477
62.4k
    s_hevcd_dec_ip.s_ivd_video_decode_ip_t.u4_size = sizeof(ihevcd_cxa_video_decode_ip_t);
478
479
62.4k
    ps_hevcd_dec_ip = &s_hevcd_dec_ip;
480
62.4k
    ps_dec_ip = &ps_hevcd_dec_ip->s_ivd_video_decode_ip_t;
481
482
62.4k
    ps_hevcd_dec_op = (ihevcd_cxa_video_decode_op_t *)pv_api_op;
483
62.4k
    ps_dec_op = &ps_hevcd_dec_op->s_ivd_video_decode_op_t;
484
485
62.4k
    {
486
62.4k
        UWORD32 u4_size = ps_dec_op->u4_size;
487
62.4k
        memset(ps_hevcd_dec_op, 0, u4_size);
488
62.4k
        ps_dec_op->u4_size = u4_size; //Restore size field
489
62.4k
    }
490
62.4k
    if(ps_codec->i4_init_done != 1)
491
0
    {
492
0
        ps_dec_op->u4_error_code |= 1 << IVD_FATALERROR;
493
0
        ps_dec_op->u4_error_code |= IHEVCD_INIT_NOT_DONE;
494
0
        return IV_FAIL;
495
0
    }
496
497
62.4k
    if(ps_codec->u4_pic_cnt >= NUM_FRAMES_LIMIT)
498
0
    {
499
0
        ps_dec_op->u4_error_code |= 1 << IVD_FATALERROR;
500
0
        ps_dec_op->u4_error_code |= IHEVCD_NUM_FRAMES_LIMIT_REACHED;
501
0
        return IV_FAIL;
502
0
    }
503
504
62.4k
    if(ps_codec->u1_enable_cu_info && ps_codec->i4_sps_done)
505
0
    {
506
0
        UWORD32 blk_qp_map_size = ps_hevcd_dec_ip->u4_8x8_blk_qp_map_size;
507
0
        UWORD32 blk_type_map_size = ps_hevcd_dec_ip->u4_8x8_blk_type_map_size;
508
0
        UWORD32 blk_8x8_map_size = (ALIGN8(ps_codec->i4_wd) * ALIGN8(ps_codec->i4_ht)) >> 6;
509
510
0
        if ((ps_hevcd_dec_ip->pu1_8x8_blk_qp_map && blk_qp_map_size < blk_8x8_map_size) ||
511
0
            (ps_hevcd_dec_ip->pu1_8x8_blk_type_map && blk_type_map_size < blk_8x8_map_size))
512
0
        {
513
0
            ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
514
0
            ps_dec_op->u4_error_code |= IHEVCD_INSUFFICIENT_METADATA_BUFFER;
515
0
            return IV_FAIL;
516
0
        }
517
0
     }
518
519
    /* If reset flag is set, flush the existing buffers */
520
62.4k
    if(ps_codec->i4_reset_flag)
521
149
    {
522
149
        ps_codec->i4_flush_mode = 1;
523
149
    }
524
525
    /*Data memory barries instruction,so that bitstream write by the application is complete*/
526
    //arm_dsb();
527
    /* In case the decoder is not in flush mode check for input buffer validity */
528
62.4k
    if(0 == ps_codec->i4_flush_mode)
529
62.2k
    {
530
62.2k
        if(ps_dec_ip->pv_stream_buffer == NULL)
531
0
        {
532
0
            ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
533
0
            ps_dec_op->u4_error_code |= IVD_DEC_FRM_BS_BUF_NULL;
534
0
            return IV_FAIL;
535
0
        }
536
62.2k
        if(ps_dec_ip->u4_num_Bytes <= MIN_START_CODE_LEN)
537
6
        {
538
6
            if((WORD32)ps_dec_ip->u4_num_Bytes > 0)
539
6
                ps_dec_op->u4_num_bytes_consumed = ps_dec_ip->u4_num_Bytes;
540
0
            else
541
0
                ps_dec_op->u4_num_bytes_consumed = 0;
542
543
6
            ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
544
6
            ps_dec_op->u4_error_code |= IVD_DEC_NUMBYTES_INV;
545
6
            return IV_FAIL;
546
547
6
        }
548
62.2k
    }
549
550
#ifdef APPLY_CONCEALMENT
551
    {
552
        WORD32 num_mbs;
553
554
        num_mbs = (ps_codec->i4_wd * ps_codec->i4_ht + 255) >> 8;
555
        /* Reset MB Count at the beginning of every process call */
556
        ps_codec->mb_count = 0;
557
        memset(ps_codec->mb_map, 0, ((num_mbs + 7) >> 3));
558
    }
559
#endif
560
561
62.4k
    if(0 == ps_codec->i4_share_disp_buf && ps_codec->i4_header_mode == 0)
562
33.3k
    {
563
33.3k
        UWORD32 i;
564
33.3k
        if((ps_dec_ip->s_out_buffer.u4_num_bufs <= 0) ||
565
33.3k
           (ps_dec_ip->s_out_buffer.u4_num_bufs > IVD_VIDDEC_MAX_IO_BUFFERS))
566
0
        {
567
0
            ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
568
0
            ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUFS;
569
0
            return IV_FAIL;
570
0
        }
571
572
104k
        for(i = 0; i < ps_dec_ip->s_out_buffer.u4_num_bufs; i++)
573
70.7k
        {
574
70.7k
            if(ps_dec_ip->s_out_buffer.pu1_bufs[i] == NULL)
575
0
            {
576
0
                ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
577
0
                ps_dec_op->u4_error_code |= IVD_DISP_FRM_OP_BUF_NULL;
578
0
                return IV_FAIL;
579
0
            }
580
581
70.7k
            if(ps_dec_ip->s_out_buffer.u4_min_out_buf_size[i] == 0)
582
0
            {
583
0
                ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
584
0
                ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
585
0
                return IV_FAIL;
586
0
            }
587
70.7k
        }
588
33.3k
    }
589
590
62.4k
    ps_codec->ps_out_buffer = &ps_dec_ip->s_out_buffer;
591
62.4k
    ps_codec->u4_ts = ps_dec_ip->u4_ts;
592
62.4k
    if(ps_codec->i4_flush_mode)
593
149
    {
594
595
149
        ps_dec_op->u4_pic_wd = ps_codec->i4_disp_wd;
596
149
        ps_dec_op->u4_pic_ht = ps_codec->i4_disp_ht;
597
598
149
        ps_dec_op->u4_new_seq = 0;
599
600
149
        ps_codec->ps_disp_buf = (pic_buf_t *)ihevc_disp_mgr_get(
601
149
                        (disp_mgr_t *)ps_codec->pv_disp_buf_mgr, &ps_codec->i4_disp_buf_id);
602
        /* In case of non-shared mode, then convert/copy the frame to output buffer */
603
        /* Only if the codec is in non-shared mode or in shared mode but needs 420P output */
604
149
        if((ps_codec->ps_disp_buf)
605
0
                        && ((0 == ps_codec->i4_share_disp_buf)
606
0
                                        || (IV_YUV_420P
607
0
                                                        == ps_codec->e_chroma_fmt)))
608
0
        {
609
610
0
            process_ctxt_t *ps_proc = &ps_codec->as_process[prev_proc_idx];
611
0
            if(0 == ps_proc->i4_init_done)
612
0
            {
613
0
                ihevcd_init_proc_ctxt(ps_proc, 0);
614
0
            }
615
616
            /* Output buffer check */
617
0
            ret = ihevcd_check_out_buf_size(ps_codec);
618
0
            RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
619
620
            /* Set remaining number of rows to be processed */
621
0
            ret = ihevcd_fmt_conv(ps_codec, &ps_codec->as_process[prev_proc_idx],
622
0
                                  ps_dec_ip->s_out_buffer.pu1_bufs[0],
623
0
                                  ps_dec_ip->s_out_buffer.pu1_bufs[1],
624
0
                                  ps_dec_ip->s_out_buffer.pu1_bufs[2], 0,
625
0
                                  ps_codec->i4_disp_ht);
626
627
0
            ihevc_buf_mgr_release((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
628
0
                                  ps_codec->i4_disp_buf_id, BUF_MGR_DISP);
629
0
        }
630
631
149
        ihevcd_fill_outargs(ps_codec, ps_hevcd_dec_ip, ps_hevcd_dec_op);
632
633
149
        if(1 == ps_dec_op->u4_output_present)
634
0
        {
635
0
            WORD32 xpos = ps_codec->i4_disp_wd - 32 - LOGO_WD;
636
0
            WORD32 ypos = ps_codec->i4_disp_ht - 32 - LOGO_HT;
637
638
0
            if(ypos < 0)
639
0
                ypos = 0;
640
641
0
            if(xpos < 0)
642
0
                xpos = 0;
643
644
0
            INSERT_LOGO(ps_dec_ip->s_out_buffer.pu1_bufs[0],
645
0
                        ps_dec_ip->s_out_buffer.pu1_bufs[1],
646
0
                        ps_dec_ip->s_out_buffer.pu1_bufs[2], ps_codec->i4_disp_strd,
647
0
                        xpos,
648
0
                        ypos,
649
0
                        ps_codec->e_chroma_fmt,
650
0
                        ps_codec->i4_disp_wd,
651
0
                        ps_codec->i4_disp_ht);
652
0
        }
653
654
655
149
        if(NULL == ps_codec->ps_disp_buf)
656
149
        {
657
            /* If in flush mode and there are no more buffers to flush,
658
             * check for the reset flag and reset the decoder */
659
149
            if(ps_codec->i4_reset_flag)
660
149
            {
661
149
                ihevcd_init(ps_codec);
662
149
            }
663
149
            return (IV_FAIL);
664
149
        }
665
666
0
        return (IV_SUCCESS);
667
668
149
    }
669
    /* In case of shared mode, check if there is a free buffer for reconstruction */
670
62.2k
    if((0 == ps_codec->i4_header_mode) && (1 == ps_codec->i4_share_disp_buf))
671
0
    {
672
0
        WORD32 buf_status;
673
0
        buf_status = 1;
674
0
        if(ps_codec->pv_pic_buf_mgr)
675
0
            buf_status = ihevc_buf_mgr_check_free((buf_mgr_t *)ps_codec->pv_pic_buf_mgr);
676
677
        /* If there is no free buffer, then return with an error code */
678
0
        if(0 == buf_status)
679
0
        {
680
0
            ps_dec_op->u4_error_code = IVD_DEC_REF_BUF_NULL;
681
0
            ps_dec_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
682
0
            return IV_FAIL;
683
0
        }
684
0
    }
685
62.2k
    ps_codec->i4_bytes_remaining = ps_dec_ip->u4_num_Bytes;
686
62.2k
    ps_codec->pu1_inp_bitsbuf = (UWORD8 *)ps_dec_ip->pv_stream_buffer;
687
62.2k
    ps_codec->s_parse.i4_end_of_frame = 0;
688
689
62.2k
    ps_codec->i4_pic_present = 0;
690
62.2k
    ps_codec->i4_slice_error = 0;
691
62.2k
    ps_codec->ps_disp_buf = NULL;
692
693
62.2k
    if(ps_codec->i4_num_cores > 1)
694
29.8k
    {
695
29.8k
        ithread_set_affinity(0);
696
29.8k
    }
697
137k
    while(MIN_START_CODE_LEN < ps_codec->i4_bytes_remaining)
698
136k
    {
699
136k
        WORD32 nal_len;
700
136k
        WORD32 nal_ofst;
701
136k
        WORD32 bits_len;
702
703
136k
        if(ps_codec->i4_slice_error)
704
2.09k
        {
705
2.09k
            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));
706
2.09k
            WORD32 next_slice_addr = ps_slice_hdr_next->i2_ctb_x +
707
2.09k
                            ps_slice_hdr_next->i2_ctb_y * ps_codec->s_parse.ps_sps->i2_pic_wd_in_ctb;
708
2.09k
            if(ps_codec->s_parse.i4_next_ctb_indx == next_slice_addr)
709
0
                ps_codec->i4_slice_error = 0;
710
2.09k
        }
711
712
136k
        if(ps_codec->pu1_bitsbuf_dynamic)
713
10.7k
        {
714
10.7k
            ps_codec->pu1_bitsbuf = ps_codec->pu1_bitsbuf_dynamic;
715
10.7k
            ps_codec->u4_bitsbuf_size = ps_codec->u4_bitsbuf_size_dynamic;
716
10.7k
        }
717
126k
        else
718
126k
        {
719
126k
            ps_codec->pu1_bitsbuf = ps_codec->pu1_bitsbuf_static;
720
126k
            ps_codec->u4_bitsbuf_size = ps_codec->u4_bitsbuf_size_static;
721
126k
        }
722
723
136k
        nal_ofst = ihevcd_nal_search_start_code(ps_codec->pu1_inp_bitsbuf,
724
136k
                                                ps_codec->i4_bytes_remaining);
725
        /* If there is no start code found, consume the data and break */
726
136k
        if(nal_ofst == ps_codec->i4_bytes_remaining)
727
28
        {
728
28
            ps_codec->pu1_inp_bitsbuf += nal_ofst;
729
28
            ps_codec->i4_bytes_remaining -= nal_ofst;
730
28
            break;
731
28
        }
732
733
136k
        ps_codec->i4_nal_ofst = nal_ofst;
734
136k
        {
735
136k
            WORD32 bytes_remaining = ps_codec->i4_bytes_remaining - nal_ofst;
736
737
136k
            bytes_remaining = MIN((UWORD32)bytes_remaining, ps_codec->u4_bitsbuf_size);
738
136k
            ihevcd_nal_remv_emuln_bytes(ps_codec->pu1_inp_bitsbuf + nal_ofst,
739
136k
                                        ps_codec->pu1_bitsbuf,
740
136k
                                        bytes_remaining,
741
136k
                                        &nal_len, &bits_len);
742
743
            /* Decoder may read upto 8 extra bytes at the end of frame */
744
            /* These are not used, but still set them to zero to avoid uninitialized reads */
745
136k
            if(bits_len < (WORD32)(ps_codec->u4_bitsbuf_size - 8))
746
136k
            {
747
136k
                memset(ps_codec->pu1_bitsbuf + bits_len, 0, 2 * sizeof(UWORD32));
748
136k
            }
749
136k
        }
750
        /* This may be used to update the offsets for tiles and entropy sync row offsets */
751
136k
        ps_codec->i4_num_emln_bytes = nal_len - bits_len;
752
136k
        ps_codec->i4_nal_len = nal_len;
753
754
136k
        ihevcd_bits_init(&ps_codec->s_parse.s_bitstrm, ps_codec->pu1_bitsbuf,
755
136k
                         bits_len);
756
757
136k
        ret = ihevcd_nal_unit(ps_codec);
758
759
        /* If the frame is incomplete and
760
         * the bytes remaining is zero or a header is received,
761
         * complete the frame treating it to be in error */
762
136k
        if(ps_codec->i4_pic_present &&
763
31.4k
                        (ps_codec->s_parse.i4_next_ctb_indx != ps_codec->s_parse.ps_sps->i4_pic_size_in_ctb))
764
21.9k
        {
765
21.9k
            if((ps_codec->i4_bytes_remaining - (nal_len + nal_ofst) <= MIN_START_CODE_LEN) ||
766
21.6k
                            (ps_codec->i4_header_in_slice_mode))
767
1.51k
            {
768
1.51k
                slice_header_t *ps_slice_hdr_next;
769
770
1.51k
                ps_codec->s_parse.i4_cur_slice_idx--;
771
1.51k
                if(ps_codec->s_parse.i4_cur_slice_idx < 0)
772
0
                    ps_codec->s_parse.i4_cur_slice_idx = 0;
773
774
1.51k
                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));
775
1.51k
                ps_slice_hdr_next->i2_ctb_x = 0;
776
1.51k
                ps_slice_hdr_next->i2_ctb_y = ps_codec->s_parse.ps_sps->i2_pic_ht_in_ctb;
777
1.51k
                ps_codec->i4_slice_error = 1;
778
1.51k
                continue;
779
1.51k
            }
780
21.9k
        }
781
782
135k
        if(IHEVCD_IGNORE_SLICE == ret)
783
16.5k
        {
784
16.5k
            ps_codec->pu1_inp_bitsbuf += (nal_ofst + nal_len);
785
16.5k
            ps_codec->i4_bytes_remaining -= (nal_ofst + nal_len);
786
787
16.5k
            continue;
788
16.5k
        }
789
790
118k
        if(IVD_RES_CHANGED == ret)
791
1.53k
        {
792
1.53k
            break;
793
1.53k
        }
794
795
        /* Update bytes remaining and bytes consumed and input bitstream pointer */
796
        /* Do not consume the NAL in the following cases */
797
        /* Slice header reached during header decode mode */
798
        /* TODO: Next picture's slice reached */
799
117k
        if(ret != IHEVCD_SLICE_IN_HEADER_MODE)
800
92.3k
        {
801
92.3k
            if((0 == ps_codec->i4_slice_error) ||
802
38
                            (ps_codec->i4_bytes_remaining - (nal_len + nal_ofst) <= MIN_START_CODE_LEN))
803
92.2k
            {
804
92.2k
                ps_codec->pu1_inp_bitsbuf += (nal_ofst + nal_len);
805
92.2k
                ps_codec->i4_bytes_remaining -= (nal_ofst + nal_len);
806
92.2k
            }
807
92.3k
            if(ret != IHEVCD_SUCCESS)
808
26.0k
                break;
809
810
66.2k
            if(ps_codec->s_parse.i4_end_of_frame)
811
9.52k
                break;
812
66.2k
        }
813
24.9k
        else
814
24.9k
        {
815
24.9k
            ret = IHEVCD_SUCCESS;
816
24.9k
            break;
817
24.9k
        }
818
819
        /* Allocate dynamic bitstream buffer once SPS is decoded */
820
56.7k
        if((ps_codec->u4_allocate_dynamic_done == 0) && ps_codec->i4_sps_done)
821
2.26k
        {
822
2.26k
            WORD32 ret;
823
2.26k
            ret = ihevcd_allocate_dynamic_bufs(ps_codec);
824
2.26k
            if(ret != IV_SUCCESS)
825
0
            {
826
                /* Free any dynamic buffers that are allocated */
827
0
                ihevcd_free_dynamic_bufs(ps_codec);
828
0
                ps_codec->i4_error_code = IVD_MEM_ALLOC_FAILED;
829
0
                ps_dec_op->u4_error_code = 1 << IVD_FATALERROR;
830
0
                ps_dec_op->u4_error_code |= IVD_MEM_ALLOC_FAILED;
831
832
0
                return IV_FAIL;
833
0
            }
834
2.26k
        }
835
836
56.7k
        BREAK_AFTER_SLICE_NAL();
837
56.7k
    }
838
839
62.2k
    if(1 == ps_codec->i4_pic_present && 0 == ps_codec->s_parse.i4_end_of_frame)
840
1.40k
    {
841
1.40k
        slice_header_t *ps_slice_hdr_next;
842
1.40k
        ps_codec->i4_slice_error = 1;
843
1.40k
        ps_codec->s_parse.i4_cur_slice_idx--;
844
1.40k
        if(ps_codec->s_parse.i4_cur_slice_idx < 0)
845
0
            ps_codec->s_parse.i4_cur_slice_idx = 0;
846
847
1.40k
        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));
848
1.40k
        ps_slice_hdr_next->i2_ctb_x = -1;
849
1.40k
        ps_slice_hdr_next->i2_ctb_y = -1;
850
851
1.40k
        ihevcd_parse_slice_data(ps_codec);
852
1.40k
        ASSERT(ps_codec->s_parse.i4_end_of_frame != 0);
853
1.40k
    }
854
855
62.2k
    if(1 == ps_codec->i4_pic_present)
856
10.9k
    {
857
10.9k
        WORD32 i;
858
10.9k
        sps_t *ps_sps = ps_codec->s_parse.ps_sps;
859
10.9k
        ps_codec->i4_first_pic_done = 1;
860
861
        /*TODO temporary fix: end_of_frame is checked before adding format conversion to job queue         */
862
10.9k
        if(ps_codec->i4_num_cores > 1 && ps_codec->s_parse.i4_end_of_frame)
863
4.95k
        {
864
865
            /* Add job queue for format conversion / frame copy for each ctb row */
866
            /* Only if the codec is in non-shared mode or in shared mode but needs 420P output */
867
4.95k
            process_ctxt_t *ps_proc;
868
869
            /* i4_num_cores - 1 contexts are currently being used by other threads */
870
4.95k
            ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1];
871
872
4.95k
            if((ps_codec->ps_disp_buf) &&
873
4.20k
               ((0 == ps_codec->i4_share_disp_buf) || (IV_YUV_420P == ps_codec->e_chroma_fmt)))
874
4.20k
            {
875
                /* If format conversion jobs were not issued in pic_init() add them here */
876
4.20k
                if((0 == ps_codec->u4_enable_fmt_conv_ahead) ||
877
0
                                (ps_codec->i4_disp_buf_id == ps_proc->i4_cur_pic_buf_id))
878
43.8k
                    for(i = 0; i < ps_sps->i2_pic_ht_in_ctb; i++)
879
39.6k
                    {
880
39.6k
                        proc_job_t s_job;
881
39.6k
                        IHEVCD_ERROR_T ret;
882
39.6k
                        s_job.i4_cmd = CMD_FMTCONV;
883
39.6k
                        s_job.i2_ctb_cnt = 0;
884
39.6k
                        s_job.i2_ctb_x = 0;
885
39.6k
                        s_job.i2_ctb_y = i;
886
39.6k
                        s_job.i2_slice_idx = 0;
887
39.6k
                        s_job.i4_tu_coeff_data_ofst = 0;
888
39.6k
                        ret = ihevcd_jobq_queue((jobq_t *)ps_codec->s_parse.pv_proc_jobq,
889
39.6k
                                                &s_job, sizeof(proc_job_t), 1);
890
39.6k
                        if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
891
0
                            return (WORD32)ret;
892
39.6k
                    }
893
4.20k
            }
894
            /* Reached end of frame : Signal terminate */
895
            /* The terminate flag is checked only after all the jobs are dequeued */
896
4.95k
            ret = ihevcd_jobq_terminate((jobq_t *)ps_codec->s_parse.pv_proc_jobq);
897
898
33.4k
            while(1)
899
33.4k
            {
900
33.4k
                IHEVCD_ERROR_T ret;
901
33.4k
                proc_job_t s_job;
902
33.4k
                process_ctxt_t *ps_proc;
903
904
                /* i4_num_cores - 1 contexts are currently being used by other threads */
905
33.4k
                ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1];
906
907
33.4k
                ret = ihevcd_jobq_dequeue((jobq_t *)ps_proc->pv_proc_jobq, &s_job,
908
33.4k
                                          sizeof(proc_job_t), 1);
909
33.4k
                if((IHEVCD_ERROR_T)IHEVCD_SUCCESS != ret)
910
4.95k
                    break;
911
912
28.4k
                ps_proc->i4_ctb_cnt = s_job.i2_ctb_cnt;
913
28.4k
                ps_proc->i4_ctb_x = s_job.i2_ctb_x;
914
28.4k
                ps_proc->i4_ctb_y = s_job.i2_ctb_y;
915
28.4k
                ps_proc->i4_cur_slice_idx = s_job.i2_slice_idx;
916
917
28.4k
                if(CMD_PROCESS == s_job.i4_cmd)
918
14.4k
                {
919
14.4k
                    ihevcd_init_proc_ctxt(ps_proc, s_job.i4_tu_coeff_data_ofst);
920
921
14.4k
                    ihevcd_process(ps_proc);
922
14.4k
                }
923
13.9k
                else if(CMD_FMTCONV == s_job.i4_cmd)
924
13.9k
                {
925
13.9k
                    sps_t *ps_sps = ps_codec->s_parse.ps_sps;
926
13.9k
                    WORD32 num_rows = 1 << ps_sps->i1_log2_ctb_size;
927
13.9k
                    if(0 == ps_proc->i4_init_done)
928
442
                    {
929
442
                        ihevcd_init_proc_ctxt(ps_proc, 0);
930
442
                    }
931
932
13.9k
                    num_rows = MIN(num_rows, (ps_codec->i4_disp_ht - (s_job.i2_ctb_y << ps_sps->i1_log2_ctb_size)));
933
13.9k
                    if(num_rows < 0)
934
0
                        num_rows = 0;
935
936
13.9k
                    ihevcd_fmt_conv(ps_codec, ps_proc,
937
13.9k
                                    ps_dec_ip->s_out_buffer.pu1_bufs[0],
938
13.9k
                                    ps_dec_ip->s_out_buffer.pu1_bufs[1],
939
13.9k
                                    ps_dec_ip->s_out_buffer.pu1_bufs[2],
940
13.9k
                                    s_job.i2_ctb_y << ps_sps->i1_log2_ctb_size,
941
13.9k
                                    num_rows);
942
13.9k
                }
943
28.4k
            }
944
4.95k
        }
945
        /* In case of non-shared mode and while running in single core mode, then convert/copy the frame to output buffer */
946
        /* Only if the codec is in non-shared mode or in shared mode but needs 420P output */
947
5.96k
        else if((ps_codec->ps_disp_buf) && ((0 == ps_codec->i4_share_disp_buf) ||
948
0
                                            (IV_YUV_420P == ps_codec->e_chroma_fmt)) &&
949
5.26k
                        (ps_codec->s_parse.i4_end_of_frame))
950
5.26k
        {
951
5.26k
            process_ctxt_t *ps_proc = &ps_codec->as_process[proc_idx];
952
            /* Set remaining number of rows to be processed */
953
5.26k
            ps_codec->s_fmt_conv.i4_num_rows = ps_codec->i4_disp_ht
954
5.26k
                            - ps_codec->s_fmt_conv.i4_cur_row;
955
5.26k
            if(0 == ps_proc->i4_init_done)
956
0
            {
957
0
                ihevcd_init_proc_ctxt(ps_proc, 0);
958
0
            }
959
960
5.26k
            if(ps_codec->s_fmt_conv.i4_num_rows < 0)
961
0
                ps_codec->s_fmt_conv.i4_num_rows = 0;
962
963
5.26k
            ret = ihevcd_fmt_conv(ps_codec, ps_proc,
964
5.26k
                                  ps_dec_ip->s_out_buffer.pu1_bufs[0],
965
5.26k
                                  ps_dec_ip->s_out_buffer.pu1_bufs[1],
966
5.26k
                                  ps_dec_ip->s_out_buffer.pu1_bufs[2],
967
5.26k
                                  ps_codec->s_fmt_conv.i4_cur_row,
968
5.26k
                                  ps_codec->s_fmt_conv.i4_num_rows);
969
5.26k
            ps_codec->s_fmt_conv.i4_cur_row += ps_codec->s_fmt_conv.i4_num_rows;
970
971
5.26k
        }
972
973
974
10.9k
        DEBUG_DUMP_MV_MAP(ps_codec);
975
976
        /* Mark MV Buf as needed for reference */
977
10.9k
        ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_mv_buf_mgr,
978
10.9k
                                 ps_codec->as_process[proc_idx].i4_cur_mv_bank_buf_id,
979
10.9k
                                 BUF_MGR_REF);
980
981
        /* Mark pic buf as needed for reference */
982
10.9k
        ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
983
10.9k
                                 ps_codec->as_process[proc_idx].i4_cur_pic_buf_id,
984
10.9k
                                 BUF_MGR_REF);
985
986
        /* Mark pic buf as needed for display */
987
10.9k
        ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
988
10.9k
                                 ps_codec->as_process[proc_idx].i4_cur_pic_buf_id,
989
10.9k
                                 BUF_MGR_DISP);
990
991
        /* Insert the current picture as short term reference */
992
10.9k
        ihevc_dpb_mgr_insert_ref((dpb_mgr_t *)ps_codec->pv_dpb_mgr,
993
10.9k
                                 ps_codec->as_process[proc_idx].ps_cur_pic,
994
10.9k
                                 ps_codec->as_process[proc_idx].i4_cur_pic_buf_id);
995
996
        /* If a frame was displayed (in non-shared mode), then release it from display manager */
997
10.9k
        if((0 == ps_codec->i4_share_disp_buf) && (ps_codec->ps_disp_buf))
998
9.46k
            ihevc_buf_mgr_release((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
999
9.46k
                                  ps_codec->i4_disp_buf_id, BUF_MGR_DISP);
1000
1001
        /* Wait for threads */
1002
21.1k
        for(i = 0; i < (ps_codec->i4_num_cores - 1); i++)
1003
10.2k
        {
1004
10.2k
            if(ps_codec->ai4_process_thread_created[i])
1005
10.2k
            {
1006
10.2k
                if(ps_codec->i4_threads_active)
1007
10.2k
                {
1008
10.2k
                    ret = ithread_mutex_lock(ps_codec->apv_proc_done_mutex[i]);
1009
10.2k
                    RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
1010
1011
13.6k
                    while(!ps_codec->ai4_process_done[i])
1012
3.43k
                    {
1013
3.43k
                        ithread_cond_wait(ps_codec->apv_proc_done_condition[i],
1014
3.43k
                                          ps_codec->apv_proc_done_mutex[i]);
1015
3.43k
                    }
1016
10.2k
                    ps_codec->ai4_process_done[i] = 0;
1017
10.2k
                    ret = ithread_mutex_unlock(ps_codec->apv_proc_done_mutex[i]);
1018
10.2k
                    RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
1019
10.2k
                }
1020
0
                else
1021
0
                {
1022
0
                    ithread_join(ps_codec->apv_process_thread_handle[i], NULL);
1023
0
                    ps_codec->ai4_process_thread_created[i] = 0;
1024
0
                }
1025
10.2k
            }
1026
10.2k
        }
1027
1028
10.9k
        DEBUG_VALIDATE_PADDED_REGION(&ps_codec->as_process[proc_idx]);
1029
10.9k
        if(ps_codec->u4_pic_cnt > 0)
1030
9.32k
        {
1031
9.32k
            DEBUG_DUMP_PIC_PU(ps_codec);
1032
9.32k
        }
1033
10.9k
        DEBUG_DUMP_PIC_BUFFERS(ps_codec);
1034
1035
        /* Increment the number of pictures decoded */
1036
10.9k
        ps_codec->u4_pic_cnt++;
1037
10.9k
    }
1038
62.2k
    ihevcd_fill_outargs(ps_codec, ps_hevcd_dec_ip, ps_hevcd_dec_op);
1039
1040
62.2k
    if(1 == ps_dec_op->u4_output_present)
1041
9.46k
    {
1042
9.46k
        WORD32 xpos = ps_codec->i4_disp_wd - 32 - LOGO_WD;
1043
9.46k
        WORD32 ypos = ps_codec->i4_disp_ht - 32 - LOGO_HT;
1044
1045
9.46k
        if(ypos < 0)
1046
1.42k
            ypos = 0;
1047
1048
9.46k
        if(xpos < 0)
1049
1.92k
            xpos = 0;
1050
1051
9.46k
        INSERT_LOGO(ps_dec_ip->s_out_buffer.pu1_bufs[0],
1052
9.46k
                    ps_dec_ip->s_out_buffer.pu1_bufs[1],
1053
9.46k
                    ps_dec_ip->s_out_buffer.pu1_bufs[2], ps_codec->i4_disp_strd,
1054
9.46k
                    xpos,
1055
9.46k
                    ypos,
1056
9.46k
                    ps_codec->e_chroma_fmt,
1057
9.46k
                    ps_codec->i4_disp_wd,
1058
9.46k
                    ps_codec->i4_disp_ht);
1059
9.46k
    }
1060
1061
1062
62.2k
    return ret;
1063
62.2k
}
1064