Coverage Report

Created: 2025-10-10 06:46

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