Coverage Report

Created: 2026-03-20 07:09

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