Coverage Report

Created: 2026-10-17 06:46

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