Coverage Report

Created: 2026-02-26 07:08

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libhevc/decoder/ihevcd_utils.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_utils.c
22
*
23
* @brief
24
*  Contains miscellaneous utility functions such as init() etc
25
*
26
* @author
27
*  Harish
28
*
29
* @par List of Functions:
30
*
31
* @remarks
32
*  None
33
*
34
*******************************************************************************
35
*/
36
/*****************************************************************************/
37
/* File Includes                                                             */
38
/*****************************************************************************/
39
#include <stdio.h>
40
#include <stddef.h>
41
#include <stdlib.h>
42
#include <string.h>
43
#include <assert.h>
44
45
#include "ihevc_typedefs.h"
46
#include "iv.h"
47
#include "ivd.h"
48
#include "ihevcd_cxa.h"
49
#include "ithread.h"
50
51
#include "ihevc_defs.h"
52
#include "ihevc_debug.h"
53
#include "ihevc_defs.h"
54
#include "ihevc_error.h"
55
#include "ihevc_structs.h"
56
#include "ihevc_buf_mgr.h"
57
#include "ihevc_dpb_mgr.h"
58
#include "ihevc_macros.h"
59
#include "ihevc_platform_macros.h"
60
61
#include "ihevc_common_tables.h"
62
#include "ihevc_buf_mgr.h"
63
#include "ihevc_disp_mgr.h"
64
#include "ihevc_cabac_tables.h"
65
66
#include "ihevcd_defs.h"
67
68
#include "ihevcd_function_selector.h"
69
#include "ihevcd_structs.h"
70
#include "ihevcd_error.h"
71
#include "ihevcd_nal.h"
72
#include "ihevcd_bitstream.h"
73
#include "ihevcd_utils.h"
74
#include "ihevcd_trace.h"
75
#include "ihevcd_process_slice.h"
76
#include "ihevcd_job_queue.h"
77
#define MAX_DPB_PIC_BUF 6
78
79
/* Function declarations */
80
mv_buf_t* ihevcd_mv_mgr_get_poc(buf_mgr_t *ps_mv_buf_mgr, UWORD32 abs_poc);
81
82
/**
83
*******************************************************************************
84
*
85
* @brief
86
*  Used to get level index for a given level
87
*
88
* @par Description:
89
*  Converts from level_idc (which is multiplied by 30) to an index that can be
90
*  used as a lookup. Also used to ignore invalid levels like 2.2 , 3.2 etc
91
*
92
* @param[in] level
93
*  Level of the stream
94
*
95
* @returns  Level index for a given level
96
*
97
* @remarks
98
*
99
*
100
*******************************************************************************
101
*/
102
WORD32 ihevcd_get_lvl_idx(WORD32 level)
103
0
{
104
0
    WORD32 lvl_idx = 0;
105
106
0
    if(level < IHEVC_LEVEL_20)
107
0
    {
108
0
        lvl_idx = 0;
109
0
    }
110
0
    else if(level >= IHEVC_LEVEL_20 && level < IHEVC_LEVEL_21)
111
0
    {
112
0
        lvl_idx = 1;
113
0
    }
114
0
    else if(level >= IHEVC_LEVEL_21 && level < IHEVC_LEVEL_30)
115
0
    {
116
0
        lvl_idx = 2;
117
0
    }
118
0
    else if(level >= IHEVC_LEVEL_30 && level < IHEVC_LEVEL_31)
119
0
    {
120
0
        lvl_idx = 3;
121
0
    }
122
0
    else if(level >= IHEVC_LEVEL_31 && level < IHEVC_LEVEL_40)
123
0
    {
124
0
        lvl_idx = 4;
125
0
    }
126
0
    else if(level >= IHEVC_LEVEL_40 && level < IHEVC_LEVEL_41)
127
0
    {
128
0
        lvl_idx = 5;
129
0
    }
130
0
    else if(level >= IHEVC_LEVEL_41 && level < IHEVC_LEVEL_50)
131
0
    {
132
0
        lvl_idx = 6;
133
0
    }
134
0
    else if(level >= IHEVC_LEVEL_50 && level < IHEVC_LEVEL_51)
135
0
    {
136
0
        lvl_idx = 7;
137
0
    }
138
0
    else if(level >= IHEVC_LEVEL_51 && level < IHEVC_LEVEL_52)
139
0
    {
140
0
        lvl_idx = 8;
141
0
    }
142
0
    else if(level >= IHEVC_LEVEL_52 && level < IHEVC_LEVEL_60)
143
0
    {
144
0
        lvl_idx = 9;
145
0
    }
146
0
    else if(level >= IHEVC_LEVEL_60 && level < IHEVC_LEVEL_61)
147
0
    {
148
0
        lvl_idx = 10;
149
0
    }
150
0
    else if(level >= IHEVC_LEVEL_61 && level < IHEVC_LEVEL_62)
151
0
    {
152
0
        lvl_idx = 11;
153
0
    }
154
0
    else if(level >= IHEVC_LEVEL_62)
155
0
    {
156
0
        lvl_idx = 12;
157
0
    }
158
159
0
    return (lvl_idx);
160
0
}
161
162
/**
163
*******************************************************************************
164
*
165
* @brief
166
*  Used to get reference picture buffer size for a given level and
167
*  and padding used
168
*
169
* @par Description:
170
*  Used to get reference picture buffer size for a given level and padding used
171
*  Each picture is padded on all four sides
172
*
173
* @param[in] pic_size
174
*  Mumber of luma samples (Width * Height)
175
*
176
* @param[in] level
177
*  Level
178
*
179
* @param[in] horz_pad
180
*  Total padding used in horizontal direction
181
*
182
* @param[in] vert_pad
183
*  Total padding used in vertical direction
184
*
185
* @returns  Total picture buffer size
186
*
187
* @remarks
188
*
189
*
190
*******************************************************************************
191
*/
192
WORD32 ihevcd_get_total_pic_buf_size(codec_t *ps_codec,
193
                                     WORD32 wd,
194
                                     WORD32 ht)
195
2.26k
{
196
2.26k
    WORD32 size;
197
2.26k
    WORD32 num_luma_samples;
198
2.26k
    WORD32 max_dpb_size;
199
2.26k
    WORD32 num_samples;
200
201
202
2.26k
    sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id);
203
204
    /* Get maximum number of buffers for the current picture size */
205
2.26k
    max_dpb_size = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1];
206
207
2.26k
    if(ps_codec->e_frm_out_mode != IVD_DECODE_FRAME_OUT)
208
2.26k
        max_dpb_size += ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1];
209
210
2.26k
    max_dpb_size++;
211
    /* Allocation is required for
212
     * (Wd + horz_pad) * (Ht + vert_pad) * (2 * max_dpb_size + 1)
213
     */
214
215
    /* Account for padding area */
216
2.26k
    num_luma_samples = (wd + PAD_WD) * (ht + PAD_HT);
217
218
    /* Account for chroma */
219
2.26k
    if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV444)
220
0
    {
221
0
        num_samples = num_luma_samples * 3;
222
0
    }
223
2.26k
    else if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422)
224
0
    {
225
0
        num_samples = num_luma_samples * 2;
226
0
    }
227
2.26k
    else if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV420)
228
2.26k
    {
229
2.26k
        num_samples = num_luma_samples * 3 / 2;
230
2.26k
    }
231
0
    else
232
0
    {
233
0
        num_samples = num_luma_samples;
234
0
    }
235
236
    /* Number of bytes in reference pictures */
237
2.26k
    size = num_samples * max_dpb_size;
238
239
240
2.26k
    return size;
241
2.26k
}
242
/**
243
*******************************************************************************
244
*
245
* @brief
246
*  Used to get MV bank size for a given number of luma samples
247
*
248
* @par Description:
249
*  For given number of luma samples  one MV bank size is computed
250
*  Each MV bank includes pu_map and pu_t for all the min PUs(4x4) in a picture
251
*
252
* @param[in] num_luma_samples
253
*  Max number of luma pixels in the frame
254
*
255
* @returns  Total MV Bank size
256
*
257
* @remarks
258
*
259
*
260
*******************************************************************************
261
*/
262
WORD32 ihevcd_get_pic_mv_bank_size(WORD32 num_luma_samples)
263
4.15k
{
264
4.15k
    WORD32 size;
265
266
4.15k
    WORD32 pic_size;
267
268
4.15k
    WORD32 mv_bank_size;
269
4.15k
    WORD32 num_pu;
270
4.15k
    WORD32 num_ctb;
271
4.15k
    pic_size = num_luma_samples;
272
273
274
4.15k
    num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE);
275
4.15k
    num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);
276
277
4.15k
    mv_bank_size = 0;
278
279
    /* Size for storing pu_t start index each CTB */
280
    /* One extra entry is needed to compute number of PUs in the last CTB */
281
4.15k
    mv_bank_size += (num_ctb + 1) * sizeof(WORD32);
282
283
    /* Size for pu_map */
284
4.15k
    mv_bank_size += num_pu;
285
286
    /* Size for storing pu_t for each PU */
287
4.15k
    mv_bank_size += num_pu * sizeof(pu_t);
288
289
    /* Size for storing slice_idx for each CTB */
290
4.15k
    mv_bank_size += ALIGN4(num_ctb * sizeof(UWORD16));
291
292
4.15k
    size =  mv_bank_size;
293
4.15k
    return size;
294
4.15k
}
295
/**
296
*******************************************************************************
297
*
298
* @brief
299
*  Used to get TU data size for a given number luma samples
300
*
301
* @par Description:
302
*  For a given number of luma samples TU data size is computed
303
*  Each TU data includes tu_map and tu_t and coeff data for all
304
*  the min TUs(4x4) in given CTB
305
*
306
* @param[in] num_luma_samples
307
*  Number of 64 x 64 CTBs for which TU data has to be allocated.
308
*
309
* @returns  Total TU data size
310
*
311
* @remarks Assumption is num_luma_samples will be at least
312
* 64 x 64 to handle CTB of size 64 x 64. Can be frame size as well
313
*
314
*******************************************************************************
315
*/
316
WORD32 ihevcd_get_tu_data_size(codec_t *ps_codec, WORD32 num_luma_samples)
317
2.26k
{
318
319
2.26k
    sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id);
320
2.26k
    WORD32 tu_data_size;
321
2.26k
    WORD32 num_ctb;
322
2.26k
    WORD32 num_luma_tu, num_chroma_tu, num_tu;
323
2.26k
    num_ctb = num_luma_samples / (MIN_CTB_SIZE * MIN_CTB_SIZE);
324
325
2.26k
    num_luma_tu = num_luma_samples / (MIN_TU_SIZE * MIN_TU_SIZE);
326
327
2.26k
    if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV444)
328
0
    {
329
0
        num_chroma_tu = num_luma_tu << 1;
330
0
    }
331
2.26k
    else if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422)
332
0
    {
333
0
        num_chroma_tu = num_luma_tu;
334
0
    }
335
2.26k
    else if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV420)
336
2.26k
    {
337
2.26k
        num_chroma_tu = num_luma_tu >> 1;
338
2.26k
    }
339
0
    else
340
0
    {
341
0
        num_chroma_tu = 0;
342
0
    }
343
344
2.26k
    num_tu = num_luma_tu + num_chroma_tu;
345
2.26k
    tu_data_size = 0;
346
347
    /* Size for storing tu_t start index each CTB */
348
    /* One extra entry is needed to compute number of TUs in the last CTB */
349
2.26k
    tu_data_size += (num_ctb + 1) * sizeof(WORD32);
350
351
    /* Size for storing tu map */
352
2.26k
    tu_data_size += num_luma_tu * sizeof(UWORD8);
353
354
    /* Size for storing tu_t for each TU */
355
2.26k
    tu_data_size += num_tu * sizeof(tu_t);
356
357
    /* Size for storing number of coded subblocks and scan_idx for each TU */
358
2.26k
    tu_data_size += num_tu * (sizeof(WORD8) + sizeof(WORD8));
359
360
    /* Size for storing coeff data for each TU */
361
2.26k
    tu_data_size += num_tu * sizeof(tu_sblk_coeff_data_t);
362
363
364
2.26k
    return tu_data_size;
365
2.26k
}
366
367
368
WORD32 ihevcd_nctb_cnt(codec_t *ps_codec, sps_t *ps_sps)
369
10.9k
{
370
10.9k
    WORD32 nctb = 1;
371
10.9k
    UNUSED(ps_codec);
372
    //TODO: Currently set to 1
373
    /* If CTB size is less than 32 x 32 then set nCTB as 4 */
374
10.9k
    if(ps_sps->i1_log2_ctb_size < 5)
375
506
        nctb = 1;
376
377
10.9k
    return nctb;
378
10.9k
}
379
380
IHEVCD_ERROR_T ihevcd_get_tile_pos(pps_t *ps_pps,
381
                                   sps_t *ps_sps,
382
                                   WORD32 ctb_x,
383
                                   WORD32 ctb_y,
384
                                   WORD32 *pi4_ctb_tile_x,
385
                                   WORD32 *pi4_ctb_tile_y,
386
                                   WORD32 *pi4_tile_idx)
387
269k
{
388
389
269k
    tile_t *ps_tile_tmp;
390
269k
    WORD32 i;
391
269k
    WORD32 tile_row, tile_col;
392
393
269k
    if(ctb_x < 0 || ctb_y < 0)
394
0
    {
395
0
        *pi4_ctb_tile_x = 0;
396
0
        *pi4_ctb_tile_y = 0;
397
0
        *pi4_tile_idx = 0;
398
399
0
        return (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
400
0
    }
401
402
269k
    tile_row = 0;
403
269k
    tile_col = 0;
404
269k
    ps_tile_tmp = ps_pps->ps_tile;
405
269k
    if(0 == ps_pps->i1_tiles_enabled_flag)
406
151k
    {
407
151k
        *pi4_ctb_tile_x = ctb_x;
408
151k
        *pi4_ctb_tile_y = ctb_y;
409
151k
        *pi4_tile_idx = 0;
410
151k
    }
411
117k
    else
412
117k
    {
413
230k
        for(i = 0; i < ps_pps->i1_num_tile_columns; i++)
414
230k
        {
415
230k
            WORD16 next_tile_ctb_x;
416
230k
            ps_tile_tmp = ps_pps->ps_tile + i; //* ps_pps->i1_num_tile_rows;
417
230k
            if((ps_pps->i1_num_tile_columns - 1) == i)
418
44.8k
            {
419
44.8k
                next_tile_ctb_x = ps_sps->i2_pic_wd_in_ctb;
420
44.8k
            }
421
185k
            else
422
185k
            {
423
185k
                tile_t *ps_tile_next_tmp;
424
185k
                ps_tile_next_tmp = ps_pps->ps_tile + i + 1;
425
185k
                next_tile_ctb_x = ps_tile_next_tmp->u1_pos_x;
426
185k
            }
427
230k
            if((ctb_x >= ps_tile_tmp->u1_pos_x) && (ctb_x < next_tile_ctb_x))
428
117k
            {
429
117k
                tile_col = i;
430
117k
                break;
431
117k
            }
432
230k
        }
433
117k
        *pi4_ctb_tile_x = ctb_x - ps_tile_tmp->u1_pos_x;
434
435
229k
        for(i = 0; i < ps_pps->i1_num_tile_rows; i++)
436
229k
        {
437
229k
            WORD16 next_tile_ctb_y;
438
229k
            ps_tile_tmp = ps_pps->ps_tile + i * ps_pps->i1_num_tile_columns;
439
229k
            if((ps_pps->i1_num_tile_rows - 1) == i)
440
47.8k
            {
441
47.8k
                next_tile_ctb_y = ps_sps->i2_pic_ht_in_ctb;
442
47.8k
            }
443
181k
            else
444
181k
            {
445
181k
                tile_t *ps_tile_next_tmp;
446
181k
                ps_tile_next_tmp = ps_pps->ps_tile + ((i + 1) * ps_pps->i1_num_tile_columns);
447
181k
                next_tile_ctb_y = ps_tile_next_tmp->u1_pos_y;
448
181k
            }
449
229k
            if((ctb_y >= ps_tile_tmp->u1_pos_y) && (ctb_y < next_tile_ctb_y))
450
117k
            {
451
117k
                tile_row = i;
452
117k
                break;
453
117k
            }
454
455
229k
        }
456
117k
        *pi4_ctb_tile_y = ctb_y - ps_tile_tmp->u1_pos_y;
457
117k
        *pi4_tile_idx = tile_row * ps_pps->i1_num_tile_columns
458
117k
                        + tile_col;
459
117k
    }
460
269k
    return (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
461
269k
}
462
/**
463
*******************************************************************************
464
*
465
* @brief
466
*  Function to initialize ps_pic_buf structs add pic buffers to
467
*  buffer manager in case of non-shared mode
468
*
469
* @par Description:
470
*  Function to initialize ps_pic_buf structs add pic buffers to
471
*  buffer manager in case of non-shared mode
472
*  To be called once per stream or for every reset
473
*
474
* @param[in] ps_codec
475
*  Pointer to codec context
476
*
477
* @returns  Error from IHEVCD_ERROR_T
478
*
479
* @remarks
480
*
481
*
482
*******************************************************************************
483
*/
484
IHEVCD_ERROR_T ihevcd_pic_buf_mgr_add_bufs(codec_t *ps_codec)
485
1.89k
{
486
1.89k
    IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
487
1.89k
    WORD32 i;
488
1.89k
    WORD32 max_dpb_size;
489
1.89k
    sps_t *ps_sps;
490
1.89k
    UWORD8 *pu1_buf;
491
1.89k
    pic_buf_t *ps_pic_buf;
492
1.89k
    WORD32 pic_buf_size_allocated;
493
1.89k
    WORD32 h_samp_factor, v_samp_factor;
494
1.89k
    WORD32 chroma_pixel_strd = 2;
495
496
497
    /* Initialize Pic buffer manager */
498
1.89k
    ps_sps = ps_codec->s_parse.ps_sps;
499
500
1.89k
    h_samp_factor = (CHROMA_FMT_IDC_YUV444 == ps_sps->i1_chroma_format_idc) ? 1 : 2;
501
1.89k
    v_samp_factor = (CHROMA_FMT_IDC_YUV420 == ps_sps->i1_chroma_format_idc) ? 2 : 1;
502
503
    /* Compute the number of Pic buffers needed */
504
1.89k
    max_dpb_size = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1];
505
506
1.89k
    if(ps_codec->e_frm_out_mode != IVD_DECODE_FRAME_OUT)
507
1.89k
        max_dpb_size += ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1];
508
509
    /* Allocate one extra picture to handle current frame
510
     * In case of asynchronous parsing and processing, number of buffers should increase here
511
     * based on when parsing and processing threads are synchronized
512
     */
513
1.89k
    max_dpb_size++;
514
515
516
1.89k
    pu1_buf = (UWORD8 *)ps_codec->pu1_ref_pic_buf_base;
517
518
1.89k
    ps_pic_buf = (pic_buf_t *)ps_codec->ps_pic_buf;
519
520
    /* In case of non-shared mode, add picture buffers to buffer manager
521
     * In case of shared mode buffers are added in the run-time
522
     */
523
1.89k
    if(0 == ps_codec->i4_share_disp_buf)
524
1.89k
    {
525
1.89k
        WORD32 buf_ret;
526
1.89k
        WORD32 luma_samples;
527
1.89k
        WORD32 chroma_samples;
528
1.89k
        pic_buf_size_allocated = ps_codec->i4_total_pic_buf_size;
529
530
1.89k
        luma_samples = (ps_codec->i4_strd) *
531
1.89k
                        (ps_sps->i2_pic_height_in_luma_samples + PAD_HT);
532
533
1.89k
        if(CHROMA_FMT_IDC_MONOCHROME == ps_sps->i1_chroma_format_idc)
534
0
        {
535
0
            chroma_samples = 0;
536
0
        }
537
1.89k
        else
538
1.89k
        {
539
1.89k
            chroma_samples = luma_samples * 2 / (h_samp_factor * v_samp_factor);
540
1.89k
        }
541
542
        /* Try to add as many buffers as possible since memory is already allocated */
543
        /* If the number of buffers that can be added is less than max_num_bufs
544
         * return with an error.
545
         */
546
19.1k
        for(i = 0; i < max_dpb_size; i++)
547
17.2k
        {
548
17.2k
            pic_buf_size_allocated -= (luma_samples + chroma_samples);
549
550
17.2k
            if(pic_buf_size_allocated < 0)
551
0
            {
552
0
                ps_codec->s_parse.i4_error_code = IHEVCD_INSUFFICIENT_MEM_PICBUF;
553
0
                return IHEVCD_INSUFFICIENT_MEM_PICBUF;
554
0
            }
555
556
17.2k
            ps_pic_buf->pu1_luma = pu1_buf + ps_codec->i4_strd * PAD_TOP + PAD_LEFT;
557
17.2k
            pu1_buf += luma_samples;
558
559
17.2k
            if(chroma_samples)
560
17.2k
            {
561
17.2k
                ps_pic_buf->pu1_chroma = pu1_buf
562
17.2k
                                + (ps_codec->i4_strd * chroma_pixel_strd / h_samp_factor) * (PAD_TOP / v_samp_factor)
563
17.2k
                                + (PAD_LEFT * chroma_pixel_strd / h_samp_factor);
564
17.2k
                pu1_buf += chroma_samples;
565
17.2k
            }
566
0
            else
567
0
            {
568
0
                ps_pic_buf->pu1_chroma = NULL;
569
0
            }
570
571
            /* Pad boundary pixels (one pixel on all sides) */
572
            /* This ensures SAO does not read uninitialized pixels */
573
            /* Note these are not used in actual processing */
574
17.2k
            {
575
17.2k
                UWORD8 *pu1_buf;
576
17.2k
                WORD32 strd, wd, ht;
577
17.2k
                WORD32 i;
578
17.2k
                strd = ps_codec->i4_strd;
579
17.2k
                wd = ps_codec->i4_wd;
580
17.2k
                ht = ps_codec->i4_ht;
581
582
17.2k
                pu1_buf = ps_pic_buf->pu1_luma;
583
3.48M
                for(i = 0; i < ht; i++)
584
3.47M
                {
585
3.47M
                    pu1_buf[-1] = 0;
586
3.47M
                    pu1_buf[wd] = 0;
587
3.47M
                    pu1_buf += strd;
588
3.47M
                }
589
17.2k
                pu1_buf = ps_pic_buf->pu1_luma;
590
17.2k
                memset(pu1_buf - strd - 1, 0, wd + 2);
591
592
17.2k
                pu1_buf += strd * ht;
593
17.2k
                memset(pu1_buf - 1, 0, wd + 2);
594
595
17.2k
                if(ps_pic_buf->pu1_chroma)
596
17.2k
                {
597
17.2k
                    pu1_buf = ps_pic_buf->pu1_chroma;
598
17.2k
                    ht /= v_samp_factor;
599
17.2k
                    WORD32 chroma_strd_scale = chroma_pixel_strd / h_samp_factor;
600
1.75M
                    for(i = 0; i < ht; i++)
601
1.73M
                    {
602
1.73M
                        pu1_buf[-1] = 0;
603
1.73M
                        pu1_buf[-2] = 0;
604
1.73M
                        pu1_buf[wd * chroma_strd_scale] = 0;
605
1.73M
                        pu1_buf[wd * chroma_strd_scale + 1] = 0;
606
1.73M
                        pu1_buf += (strd * chroma_strd_scale);
607
1.73M
                    }
608
17.2k
                    pu1_buf = ps_pic_buf->pu1_chroma;
609
17.2k
                    memset(pu1_buf - (strd * chroma_strd_scale) - 2, 0, wd * chroma_strd_scale + 4);
610
611
17.2k
                    pu1_buf += (strd * chroma_strd_scale) * ht;
612
17.2k
                    memset(pu1_buf - 2, 0, wd * chroma_strd_scale + 4);
613
17.2k
                }
614
17.2k
            }
615
616
17.2k
            buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, ps_pic_buf, i);
617
618
619
17.2k
            if(0 != buf_ret)
620
0
            {
621
0
                ps_codec->s_parse.i4_error_code = IHEVCD_BUF_MGR_ERROR;
622
0
                return IHEVCD_BUF_MGR_ERROR;
623
0
            }
624
17.2k
            ps_pic_buf++;
625
17.2k
        }
626
1.89k
    }
627
0
    else
628
0
    {
629
        /* In case of shared mode, buffers are added without adjusting for padding.
630
           Update luma and chroma pointers here to account for padding as per stride.
631
           In some cases stride might not be available when set_display_frame is called.
632
           Hence updated luma and chroma pointers here */
633
634
0
        for(i = 0; i < BUF_MGR_MAX_CNT; i++)
635
0
        {
636
0
            ps_pic_buf = ihevc_buf_mgr_get_buf((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, i);
637
0
            if((NULL == ps_pic_buf) ||
638
0
               (NULL == ps_pic_buf->pu1_luma) ||
639
0
               (NULL == ps_pic_buf->pu1_chroma))
640
0
            {
641
0
                break;
642
0
            }
643
0
            ps_pic_buf->pu1_luma += ps_codec->i4_strd * PAD_TOP + PAD_LEFT;
644
0
            ps_pic_buf->pu1_chroma += (ps_codec->i4_strd * chroma_pixel_strd / h_samp_factor) * (PAD_TOP / v_samp_factor)
645
0
                            + (PAD_LEFT * chroma_pixel_strd / h_samp_factor);
646
0
        }
647
0
    }
648
649
1.89k
    return ret;
650
1.89k
}
651
/**
652
*******************************************************************************
653
*
654
* @brief
655
*  Function to add buffers to MV Bank buffer manager
656
*
657
* @par Description:
658
*  Function to add buffers to MV Bank buffer manager
659
*  To be called once per stream or for every reset
660
*
661
* @param[in] ps_codec
662
*  Pointer to codec context
663
*
664
* @returns  Error from IHEVCD_ERROR_T
665
*
666
* @remarks
667
*
668
*
669
*******************************************************************************
670
*/
671
IHEVCD_ERROR_T ihevcd_mv_buf_mgr_add_bufs(codec_t *ps_codec)
672
1.89k
{
673
1.89k
    IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
674
1.89k
    WORD32 i;
675
1.89k
    WORD32 max_dpb_size;
676
1.89k
    WORD32 mv_bank_size_allocated;
677
1.89k
    WORD32 pic_mv_bank_size;
678
679
1.89k
    sps_t *ps_sps;
680
1.89k
    UWORD8 *pu1_buf;
681
1.89k
    mv_buf_t *ps_mv_buf;
682
683
684
    /* Initialize MV Bank buffer manager */
685
1.89k
    ps_sps = ps_codec->s_parse.ps_sps;
686
687
688
    /* Compute the number of MV Bank buffers needed */
689
1.89k
    max_dpb_size = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1];
690
691
    /* Allocate one extra MV Bank to handle current frame
692
     * In case of asynchronous parsing and processing, number of buffers should increase here
693
     * based on when parsing and processing threads are synchronized
694
     */
695
1.89k
    max_dpb_size++;
696
697
1.89k
    ps_codec->i4_max_dpb_size = max_dpb_size;
698
699
1.89k
    pu1_buf = (UWORD8 *)ps_codec->pv_mv_bank_buf_base;
700
701
1.89k
    ps_mv_buf = (mv_buf_t *)pu1_buf;
702
1.89k
    pu1_buf += max_dpb_size * sizeof(mv_buf_t);
703
1.89k
    ps_codec->ps_mv_buf = ps_mv_buf;
704
1.89k
    mv_bank_size_allocated = ps_codec->i4_total_mv_bank_size - max_dpb_size  * sizeof(mv_buf_t);
705
706
    /* Compute MV bank size per picture */
707
1.89k
    pic_mv_bank_size = ihevcd_get_pic_mv_bank_size(ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
708
1.89k
                                                   ALIGN64(ps_sps->i2_pic_height_in_luma_samples));
709
710
17.2k
    for(i = 0; i < max_dpb_size; i++)
711
15.3k
    {
712
15.3k
        WORD32 buf_ret;
713
15.3k
        WORD32 num_pu;
714
15.3k
        WORD32 num_ctb;
715
15.3k
        WORD32 pic_size;
716
15.3k
        pic_size = ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
717
15.3k
                        ALIGN64(ps_sps->i2_pic_height_in_luma_samples);
718
719
720
15.3k
        num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE);
721
15.3k
        num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);
722
723
724
15.3k
        mv_bank_size_allocated -= pic_mv_bank_size;
725
726
15.3k
        if(mv_bank_size_allocated < 0)
727
0
        {
728
0
            ps_codec->s_parse.i4_error_code = IHEVCD_INSUFFICIENT_MEM_MVBANK;
729
0
            return IHEVCD_INSUFFICIENT_MEM_MVBANK;
730
0
        }
731
732
15.3k
        ps_mv_buf->pu4_pic_pu_idx = (UWORD32 *)pu1_buf;
733
15.3k
        pu1_buf += (num_ctb + 1) * sizeof(WORD32);
734
735
15.3k
        ps_mv_buf->pu1_pic_pu_map = pu1_buf;
736
15.3k
        pu1_buf += num_pu;
737
738
15.3k
        ps_mv_buf->pu1_pic_slice_map = (UWORD16 *)pu1_buf;
739
15.3k
        pu1_buf += ALIGN4(num_ctb * sizeof(UWORD16));
740
741
15.3k
        ps_mv_buf->ps_pic_pu = (pu_t *)pu1_buf;
742
15.3k
        pu1_buf += num_pu * sizeof(pu_t);
743
744
15.3k
        buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_mv_buf_mgr, ps_mv_buf, i);
745
746
15.3k
        if(0 != buf_ret)
747
0
        {
748
0
            ps_codec->s_parse.i4_error_code = IHEVCD_BUF_MGR_ERROR;
749
0
            return IHEVCD_BUF_MGR_ERROR;
750
0
        }
751
752
15.3k
        ps_mv_buf++;
753
754
15.3k
    }
755
1.89k
    return ret;
756
1.89k
}
757
/**
758
*******************************************************************************
759
*
760
* @brief
761
*  Output buffer check
762
*
763
* @par Description:
764
*  Check for the number of buffers and buffer sizes of output buffer
765
*
766
* @param[in] ps_codec
767
*  Pointer to codec context
768
*
769
* @returns  Error from IHEVCD_ERROR_T
770
*
771
* @remarks
772
*
773
*
774
*******************************************************************************
775
*/
776
IHEVCD_ERROR_T ihevcd_check_out_buf_size(codec_t *ps_codec)
777
11.2k
{
778
11.2k
    ivd_out_bufdesc_t *ps_out_buffer = ps_codec->ps_out_buffer;
779
11.2k
    UWORD32 au4_min_out_buf_size[IVD_VIDDEC_MAX_IO_BUFFERS];
780
11.2k
    UWORD32 u4_min_num_out_bufs = 0, i;
781
11.2k
    UWORD32 wd, ht;
782
783
11.2k
    if(0 == ps_codec->i4_share_disp_buf)
784
11.2k
    {
785
11.2k
        wd = ps_codec->i4_disp_wd;
786
11.2k
        ht = ps_codec->i4_disp_ht;
787
11.2k
    }
788
0
    else
789
0
    {
790
        /* In case of shared mode, do not check validity of ps_codec->ps_out_buffer */
791
0
        return (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
792
0
    }
793
794
11.2k
    if(ps_codec->i4_disp_strd > (WORD32)wd)
795
0
        wd = ps_codec->i4_disp_strd;
796
797
11.2k
    if(ps_codec->e_chroma_fmt == IV_YUV_420P)
798
3.47k
        u4_min_num_out_bufs = MIN_OUT_BUFS_420;
799
7.82k
    else if(ps_codec->e_chroma_fmt == IV_YUV_444P)
800
0
        u4_min_num_out_bufs = MIN_OUT_BUFS_444;
801
7.82k
    else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
802
4.96k
                    || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
803
4.83k
        u4_min_num_out_bufs = MIN_OUT_BUFS_420SP;
804
2.98k
    else if(ps_codec->e_chroma_fmt == IV_GRAY)
805
2.98k
        u4_min_num_out_bufs = MIN_OUT_BUFS_GRAY;
806
807
11.2k
    if(ps_codec->e_chroma_fmt == IV_YUV_420P)
808
3.47k
    {
809
3.47k
        au4_min_out_buf_size[0] = (wd * ht);
810
3.47k
        au4_min_out_buf_size[1] = (wd * ht) >> 2;
811
3.47k
        au4_min_out_buf_size[2] = (wd * ht) >> 2;
812
3.47k
    }
813
7.82k
    else if(ps_codec->e_chroma_fmt == IV_YUV_444P)
814
0
    {
815
0
        au4_min_out_buf_size[0] = (wd * ht);
816
0
        au4_min_out_buf_size[1] = (wd * ht);
817
0
        au4_min_out_buf_size[2] = (wd * ht);
818
0
    }
819
7.82k
    else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
820
4.96k
                    || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
821
4.83k
    {
822
4.83k
        au4_min_out_buf_size[0] = (wd * ht);
823
4.83k
        au4_min_out_buf_size[1] = (wd * ht) >> 1;
824
4.83k
        au4_min_out_buf_size[2] = 0;
825
4.83k
    }
826
2.98k
    else if(ps_codec->e_chroma_fmt == IV_GRAY)
827
2.98k
    {
828
2.98k
        au4_min_out_buf_size[0] = (wd * ht);
829
2.98k
        au4_min_out_buf_size[1] = 0;
830
2.98k
        au4_min_out_buf_size[2] = 0;
831
2.98k
    }
832
833
834
11.2k
    if(ps_out_buffer->u4_num_bufs < u4_min_num_out_bufs)
835
0
    {
836
0
        return (IHEVCD_ERROR_T)IV_FAIL;
837
0
    }
838
839
33.6k
    for (i = 0 ; i < u4_min_num_out_bufs; i++)
840
22.7k
    {
841
22.7k
        if(ps_out_buffer->u4_min_out_buf_size[i] < au4_min_out_buf_size[i])
842
369
        {
843
369
            return (IHEVCD_ERROR_T)IV_FAIL;
844
369
        }
845
22.7k
    }
846
847
10.9k
    return (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
848
11.2k
}
849
850
/**
851
*******************************************************************************
852
*
853
* @brief
854
*  Picture level initializations required during parsing
855
*
856
* @par Description:
857
*  Initialize picture level context variables during parsing Initialize mv
858
* bank buffer manager in the first init call
859
*
860
* @param[in] ps_codec
861
*  Pointer to codec context
862
*
863
* @returns  Error from IHEVCD_ERROR_T
864
*
865
* @remarks
866
*
867
*
868
*******************************************************************************
869
*/
870
IHEVCD_ERROR_T ihevcd_parse_pic_init(codec_t *ps_codec)
871
11.2k
{
872
11.2k
    IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
873
11.2k
    mv_buf_t *ps_mv_buf;
874
11.2k
    sps_t *ps_sps;
875
11.2k
    WORD32 num_min_cu;
876
11.2k
    WORD32 cur_pic_buf_id;
877
11.2k
    WORD32 cur_mv_bank_buf_id;
878
11.2k
    pic_buf_t *ps_cur_pic;
879
11.2k
    slice_header_t *ps_slice_hdr;
880
11.2k
    UWORD8 *pu1_cur_pic_luma, *pu1_cur_pic_chroma;
881
11.2k
    WORD32 h_samp_factor, v_samp_factor;
882
11.2k
    WORD32 chroma_pixel_strd = 2;
883
11.2k
    WORD32 i;
884
885
11.2k
    ps_codec->s_parse.i4_error_code = IHEVCD_SUCCESS;
886
11.2k
    ps_sps = ps_codec->s_parse.ps_sps;
887
11.2k
    ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr;
888
889
    /* Memset picture level intra map and transquant bypass map to zero */
890
11.2k
    num_min_cu = ((ps_sps->i2_pic_height_in_luma_samples + 7) / 8) * ((ps_sps->i2_pic_width_in_luma_samples + 63) / 64);
891
11.2k
    memset(ps_codec->s_parse.pu1_pic_intra_flag, 0, num_min_cu);
892
11.2k
    memset(ps_codec->s_parse.pu1_pic_no_loop_filter_flag, 0, num_min_cu);
893
894
11.2k
    h_samp_factor = (CHROMA_FMT_IDC_YUV444 == ps_sps->i1_chroma_format_idc) ? 1 : 2;
895
11.2k
    v_samp_factor = (CHROMA_FMT_IDC_YUV420 == ps_sps->i1_chroma_format_idc) ? 2 : 1;
896
897
11.2k
    if(0 == ps_codec->s_parse.i4_first_pic_init)
898
1.89k
    {
899
1.89k
        ret = ihevcd_mv_buf_mgr_add_bufs(ps_codec);
900
1.89k
        RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
901
902
1.89k
        ret = ihevcd_pic_buf_mgr_add_bufs(ps_codec);
903
1.89k
        RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
904
905
1.89k
        ps_codec->s_parse.i4_first_pic_init = 1;
906
1.89k
    }
907
908
    /* Output buffer check */
909
11.2k
    ret = ihevcd_check_out_buf_size(ps_codec);
910
11.2k
    RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
911
912
    /* Initialize all the slice headers' slice addresses to zero */
913
10.9k
    {
914
10.9k
        WORD32 slice_idx;
915
10.9k
        WORD32 slice_start_idx;
916
917
10.9k
        slice_start_idx = ps_codec->i4_slice_error ? 2 : 1;
918
919
2.79M
        for(slice_idx = slice_start_idx; slice_idx < MAX_SLICE_HDR_CNT; slice_idx++)
920
2.78M
        {
921
2.78M
            slice_header_t *ps_slice_hdr_tmp = ps_codec->ps_slice_hdr_base + slice_idx;
922
2.78M
            ps_slice_hdr_tmp->i2_ctb_x = -1;
923
2.78M
            ps_slice_hdr_tmp->i2_ctb_y = -1;
924
925
2.78M
        }
926
10.9k
    }
927
928
    /* Get free MV Bank to hold current picture's motion vector data */
929
10.9k
    {
930
10.9k
        ps_mv_buf = (mv_buf_t *)ihevc_buf_mgr_get_next_free((buf_mgr_t *)ps_codec->pv_mv_buf_mgr, &cur_mv_bank_buf_id);
931
932
        /* If there are no free buffers then return with an error code.
933
         * If the buffer is to be freed by another thread , change the
934
         * following to call thread yield and wait for buffer to be freed
935
         */
936
10.9k
        if(NULL == ps_mv_buf)
937
6
        {
938
6
            ps_codec->s_parse.i4_error_code = IHEVCD_NO_FREE_MVBANK;
939
6
            ps_codec->i4_error_code = IHEVCD_NO_FREE_MVBANK;
940
6
            return IHEVCD_NO_FREE_MVBANK;
941
6
        }
942
943
10.9k
        ps_codec->s_parse.ps_cur_mv_buf = ps_mv_buf;
944
        /* Set current ABS poc to ps_mv_buf, so that while freeing a reference buffer
945
         * corresponding mv buffer can be found by looping through ps_codec->ps_mv_buf array
946
         * and getting a buffer id to free
947
         */
948
10.9k
        ps_mv_buf->i4_abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
949
10.9k
    }
950
951
    /* Get free picture buffer to hold current picture recon data */
952
    /* TODO: For asynchronous api the following initializations related to picture
953
     * buffer should be moved to processing side
954
     */
955
0
    {
956
957
10.9k
        UWORD8 *pu1_buf;
958
10.9k
        ps_cur_pic = (pic_buf_t *)ihevc_buf_mgr_get_next_free((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, &cur_pic_buf_id);
959
960
        /* If there are no free buffers then return with an error code.
961
         * TODO: If the buffer is to be freed by another thread , change the
962
         * following to call thread yield and wait for buffer to be freed
963
         */
964
10.9k
        if(NULL == ps_cur_pic)
965
0
        {
966
0
            ps_codec->s_parse.i4_error_code = IHEVCD_NO_FREE_PICBUF;
967
0
            ps_codec->i4_error_code = IHEVCD_NO_FREE_PICBUF;
968
0
            return IHEVCD_NO_FREE_PICBUF;
969
0
        }
970
971
        /* Store input timestamp sent with input buffer */
972
10.9k
        ps_cur_pic->u4_ts = ps_codec->u4_ts;
973
10.9k
        ps_cur_pic->i4_abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
974
10.9k
        ps_cur_pic->i4_poc_lsb = ps_slice_hdr->i4_pic_order_cnt_lsb;
975
10.9k
        pu1_buf = ps_cur_pic->pu1_luma;
976
10.9k
        pu1_cur_pic_luma = pu1_buf;
977
978
10.9k
        pu1_buf = ps_cur_pic->pu1_chroma;
979
10.9k
        pu1_cur_pic_chroma = pu1_buf;
980
981
10.9k
#ifndef DISABLE_SEI
982
10.9k
        ps_cur_pic->s_sei_params.i1_sei_parameters_present_flag = 0;
983
10.9k
        if(ps_codec->s_parse.s_sei_params.i1_sei_parameters_present_flag)
984
210
        {
985
210
            sei_params_t *ps_sei = &ps_codec->s_parse.s_sei_params;
986
210
            ps_cur_pic->s_sei_params = ps_codec->s_parse.s_sei_params;
987
988
            /* Once sei_params is copied to pic_buf,
989
             * mark sei_params in s_parse as not present,
990
             * this ensures that future frames do not use this data again.
991
             */
992
210
            ps_sei->i1_sei_parameters_present_flag = 0;
993
210
            ps_sei->i1_user_data_registered_present_flag = 0;
994
210
            ps_sei->i1_aud_present_flag = 0;
995
210
            ps_sei->i1_time_code_present_flag = 0;
996
210
            ps_sei->i1_buf_period_params_present_flag = 0;
997
210
            ps_sei->i1_pic_timing_params_present_flag = 0;
998
210
            ps_sei->i1_recovery_point_params_present_flag = 0;
999
210
            ps_sei->i1_active_parameter_set = 0;
1000
210
            ps_sei->i4_sei_mastering_disp_colour_vol_params_present_flags = 0;
1001
210
        }
1002
10.9k
#endif
1003
10.9k
    }
1004
1005
10.9k
    if(0 == ps_codec->u4_pic_cnt)
1006
1.59k
    {
1007
1.59k
        memset(ps_cur_pic->pu1_luma, 128, (ps_sps->i2_pic_width_in_luma_samples + PAD_WD) * ps_sps->i2_pic_height_in_luma_samples);
1008
1.59k
        if(ps_sps->i1_chroma_format_idc != CHROMA_FMT_IDC_MONOCHROME)
1009
1.59k
        {
1010
1.59k
            memset(ps_cur_pic->pu1_chroma,
1011
1.59k
                   128,
1012
1.59k
                   (((ps_sps->i2_pic_width_in_luma_samples + PAD_WD) * (chroma_pixel_strd / h_samp_factor))
1013
1.59k
                                   * ps_sps->i2_pic_height_in_luma_samples / v_samp_factor));
1014
1.59k
        }
1015
1.59k
    }
1016
1017
    /* Fill the remaining entries of the reference lists with the nearest POC
1018
     * This is done to handle cases where there is a corruption in the reference index */
1019
10.9k
    {
1020
10.9k
        pic_buf_t *ps_pic_buf_ref;
1021
10.9k
        mv_buf_t *ps_mv_buf_ref;
1022
10.9k
        WORD32 r_idx;
1023
10.9k
        dpb_mgr_t *ps_dpb_mgr = (dpb_mgr_t *)ps_codec->pv_dpb_mgr;
1024
10.9k
        buf_mgr_t *ps_mv_buf_mgr = (buf_mgr_t *)ps_codec->pv_mv_buf_mgr;
1025
1026
10.9k
        ps_pic_buf_ref = ihevc_dpb_mgr_get_ref_by_nearest_poc(ps_dpb_mgr, ps_slice_hdr->i4_abs_pic_order_cnt);
1027
10.9k
        if(NULL == ps_pic_buf_ref)
1028
4.37k
        {
1029
4.37k
            WORD32 size;
1030
1031
4.37k
            WORD32 num_pu;
1032
4.37k
            WORD32 num_ctb;
1033
4.37k
            WORD32 pic_size;
1034
            /* In case current mv buffer itself is being used as reference mv buffer for colocated
1035
             * calculations, then memset all the buffers to zero.
1036
             */
1037
4.37k
            pic_size = ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
1038
4.37k
                            ALIGN64(ps_sps->i2_pic_height_in_luma_samples);
1039
1040
4.37k
            num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE);
1041
4.37k
            num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);
1042
1043
4.37k
            memset(ps_mv_buf->ai4_l0_collocated_poc, 0, sizeof(ps_mv_buf->ai4_l0_collocated_poc));
1044
4.37k
            memset(ps_mv_buf->ai1_l0_collocated_poc_lt, 0, sizeof(ps_mv_buf->ai1_l0_collocated_poc_lt));
1045
4.37k
            memset(ps_mv_buf->ai4_l1_collocated_poc, 0, sizeof(ps_mv_buf->ai4_l1_collocated_poc));
1046
4.37k
            memset(ps_mv_buf->ai1_l1_collocated_poc_lt, 0, sizeof(ps_mv_buf->ai1_l1_collocated_poc_lt));
1047
1048
4.37k
            size = (num_ctb + 1) * sizeof(WORD32);
1049
4.37k
            memset(ps_mv_buf->pu4_pic_pu_idx, 0, size);
1050
1051
4.37k
            size = num_pu;
1052
4.37k
            memset(ps_mv_buf->pu1_pic_pu_map, 0, size);
1053
4.37k
            size = ALIGN4(num_ctb * sizeof(UWORD16));
1054
4.37k
            memset(ps_mv_buf->pu1_pic_slice_map, 0, size);
1055
4.37k
            size = num_pu * sizeof(pu_t);
1056
4.37k
            memset(ps_mv_buf->ps_pic_pu, 0, size);
1057
1058
4.37k
            ps_pic_buf_ref = ps_cur_pic;
1059
4.37k
            ps_mv_buf_ref = ps_mv_buf;
1060
4.37k
        }
1061
6.54k
        else
1062
6.54k
        {
1063
6.54k
            ps_mv_buf_ref = ihevcd_mv_mgr_get_poc(ps_mv_buf_mgr, ps_pic_buf_ref->i4_abs_poc);
1064
6.54k
        }
1065
1066
25.9k
        for(r_idx = 0; r_idx < ps_slice_hdr->i1_num_ref_idx_l0_active; r_idx++)
1067
15.0k
        {
1068
15.0k
            if(NULL == ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf)
1069
1.09k
            {
1070
1.09k
                ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
1071
1.09k
                ps_slice_hdr->as_ref_pic_list0[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
1072
1.09k
            }
1073
15.0k
        }
1074
1075
170k
        for(r_idx = ps_slice_hdr->i1_num_ref_idx_l0_active; r_idx < MAX_DPB_SIZE; r_idx++)
1076
159k
        {
1077
159k
            ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
1078
159k
            ps_slice_hdr->as_ref_pic_list0[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
1079
159k
        }
1080
1081
23.0k
        for(r_idx = 0; r_idx < ps_slice_hdr->i1_num_ref_idx_l1_active; r_idx++)
1082
12.1k
        {
1083
12.1k
            if(NULL == ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf)
1084
526
            {
1085
526
                ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
1086
526
                ps_slice_hdr->as_ref_pic_list1[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
1087
526
            }
1088
12.1k
        }
1089
1090
173k
        for(r_idx = ps_slice_hdr->i1_num_ref_idx_l1_active; r_idx < MAX_DPB_SIZE; r_idx++)
1091
162k
        {
1092
162k
            ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
1093
162k
            ps_slice_hdr->as_ref_pic_list1[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
1094
162k
        }
1095
10.9k
    }
1096
1097
1098
    /* Reset the jobq to start of the jobq buffer */
1099
10.9k
    ihevcd_jobq_reset((jobq_t *)ps_codec->pv_proc_jobq);
1100
1101
10.9k
    if(ps_codec->i4_threads_active)
1102
10.9k
    {
1103
10.9k
        ps_codec->i4_break_threads = 0;
1104
10.9k
    }
1105
10.9k
    ps_codec->s_parse.i4_pic_pu_idx = 0;
1106
10.9k
    ps_codec->s_parse.i4_pic_tu_idx = 0;
1107
1108
10.9k
    ps_codec->s_parse.pu1_pic_pu_map = ps_mv_buf->pu1_pic_pu_map;
1109
10.9k
    ps_codec->s_parse.ps_pic_pu      = ps_mv_buf->ps_pic_pu;
1110
10.9k
    ps_codec->s_parse.pu4_pic_pu_idx = ps_mv_buf->pu4_pic_pu_idx;
1111
10.9k
    ps_codec->s_parse.pu1_slice_idx = (UWORD16 *)ps_mv_buf->pu1_pic_slice_map;
1112
98.3k
    for(i = 0; i < MAX_PROCESS_THREADS; i++)
1113
87.3k
    {
1114
87.3k
        ps_codec->as_process[i].pu1_slice_idx = (UWORD16 *)ps_mv_buf->pu1_pic_slice_map;
1115
87.3k
    }
1116
10.9k
    ps_codec->s_parse.pu1_pu_map = ps_codec->s_parse.pu1_pic_pu_map;
1117
10.9k
    ps_codec->s_parse.ps_pu = ps_codec->s_parse.ps_pic_pu;
1118
1119
10.9k
    {
1120
10.9k
        UWORD8 *pu1_buf;
1121
10.9k
        WORD32 ctb_luma_min_tu_cnt, ctb_chroma_min_tu_cnt, ctb_min_tu_cnt;
1122
10.9k
        WORD32 pic_size;
1123
10.9k
        WORD32 num_ctb;
1124
1125
10.9k
        pic_size = ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
1126
10.9k
                        ALIGN64(ps_sps->i2_pic_height_in_luma_samples);
1127
1128
10.9k
        ctb_luma_min_tu_cnt = pic_size / (MIN_TU_SIZE * MIN_TU_SIZE);
1129
1130
10.9k
        if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV444)
1131
0
        {
1132
0
            ctb_chroma_min_tu_cnt = ctb_luma_min_tu_cnt << 1;
1133
0
        }
1134
10.9k
        else if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV422)
1135
0
        {
1136
0
            ctb_chroma_min_tu_cnt = ctb_luma_min_tu_cnt;
1137
0
        }
1138
10.9k
        else if(ps_sps->i1_chroma_format_idc == CHROMA_FMT_IDC_YUV420)
1139
10.9k
        {
1140
10.9k
            ctb_chroma_min_tu_cnt = ctb_luma_min_tu_cnt >> 1;
1141
10.9k
        }
1142
0
        else
1143
0
        {
1144
0
            ctb_chroma_min_tu_cnt = 0;
1145
0
        }
1146
1147
10.9k
        ctb_min_tu_cnt = ctb_luma_min_tu_cnt + ctb_chroma_min_tu_cnt;
1148
1149
10.9k
        num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);
1150
10.9k
        pu1_buf  = (UWORD8 *)ps_codec->pv_tu_data;
1151
10.9k
        ps_codec->s_parse.pu4_pic_tu_idx = (UWORD32 *)pu1_buf;
1152
10.9k
        pu1_buf += (num_ctb + 1) * sizeof(WORD32);
1153
1154
10.9k
        ps_codec->s_parse.pu1_pic_tu_map = pu1_buf;
1155
10.9k
        pu1_buf += ctb_min_tu_cnt;
1156
1157
10.9k
        ps_codec->s_parse.ps_pic_tu = (tu_t *)pu1_buf;
1158
10.9k
        pu1_buf += ctb_min_tu_cnt * sizeof(tu_t);
1159
1160
10.9k
        ps_codec->s_parse.pv_pic_tu_coeff_data = pu1_buf;
1161
1162
10.9k
        ps_codec->s_parse.pu1_tu_map = ps_codec->s_parse.pu1_pic_tu_map;
1163
10.9k
        ps_codec->s_parse.ps_tu = ps_codec->s_parse.ps_pic_tu;
1164
10.9k
        ps_codec->s_parse.pv_tu_coeff_data = ps_codec->s_parse.pv_pic_tu_coeff_data;
1165
10.9k
    }
1166
1167
10.9k
    ps_codec->s_parse.s_bs_ctxt.ps_pic_pu = ps_codec->s_parse.ps_pic_pu;
1168
10.9k
    ps_codec->s_parse.s_bs_ctxt.pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx;
1169
10.9k
    ps_codec->s_parse.s_bs_ctxt.pu4_pic_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx;
1170
1171
1172
    /* Set number of CTBs to be processed simultaneously */
1173
10.9k
    ps_codec->i4_proc_nctb = ihevcd_nctb_cnt(ps_codec, ps_sps);
1174
1175
    /* Memset Parse Map and process map at the start of frame */
1176
    //TODO: In case of asynchronous API proc_map can not be set to zero here
1177
10.9k
    {
1178
10.9k
        WORD32 num_ctb;
1179
1180
10.9k
        num_ctb = ps_sps->i4_pic_size_in_ctb;
1181
1182
10.9k
        memset(ps_codec->pu1_parse_map, 0, num_ctb);
1183
1184
10.9k
        memset(ps_codec->pu1_proc_map, 0, num_ctb);
1185
10.9k
    }
1186
1187
1188
1189
    /* Initialize disp buf id to -1, this will be updated at the end of frame if there is
1190
     * buffer to be displayed
1191
     */
1192
10.9k
    ps_codec->i4_disp_buf_id = -1;
1193
10.9k
    ps_codec->ps_disp_buf = NULL;
1194
1195
10.9k
    ps_codec->i4_disable_deblk_pic  = 0;
1196
10.9k
    ps_codec->i4_disable_sao_pic    = 0;
1197
10.9k
    ps_codec->i4_fullpel_inter_pred = 0;
1198
10.9k
    ps_codec->i4_mv_frac_mask       = 0x7FFFFFFF;
1199
1200
    /* If degrade is enabled, set the degrade flags appropriately */
1201
10.9k
    if(ps_codec->i4_degrade_type && ps_codec->i4_degrade_pics)
1202
0
    {
1203
0
        WORD32 degrade_pic;
1204
0
        ps_codec->i4_degrade_pic_cnt++;
1205
0
        degrade_pic = 0;
1206
1207
        /* If degrade is to be done in all frames, then do not check further */
1208
0
        switch(ps_codec->i4_degrade_pics)
1209
0
        {
1210
0
            case 4:
1211
0
            {
1212
0
                degrade_pic = 1;
1213
0
                break;
1214
0
            }
1215
0
            case 3:
1216
0
            {
1217
0
                if(ps_slice_hdr->i1_slice_type != ISLICE)
1218
0
                    degrade_pic = 1;
1219
1220
0
                break;
1221
0
            }
1222
0
            case 2:
1223
0
            {
1224
1225
                /* If pic count hits non-degrade interval or it is an islice, then do not degrade */
1226
0
                if((ps_slice_hdr->i1_slice_type != ISLICE) &&
1227
0
                   (ps_codec->i4_degrade_pic_cnt != ps_codec->i4_nondegrade_interval))
1228
0
                    degrade_pic = 1;
1229
1230
0
                break;
1231
0
            }
1232
0
            case 1:
1233
0
            {
1234
                /* Check if the current picture is non-ref */
1235
0
                if((ps_slice_hdr->i1_nal_unit_type < NAL_BLA_W_LP) &&
1236
0
                   (ps_slice_hdr->i1_nal_unit_type % 2 == 0))
1237
0
                {
1238
0
                    degrade_pic = 1;
1239
0
                }
1240
0
                break;
1241
0
            }
1242
1243
1244
0
        }
1245
0
        if(degrade_pic)
1246
0
        {
1247
0
            if(ps_codec->i4_degrade_type & 0x1)
1248
0
                ps_codec->i4_disable_sao_pic = 1;
1249
1250
0
            if(ps_codec->i4_degrade_type & 0x2)
1251
0
                ps_codec->i4_disable_deblk_pic = 1;
1252
1253
            /* MC degrading is done only for non-ref pictures */
1254
0
            if((ps_slice_hdr->i1_nal_unit_type < NAL_BLA_W_LP) &&
1255
0
               (ps_slice_hdr->i1_nal_unit_type % 2 == 0))
1256
0
            {
1257
0
                if(ps_codec->i4_degrade_type & 0x4)
1258
0
                    ps_codec->i4_mv_frac_mask = 0;
1259
1260
0
                if(ps_codec->i4_degrade_type & 0x8)
1261
0
                    ps_codec->i4_mv_frac_mask = 0;
1262
0
            }
1263
0
        }
1264
0
        else
1265
0
            ps_codec->i4_degrade_pic_cnt = 0;
1266
0
    }
1267
1268
1269
10.9k
    {
1270
10.9k
        WORD32 i;
1271
98.3k
        for(i = 0; i < MAX_PROCESS_THREADS; i++)
1272
87.3k
        {
1273
87.3k
            ps_codec->as_process[i].pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx;
1274
87.3k
            ps_codec->as_process[i].ps_pic_pu = ps_codec->s_parse.ps_pic_pu;
1275
87.3k
            ps_codec->as_process[i].pu1_pic_pu_map = ps_codec->s_parse.pu1_pic_pu_map;
1276
87.3k
            ps_codec->as_process[i].pu4_pic_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx;
1277
87.3k
            ps_codec->as_process[i].ps_pic_tu = ps_codec->s_parse.ps_pic_tu;
1278
87.3k
            ps_codec->as_process[i].pu1_pic_tu_map = ps_codec->s_parse.pu1_pic_tu_map;
1279
87.3k
            ps_codec->as_process[i].pv_pic_tu_coeff_data = ps_codec->s_parse.pv_pic_tu_coeff_data;
1280
87.3k
            ps_codec->as_process[i].i4_cur_mv_bank_buf_id = cur_mv_bank_buf_id;
1281
87.3k
            ps_codec->as_process[i].s_sao_ctxt.pu1_slice_idx = ps_codec->as_process[i].pu1_slice_idx;
1282
87.3k
            ps_codec->as_process[i].s_sao_ctxt.pu1_tile_idx = ps_codec->as_process[i].pu1_tile_idx;
1283
1284
            /* TODO: For asynchronous api the following initializations related to picture
1285
             * buffer should be moved to processing side
1286
             */
1287
87.3k
            ps_codec->as_process[i].pu1_cur_pic_luma = pu1_cur_pic_luma;
1288
87.3k
            ps_codec->as_process[i].pu1_cur_pic_chroma = pu1_cur_pic_chroma;
1289
87.3k
            ps_codec->as_process[i].ps_cur_pic = ps_cur_pic;
1290
87.3k
            ps_codec->as_process[i].i4_cur_pic_buf_id = cur_pic_buf_id;
1291
1292
87.3k
            ps_codec->as_process[i].ps_out_buffer = ps_codec->ps_out_buffer;
1293
87.3k
            if(1 < ps_codec->i4_num_cores)
1294
39.6k
            {
1295
39.6k
                ps_codec->as_process[i].i4_check_parse_status = 1;
1296
39.6k
                ps_codec->as_process[i].i4_check_proc_status = 1;
1297
39.6k
            }
1298
47.7k
            else
1299
47.7k
            {
1300
47.7k
                ps_codec->as_process[i].i4_check_parse_status = 0;
1301
47.7k
                ps_codec->as_process[i].i4_check_proc_status = 0;
1302
47.7k
            }
1303
87.3k
            ps_codec->as_process[i].pu1_pic_intra_flag = ps_codec->s_parse.pu1_pic_intra_flag;
1304
87.3k
            ps_codec->as_process[i].pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
1305
87.3k
            ps_codec->as_process[i].i4_init_done = 0;
1306
1307
87.3k
            ps_codec->as_process[i].s_bs_ctxt.pu4_pic_tu_idx = ps_codec->as_process[i].pu4_pic_tu_idx;
1308
87.3k
            ps_codec->as_process[i].s_bs_ctxt.pu4_pic_pu_idx = ps_codec->as_process[i].pu4_pic_pu_idx;
1309
87.3k
            ps_codec->as_process[i].s_bs_ctxt.ps_pic_pu = ps_codec->as_process[i].ps_pic_pu;
1310
87.3k
            ps_codec->as_process[i].s_deblk_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
1311
87.3k
            ps_codec->as_process[i].s_deblk_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
1312
87.3k
            ps_codec->as_process[i].s_deblk_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
1313
87.3k
            ps_codec->as_process[i].s_sao_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
1314
87.3k
            ps_codec->as_process[i].s_sao_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
1315
87.3k
            ps_codec->as_process[i].s_sao_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
1316
87.3k
            if(i < (ps_codec->i4_num_cores - 1))
1317
10.2k
            {
1318
10.2k
                if (!ps_codec->ai4_process_thread_created[i])
1319
936
                {
1320
936
                    ithread_create(ps_codec->apv_process_thread_handle[i], NULL,
1321
936
                                (void *)ihevcd_process_thread,
1322
936
                                (void *)&ps_codec->as_process[i]);
1323
936
                    ps_codec->ai4_process_thread_created[i] = 1;
1324
936
                }
1325
10.2k
                if(ps_codec->i4_threads_active)
1326
10.2k
                {
1327
10.2k
                    ret = ithread_mutex_lock(ps_codec->apv_proc_start_mutex[i]);
1328
10.2k
                    RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
1329
1330
10.2k
                    ps_codec->ai4_process_start[i] = 1;
1331
10.2k
                    ithread_cond_signal(ps_codec->apv_proc_start_condition[i]);
1332
1333
10.2k
                    ret = ithread_mutex_unlock(ps_codec->apv_proc_start_mutex[i]);
1334
10.2k
                    RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
1335
10.2k
                }
1336
10.2k
            }
1337
77.1k
            else
1338
77.1k
            {
1339
77.1k
                ps_codec->ai4_process_thread_created[i] = 0;
1340
77.1k
            }
1341
1342
87.3k
        }
1343
10.9k
        if(ps_codec->u1_enable_cu_info)
1344
0
        {
1345
0
            ps_codec->as_buf_id_info_map[cur_pic_buf_id].pu1_qp_map =
1346
0
                ps_codec->pu1_qp_map_base + (cur_pic_buf_id * ps_codec->u4_num_8x8_blks);
1347
0
            ps_codec->as_buf_id_info_map[cur_pic_buf_id].pu1_cu_type_map =
1348
0
                ps_codec->pu1_cu_type_map_base + (cur_pic_buf_id * ps_codec->u4_num_8x8_blks);
1349
0
            memset(ps_codec->as_buf_id_info_map[cur_pic_buf_id].pu1_qp_map,
1350
0
                0, ps_codec->u4_num_8x8_blks);
1351
0
            memset(ps_codec->as_buf_id_info_map[cur_pic_buf_id].pu1_qp_map,
1352
0
                0, ps_codec->u4_num_8x8_blks);
1353
0
        }
1354
1355
10.9k
        ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
1356
10.9k
        ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
1357
1358
10.9k
        ps_codec->s_parse.s_sao_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
1359
10.9k
        ps_codec->s_parse.s_sao_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
1360
10.9k
    }
1361
    /* Since any input bitstream buffer that contains slice data will be sent to output(even in
1362
     * case of error, this buffer is added to display queue and next buffer in the display queue
1363
     * will be returned as the display buffer.
1364
     * Note: If format conversion (or frame copy) is used and is scheduled
1365
     * in a different thread then it has to check if the processing for the current row is complete before
1366
     * it copies/converts a given row. In case of low delay or in case of B pictures, current frame being decoded has to be
1367
     * returned, which requires a status check to ensure that the current row is reconstructed before copying.
1368
     */
1369
    /* Add current picture to display manager */
1370
0
    {
1371
10.9k
        WORD32 abs_poc;
1372
10.9k
        slice_header_t *ps_slice_hdr;
1373
10.9k
        ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr;
1374
10.9k
        abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
1375
10.9k
        ihevc_disp_mgr_add((disp_mgr_t *)ps_codec->pv_disp_buf_mgr,
1376
10.9k
                           ps_codec->as_process[0].i4_cur_pic_buf_id,
1377
10.9k
                           abs_poc,
1378
10.9k
                           ps_codec->as_process[0].ps_cur_pic);
1379
10.9k
    }
1380
10.9k
    ps_codec->ps_disp_buf = NULL;
1381
    /* Get picture to be displayed if number of pictures decoded is more than max allowed reorder */
1382
    /* Since the current will be decoded, check is fore >= instead of > */
1383
10.9k
    if(((WORD32)(ps_codec->u4_pic_cnt - ps_codec->u4_disp_cnt) >= ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1]) ||
1384
1.45k
       (ps_codec->e_frm_out_mode == IVD_DECODE_FRAME_OUT))
1385
1386
9.46k
    {
1387
9.46k
        ps_codec->ps_disp_buf = (pic_buf_t *)ihevc_disp_mgr_get((disp_mgr_t *)ps_codec->pv_disp_buf_mgr, &ps_codec->i4_disp_buf_id);
1388
9.46k
        ps_codec->u4_disp_cnt++;
1389
9.46k
    }
1390
1391
10.9k
    ps_codec->s_fmt_conv.i4_cur_row = 0;
1392
    /* Set number of rows to be processed at a time */
1393
10.9k
    ps_codec->s_fmt_conv.i4_num_rows = 4;
1394
1395
10.9k
    if(ps_codec->u4_enable_fmt_conv_ahead && (ps_codec->i4_num_cores > 1))
1396
0
    {
1397
0
        process_ctxt_t *ps_proc;
1398
1399
        /* i4_num_cores - 1 contexts are currently being used by other threads */
1400
0
        ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1];
1401
1402
        /* If the frame being decoded and displayed are different, schedule format conversion jobs
1403
         * this will keep the proc threads busy and lets parse thread decode few CTBs ahead
1404
         * If the frame being decoded and displayed are same, then format conversion is scheduled later.
1405
         */
1406
0
        if((ps_codec->ps_disp_buf) && (ps_codec->i4_disp_buf_id != ps_proc->i4_cur_pic_buf_id) &&
1407
0
           ((0 == ps_codec->i4_share_disp_buf) || (IV_YUV_420P == ps_codec->e_chroma_fmt)))
1408
0
        {
1409
1410
0
            for(i = 0; i < ps_sps->i2_pic_ht_in_ctb; i++)
1411
0
            {
1412
0
                proc_job_t s_job;
1413
0
                IHEVCD_ERROR_T ret;
1414
0
                s_job.i4_cmd = CMD_FMTCONV;
1415
0
                s_job.i2_ctb_cnt = 0;
1416
0
                s_job.i2_ctb_x = 0;
1417
0
                s_job.i2_ctb_y = i;
1418
0
                s_job.i2_slice_idx = 0;
1419
0
                s_job.i4_tu_coeff_data_ofst = 0;
1420
0
                ret = ihevcd_jobq_queue((jobq_t *)ps_codec->s_parse.pv_proc_jobq,
1421
0
                                        &s_job, sizeof(proc_job_t), 1);
1422
0
                if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
1423
0
                    return ret;
1424
0
            }
1425
0
        }
1426
0
    }
1427
1428
    /* If parse_pic_init is called, then slice data is present in the input bitstrea stream */
1429
10.9k
    ps_codec->i4_pic_present = 1;
1430
1431
10.9k
    return ret;
1432
10.9k
}
1433
1434