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 */
80mv_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*/
102WORD32 ihevcd_get_lvl_idx(WORD32 level)
103{
104    WORD32 lvl_idx = 0;
105
106    if(level < IHEVC_LEVEL_20)
107    {
108        lvl_idx = 0;
109    }
110    else if(level >= IHEVC_LEVEL_20 && level < IHEVC_LEVEL_21)
111    {
112        lvl_idx = 1;
113    }
114    else if(level >= IHEVC_LEVEL_21 && level < IHEVC_LEVEL_30)
115    {
116        lvl_idx = 2;
117    }
118    else if(level >= IHEVC_LEVEL_30 && level < IHEVC_LEVEL_31)
119    {
120        lvl_idx = 3;
121    }
122    else if(level >= IHEVC_LEVEL_31 && level < IHEVC_LEVEL_40)
123    {
124        lvl_idx = 4;
125    }
126    else if(level >= IHEVC_LEVEL_40 && level < IHEVC_LEVEL_41)
127    {
128        lvl_idx = 5;
129    }
130    else if(level >= IHEVC_LEVEL_41 && level < IHEVC_LEVEL_50)
131    {
132        lvl_idx = 6;
133    }
134    else if(level >= IHEVC_LEVEL_50 && level < IHEVC_LEVEL_51)
135    {
136        lvl_idx = 7;
137    }
138    else if(level >= IHEVC_LEVEL_51 && level < IHEVC_LEVEL_52)
139    {
140        lvl_idx = 8;
141    }
142    else if(level >= IHEVC_LEVEL_52 && level < IHEVC_LEVEL_60)
143    {
144        lvl_idx = 9;
145    }
146    else if(level >= IHEVC_LEVEL_60 && level < IHEVC_LEVEL_61)
147    {
148        lvl_idx = 10;
149    }
150    else if(level >= IHEVC_LEVEL_61 && level < IHEVC_LEVEL_62)
151    {
152        lvl_idx = 11;
153    }
154    else if(level >= IHEVC_LEVEL_62)
155    {
156        lvl_idx = 12;
157    }
158
159    return (lvl_idx);
160}
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*/
192WORD32 ihevcd_get_total_pic_buf_size(codec_t *ps_codec,
193                                     WORD32 wd,
194                                     WORD32 ht)
195{
196    WORD32 size;
197    WORD32 num_luma_samples;
198    WORD32 max_dpb_size;
199    WORD32 num_samples;
200
201
202    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    max_dpb_size = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1];
206
207    if(ps_codec->e_frm_out_mode != IVD_DECODE_FRAME_OUT)
208        max_dpb_size += ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1];
209
210    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    num_luma_samples = (wd + PAD_WD) * (ht + PAD_HT);
217
218    /* Account for chroma */
219    num_samples = num_luma_samples * 3 / 2;
220
221    /* Number of bytes in reference pictures */
222    size = num_samples * max_dpb_size;
223
224
225    return size;
226}
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*/
247WORD32 ihevcd_get_pic_mv_bank_size(WORD32 num_luma_samples)
248{
249    WORD32 size;
250
251    WORD32 pic_size;
252
253    WORD32 mv_bank_size;
254    WORD32 num_pu;
255    WORD32 num_ctb;
256    pic_size = num_luma_samples;
257
258
259    num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE);
260    num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);
261
262    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    mv_bank_size += (num_ctb + 1) * sizeof(WORD32);
267
268    /* Size for pu_map */
269    mv_bank_size += num_pu;
270
271    /* Size for storing pu_t for each PU */
272    mv_bank_size += num_pu * sizeof(pu_t);
273
274    /* Size for storing slice_idx for each CTB */
275    mv_bank_size += ALIGN4(num_ctb * sizeof(UWORD16));
276
277    size =  mv_bank_size;
278    return size;
279}
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*/
301WORD32 ihevcd_get_tu_data_size(WORD32 num_luma_samples)
302{
303
304
305    WORD32 tu_data_size;
306    WORD32 num_ctb;
307    WORD32 num_luma_tu, num_chroma_tu, num_tu;
308    num_ctb = num_luma_samples / (MIN_CTB_SIZE * MIN_CTB_SIZE);
309
310    num_luma_tu = num_luma_samples / (MIN_TU_SIZE * MIN_TU_SIZE);
311    num_chroma_tu = num_luma_tu >> 1;
312
313    num_tu = num_luma_tu + num_chroma_tu;
314    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    tu_data_size += (num_ctb + 1) * sizeof(WORD32);
319
320    /* Size for storing tu map */
321    tu_data_size += num_luma_tu * sizeof(UWORD8);
322
323    /* Size for storing tu_t for each TU */
324    tu_data_size += num_tu * sizeof(tu_t);
325
326    /* Size for storing number of coded subblocks and scan_idx for each TU */
327    tu_data_size += num_tu * (sizeof(WORD8) + sizeof(WORD8));
328
329    /* Size for storing coeff data for each TU */
330    tu_data_size += num_tu * sizeof(tu_sblk_coeff_data_t);
331
332
333    return tu_data_size;
334}
335
336
337WORD32 ihevcd_nctb_cnt(codec_t *ps_codec, sps_t *ps_sps)
338{
339    WORD32 nctb = 1;
340    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    if(ps_sps->i1_log2_ctb_size < 5)
344        nctb = 1;
345
346    return nctb;
347}
348
349IHEVCD_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{
357
358    tile_t *ps_tile_tmp;
359    WORD32 i;
360    WORD32 tile_row, tile_col;
361
362    if(ctb_x < 0 || ctb_y < 0)
363    {
364        *pi4_ctb_tile_x = 0;
365        *pi4_ctb_tile_y = 0;
366        *pi4_tile_idx = 0;
367
368        return (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
369    }
370
371    tile_row = 0;
372    tile_col = 0;
373    ps_tile_tmp = ps_pps->ps_tile;
374    if(0 == ps_pps->i1_tiles_enabled_flag)
375    {
376        *pi4_ctb_tile_x = ctb_x;
377        *pi4_ctb_tile_y = ctb_y;
378        *pi4_tile_idx = 0;
379    }
380    else
381    {
382        for(i = 0; i < ps_pps->i1_num_tile_columns; i++)
383        {
384            WORD16 next_tile_ctb_x;
385            ps_tile_tmp = ps_pps->ps_tile + i; //* ps_pps->i1_num_tile_rows;
386            if((ps_pps->i1_num_tile_columns - 1) == i)
387            {
388                next_tile_ctb_x = ps_sps->i2_pic_wd_in_ctb;
389            }
390            else
391            {
392                tile_t *ps_tile_next_tmp;
393                ps_tile_next_tmp = ps_pps->ps_tile + i + 1;
394                next_tile_ctb_x = ps_tile_next_tmp->u1_pos_x;
395            }
396            if((ctb_x >= ps_tile_tmp->u1_pos_x) && (ctb_x < next_tile_ctb_x))
397            {
398                tile_col = i;
399                break;
400            }
401        }
402        *pi4_ctb_tile_x = ctb_x - ps_tile_tmp->u1_pos_x;
403
404        for(i = 0; i < ps_pps->i1_num_tile_rows; i++)
405        {
406            WORD16 next_tile_ctb_y;
407            ps_tile_tmp = ps_pps->ps_tile + i * ps_pps->i1_num_tile_columns;
408            if((ps_pps->i1_num_tile_rows - 1) == i)
409            {
410                next_tile_ctb_y = ps_sps->i2_pic_ht_in_ctb;
411            }
412            else
413            {
414                tile_t *ps_tile_next_tmp;
415                ps_tile_next_tmp = ps_pps->ps_tile + ((i + 1) * ps_pps->i1_num_tile_columns);
416                next_tile_ctb_y = ps_tile_next_tmp->u1_pos_y;
417            }
418            if((ctb_y >= ps_tile_tmp->u1_pos_y) && (ctb_y < next_tile_ctb_y))
419            {
420                tile_row = i;
421                break;
422            }
423
424        }
425        *pi4_ctb_tile_y = ctb_y - ps_tile_tmp->u1_pos_y;
426        *pi4_tile_idx = tile_row * ps_pps->i1_num_tile_columns
427                        + tile_col;
428    }
429    return (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
430}
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*/
453IHEVCD_ERROR_T ihevcd_pic_buf_mgr_add_bufs(codec_t *ps_codec)
454{
455    IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
456    WORD32 i;
457    WORD32 max_dpb_size;
458    sps_t *ps_sps;
459    UWORD8 *pu1_buf;
460    pic_buf_t *ps_pic_buf;
461    WORD32 pic_buf_size_allocated;
462
463
464
465
466    /* Initialize Pic buffer manager */
467    ps_sps = ps_codec->s_parse.ps_sps;
468
469    /* Compute the number of Pic buffers needed */
470    max_dpb_size = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1];
471
472    if(ps_codec->e_frm_out_mode != IVD_DECODE_FRAME_OUT)
473        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    max_dpb_size++;
480
481
482    pu1_buf = (UWORD8 *)ps_codec->pu1_ref_pic_buf_base;
483
484    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    if(0 == ps_codec->i4_share_disp_buf)
490    {
491        WORD32 buf_ret;
492        WORD32 luma_samples;
493        WORD32 chroma_samples;
494        pic_buf_size_allocated = ps_codec->i4_total_pic_buf_size;
495
496        luma_samples = (ps_codec->i4_strd) *
497                        (ps_sps->i2_pic_height_in_luma_samples + PAD_HT);
498
499        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        for(i = 0; i < max_dpb_size; i++)
506        {
507            pic_buf_size_allocated -= (luma_samples + chroma_samples);
508
509            if(pic_buf_size_allocated < 0)
510            {
511                ps_codec->s_parse.i4_error_code = IHEVCD_INSUFFICIENT_MEM_PICBUF;
512                return IHEVCD_INSUFFICIENT_MEM_PICBUF;
513            }
514
515            ps_pic_buf->pu1_luma = pu1_buf + ps_codec->i4_strd * PAD_TOP + PAD_LEFT;
516            pu1_buf += luma_samples;
517
518            ps_pic_buf->pu1_chroma = pu1_buf + ps_codec->i4_strd * (PAD_TOP / 2) + PAD_LEFT;
519            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            {
525                UWORD8 *pu1_buf;
526                WORD32 strd, wd, ht;
527                WORD32 i;
528                strd = ps_codec->i4_strd;
529                wd = ps_codec->i4_wd;
530                ht = ps_codec->i4_ht;
531
532                pu1_buf = ps_pic_buf->pu1_luma;
533                for(i = 0; i < ht; i++)
534                {
535                    pu1_buf[-1] = 0;
536                    pu1_buf[wd] = 0;
537                    pu1_buf += strd;
538                }
539                pu1_buf = ps_pic_buf->pu1_luma;
540                memset(pu1_buf - strd - 1, 0, wd + 2);
541
542                pu1_buf += strd * ht;
543                memset(pu1_buf - 1, 0, wd + 2);
544
545                pu1_buf = ps_pic_buf->pu1_chroma;
546                ht >>= 1;
547                for(i = 0; i < ht; i++)
548                {
549                    pu1_buf[-1] = 0;
550                    pu1_buf[-2] = 0;
551                    pu1_buf[wd] = 0;
552                    pu1_buf[wd + 1] = 0;
553                    pu1_buf += strd;
554                }
555                pu1_buf = ps_pic_buf->pu1_chroma;
556                memset(pu1_buf - strd - 2, 0, wd + 4);
557
558                pu1_buf += strd * ht;
559                memset(pu1_buf - 2, 0, wd + 4);
560            }
561
562            buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, ps_pic_buf, i);
563
564
565            if(0 != buf_ret)
566            {
567                ps_codec->s_parse.i4_error_code = IHEVCD_BUF_MGR_ERROR;
568                return IHEVCD_BUF_MGR_ERROR;
569            }
570            ps_pic_buf++;
571        }
572    }
573    else
574    {
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        for(i = 0; i < BUF_MGR_MAX_CNT; i++)
581        {
582            ps_pic_buf = ihevc_buf_mgr_get_buf((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, i);
583            if((NULL == ps_pic_buf) ||
584               (NULL == ps_pic_buf->pu1_luma) ||
585               (NULL == ps_pic_buf->pu1_chroma))
586            {
587                break;
588            }
589            ps_pic_buf->pu1_luma += ps_codec->i4_strd * PAD_TOP + PAD_LEFT;
590            ps_pic_buf->pu1_chroma += ps_codec->i4_strd * (PAD_TOP / 2) + PAD_LEFT;
591        }
592    }
593
594    return ret;
595}
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*/
616IHEVCD_ERROR_T ihevcd_mv_buf_mgr_add_bufs(codec_t *ps_codec)
617{
618    IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
619    WORD32 i;
620    WORD32 max_dpb_size;
621    WORD32 mv_bank_size_allocated;
622    WORD32 pic_mv_bank_size;
623
624    sps_t *ps_sps;
625    UWORD8 *pu1_buf;
626    mv_buf_t *ps_mv_buf;
627
628
629    /* Initialize MV Bank buffer manager */
630    ps_sps = ps_codec->s_parse.ps_sps;
631
632
633    /* Compute the number of MV Bank buffers needed */
634    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    max_dpb_size++;
641
642    ps_codec->i4_max_dpb_size = max_dpb_size;
643
644    pu1_buf = (UWORD8 *)ps_codec->pv_mv_bank_buf_base;
645
646    ps_mv_buf = (mv_buf_t *)pu1_buf;
647    pu1_buf += max_dpb_size * sizeof(mv_buf_t);
648    ps_codec->ps_mv_buf = ps_mv_buf;
649    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    pic_mv_bank_size = ihevcd_get_pic_mv_bank_size(ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
653                                                   ALIGN64(ps_sps->i2_pic_height_in_luma_samples));
654
655    for(i = 0; i < max_dpb_size; i++)
656    {
657        WORD32 buf_ret;
658        WORD32 num_pu;
659        WORD32 num_ctb;
660        WORD32 pic_size;
661        pic_size = ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
662                        ALIGN64(ps_sps->i2_pic_height_in_luma_samples);
663
664
665        num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE);
666        num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);
667
668
669        mv_bank_size_allocated -= pic_mv_bank_size;
670
671        if(mv_bank_size_allocated < 0)
672        {
673            ps_codec->s_parse.i4_error_code = IHEVCD_INSUFFICIENT_MEM_MVBANK;
674            return IHEVCD_INSUFFICIENT_MEM_MVBANK;
675        }
676
677        ps_mv_buf->pu4_pic_pu_idx = (UWORD32 *)pu1_buf;
678        pu1_buf += (num_ctb + 1) * sizeof(WORD32);
679
680        ps_mv_buf->pu1_pic_pu_map = pu1_buf;
681        pu1_buf += num_pu;
682
683        ps_mv_buf->pu1_pic_slice_map = (UWORD16 *)pu1_buf;
684        pu1_buf += ALIGN4(num_ctb * sizeof(UWORD16));
685
686        ps_mv_buf->ps_pic_pu = (pu_t *)pu1_buf;
687        pu1_buf += num_pu * sizeof(pu_t);
688
689        buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_mv_buf_mgr, ps_mv_buf, i);
690
691        if(0 != buf_ret)
692        {
693            ps_codec->s_parse.i4_error_code = IHEVCD_BUF_MGR_ERROR;
694            return IHEVCD_BUF_MGR_ERROR;
695        }
696
697        ps_mv_buf++;
698
699    }
700    return ret;
701}
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*/
721IHEVCD_ERROR_T ihevcd_check_out_buf_size(codec_t *ps_codec)
722{
723    ivd_out_bufdesc_t *ps_out_buffer = ps_codec->ps_out_buffer;
724    UWORD32 au4_min_out_buf_size[IVD_VIDDEC_MAX_IO_BUFFERS];
725    UWORD32 u4_min_num_out_bufs = 0, i;
726    UWORD32 wd, ht;
727
728    if(0 == ps_codec->i4_share_disp_buf)
729    {
730        wd = ps_codec->i4_disp_wd;
731        ht = ps_codec->i4_disp_ht;
732    }
733    else
734    {
735        /* In case of shared mode, do not check validity of ps_codec->ps_out_buffer */
736        return (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
737    }
738
739    if(ps_codec->i4_disp_strd > (WORD32)wd)
740        wd = ps_codec->i4_disp_strd;
741
742    if(ps_codec->e_chroma_fmt == IV_YUV_420P)
743        u4_min_num_out_bufs = MIN_OUT_BUFS_420;
744    else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE)
745        u4_min_num_out_bufs = MIN_OUT_BUFS_422ILE;
746    else if(ps_codec->e_chroma_fmt == IV_RGB_565)
747        u4_min_num_out_bufs = MIN_OUT_BUFS_RGB565;
748    else if(ps_codec->e_chroma_fmt == IV_RGBA_8888)
749        u4_min_num_out_bufs = MIN_OUT_BUFS_RGBA8888;
750    else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
751                    || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
752        u4_min_num_out_bufs = MIN_OUT_BUFS_420SP;
753
754    if(ps_codec->e_chroma_fmt == IV_YUV_420P)
755    {
756        au4_min_out_buf_size[0] = (wd * ht);
757        au4_min_out_buf_size[1] = (wd * ht) >> 2;
758        au4_min_out_buf_size[2] = (wd * ht) >> 2;
759    }
760    else if(ps_codec->e_chroma_fmt == IV_YUV_422ILE)
761    {
762        au4_min_out_buf_size[0] = (wd * ht) * 2;
763        au4_min_out_buf_size[1] =
764                        au4_min_out_buf_size[2] = 0;
765    }
766    else if(ps_codec->e_chroma_fmt == IV_RGB_565)
767    {
768        au4_min_out_buf_size[0] = (wd * ht) * 2;
769        au4_min_out_buf_size[1] =
770                        au4_min_out_buf_size[2] = 0;
771    }
772    else if(ps_codec->e_chroma_fmt == IV_RGBA_8888)
773    {
774        au4_min_out_buf_size[0] = (wd * ht) * 4;
775        au4_min_out_buf_size[1] =
776                        au4_min_out_buf_size[2] = 0;
777    }
778    else if((ps_codec->e_chroma_fmt == IV_YUV_420SP_UV)
779                    || (ps_codec->e_chroma_fmt == IV_YUV_420SP_VU))
780    {
781        au4_min_out_buf_size[0] = (wd * ht);
782        au4_min_out_buf_size[1] = (wd * ht) >> 1;
783        au4_min_out_buf_size[2] = 0;
784    }
785
786    if(ps_out_buffer->u4_num_bufs < u4_min_num_out_bufs)
787    {
788        return (IHEVCD_ERROR_T)IV_FAIL;
789    }
790
791    for (i = 0 ; i < u4_min_num_out_bufs; i++)
792    {
793        if(ps_out_buffer->u4_min_out_buf_size[i] < au4_min_out_buf_size[i])
794        {
795            return (IHEVCD_ERROR_T)IV_FAIL;
796        }
797    }
798
799    return (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
800}
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*/
822IHEVCD_ERROR_T ihevcd_parse_pic_init(codec_t *ps_codec)
823{
824    IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
825    mv_buf_t *ps_mv_buf;
826    sps_t *ps_sps;
827    WORD32 num_min_cu;
828    WORD32 cur_pic_buf_id;
829    WORD32 cur_mv_bank_buf_id;
830    pic_buf_t *ps_cur_pic;
831    slice_header_t *ps_slice_hdr;
832    UWORD8 *pu1_cur_pic_luma, *pu1_cur_pic_chroma;
833    WORD32 i;
834
835    ps_codec->s_parse.i4_error_code = IHEVCD_SUCCESS;
836    ps_sps = ps_codec->s_parse.ps_sps;
837    ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr;
838
839    /* Memset picture level intra map and transquant bypass map to zero */
840    num_min_cu = ((ps_sps->i2_pic_height_in_luma_samples + 7) / 8) * ((ps_sps->i2_pic_width_in_luma_samples + 63) / 64);
841    memset(ps_codec->s_parse.pu1_pic_intra_flag, 0, num_min_cu);
842    memset(ps_codec->s_parse.pu1_pic_no_loop_filter_flag, 0, num_min_cu);
843
844
845
846    if(0 == ps_codec->s_parse.i4_first_pic_init)
847    {
848        ret = ihevcd_mv_buf_mgr_add_bufs(ps_codec);
849        RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
850
851        ret = ihevcd_pic_buf_mgr_add_bufs(ps_codec);
852        RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
853
854        ps_codec->s_parse.i4_first_pic_init = 1;
855    }
856
857    /* Output buffer check */
858    ret = ihevcd_check_out_buf_size(ps_codec);
859    RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
860
861    /* Initialize all the slice headers' slice addresses to zero */
862    {
863        WORD32 slice_idx;
864        WORD32 slice_start_idx;
865
866        slice_start_idx = ps_codec->i4_slice_error ? 2 : 1;
867
868        for(slice_idx = slice_start_idx; slice_idx < MAX_SLICE_HDR_CNT; slice_idx++)
869        {
870            slice_header_t *ps_slice_hdr_tmp = ps_codec->ps_slice_hdr_base + slice_idx;
871            ps_slice_hdr_tmp->i2_ctb_x = -1;
872            ps_slice_hdr_tmp->i2_ctb_y = -1;
873
874        }
875    }
876
877    /* Get free MV Bank to hold current picture's motion vector data */
878    {
879        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        if(NULL == ps_mv_buf)
886        {
887            ps_codec->s_parse.i4_error_code = IHEVCD_NO_FREE_MVBANK;
888            ps_codec->i4_error_code = IHEVCD_NO_FREE_MVBANK;
889            return IHEVCD_NO_FREE_MVBANK;
890        }
891
892        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        ps_mv_buf->i4_abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
898    }
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    {
905
906        UWORD8 *pu1_buf;
907        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        if(NULL == ps_cur_pic)
914        {
915            ps_codec->s_parse.i4_error_code = IHEVCD_NO_FREE_PICBUF;
916            ps_codec->i4_error_code = IHEVCD_NO_FREE_PICBUF;
917            return IHEVCD_NO_FREE_PICBUF;
918        }
919
920        /* Store input timestamp sent with input buffer */
921        ps_cur_pic->u4_ts = ps_codec->u4_ts;
922        ps_cur_pic->i4_abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
923        ps_cur_pic->i4_poc_lsb = ps_slice_hdr->i4_pic_order_cnt_lsb;
924        pu1_buf = ps_cur_pic->pu1_luma;
925        pu1_cur_pic_luma = pu1_buf;
926
927        pu1_buf = ps_cur_pic->pu1_chroma;
928
929        pu1_cur_pic_chroma = pu1_buf;
930
931        ps_cur_pic->s_sei_params.i1_sei_parameters_present_flag = 0;
932        if(ps_codec->s_parse.s_sei_params.i1_sei_parameters_present_flag)
933        {
934            sei_params_t *ps_sei = &ps_codec->s_parse.s_sei_params;
935            ps_cur_pic->s_sei_params = ps_codec->s_parse.s_sei_params;
936
937            /* Once sei_params is copied to pic_buf,
938             * mark sei_params in s_parse as not present,
939             * this ensures that future frames do not use this data again.
940             */
941            ps_sei->i1_sei_parameters_present_flag = 0;
942            ps_sei->i1_user_data_registered_present_flag = 0;
943            ps_sei->i1_aud_present_flag = 0;
944            ps_sei->i1_time_code_present_flag = 0;
945            ps_sei->i1_buf_period_params_present_flag = 0;
946            ps_sei->i1_pic_timing_params_present_flag = 0;
947            ps_sei->i1_recovery_point_params_present_flag = 0;
948            ps_sei->i1_active_parameter_set = 0;
949            ps_sei->i4_sei_mastering_disp_colour_vol_params_present_flags = 0;
950        }
951    }
952
953    if(0 == ps_codec->u4_pic_cnt)
954    {
955        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);
956        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);
957    }
958
959    /* Fill the remaining entries of the reference lists with the nearest POC
960     * This is done to handle cases where there is a corruption in the reference index */
961    {
962        pic_buf_t *ps_pic_buf_ref;
963        mv_buf_t *ps_mv_buf_ref;
964        WORD32 r_idx;
965        dpb_mgr_t *ps_dpb_mgr = (dpb_mgr_t *)ps_codec->pv_dpb_mgr;
966        buf_mgr_t *ps_mv_buf_mgr = (buf_mgr_t *)ps_codec->pv_mv_buf_mgr;
967
968        ps_pic_buf_ref = ihevc_dpb_mgr_get_ref_by_nearest_poc(ps_dpb_mgr, ps_slice_hdr->i4_abs_pic_order_cnt);
969        if(NULL == ps_pic_buf_ref)
970        {
971            WORD32 size;
972
973            WORD32 num_pu;
974            WORD32 num_ctb;
975            WORD32 pic_size;
976            /* In case current mv buffer itself is being used as reference mv buffer for colocated
977             * calculations, then memset all the buffers to zero.
978             */
979            pic_size = ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
980                            ALIGN64(ps_sps->i2_pic_height_in_luma_samples);
981
982            num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE);
983            num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);
984
985            memset(ps_mv_buf->ai4_l0_collocated_poc, 0, sizeof(ps_mv_buf->ai4_l0_collocated_poc));
986            memset(ps_mv_buf->ai1_l0_collocated_poc_lt, 0, sizeof(ps_mv_buf->ai1_l0_collocated_poc_lt));
987            memset(ps_mv_buf->ai4_l1_collocated_poc, 0, sizeof(ps_mv_buf->ai4_l1_collocated_poc));
988            memset(ps_mv_buf->ai1_l1_collocated_poc_lt, 0, sizeof(ps_mv_buf->ai1_l1_collocated_poc_lt));
989
990            size = (num_ctb + 1) * sizeof(WORD32);
991            memset(ps_mv_buf->pu4_pic_pu_idx, 0, size);
992
993            size = num_pu;
994            memset(ps_mv_buf->pu1_pic_pu_map, 0, size);
995            size = ALIGN4(num_ctb * sizeof(UWORD16));
996            memset(ps_mv_buf->pu1_pic_slice_map, 0, size);
997            size = num_pu * sizeof(pu_t);
998            memset(ps_mv_buf->ps_pic_pu, 0, size);
999
1000            ps_pic_buf_ref = ps_cur_pic;
1001            ps_mv_buf_ref = ps_mv_buf;
1002        }
1003        else
1004        {
1005            ps_mv_buf_ref = ihevcd_mv_mgr_get_poc(ps_mv_buf_mgr, ps_pic_buf_ref->i4_abs_poc);
1006        }
1007
1008        for(r_idx = 0; r_idx < ps_slice_hdr->i1_num_ref_idx_l0_active; r_idx++)
1009        {
1010            if(NULL == ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf)
1011            {
1012                ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
1013                ps_slice_hdr->as_ref_pic_list0[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
1014            }
1015        }
1016
1017        for(r_idx = ps_slice_hdr->i1_num_ref_idx_l0_active; r_idx < MAX_DPB_SIZE; r_idx++)
1018        {
1019            ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
1020            ps_slice_hdr->as_ref_pic_list0[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
1021        }
1022
1023        for(r_idx = 0; r_idx < ps_slice_hdr->i1_num_ref_idx_l1_active; r_idx++)
1024        {
1025            if(NULL == ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf)
1026            {
1027                ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
1028                ps_slice_hdr->as_ref_pic_list1[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
1029            }
1030        }
1031
1032        for(r_idx = ps_slice_hdr->i1_num_ref_idx_l1_active; r_idx < MAX_DPB_SIZE; r_idx++)
1033        {
1034            ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
1035            ps_slice_hdr->as_ref_pic_list1[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
1036        }
1037    }
1038
1039
1040    /* Reset the jobq to start of the jobq buffer */
1041    ihevcd_jobq_reset((jobq_t *)ps_codec->pv_proc_jobq);
1042
1043    ps_codec->s_parse.i4_pic_pu_idx = 0;
1044    ps_codec->s_parse.i4_pic_tu_idx = 0;
1045
1046    ps_codec->s_parse.pu1_pic_pu_map = ps_mv_buf->pu1_pic_pu_map;
1047    ps_codec->s_parse.ps_pic_pu      = ps_mv_buf->ps_pic_pu;
1048    ps_codec->s_parse.pu4_pic_pu_idx = ps_mv_buf->pu4_pic_pu_idx;
1049    ps_codec->s_parse.pu1_slice_idx = (UWORD16 *)ps_mv_buf->pu1_pic_slice_map;
1050    for(i = 0; i < MAX_PROCESS_THREADS; i++)
1051    {
1052        ps_codec->as_process[i].pu1_slice_idx = (UWORD16 *)ps_mv_buf->pu1_pic_slice_map;
1053    }
1054    ps_codec->s_parse.pu1_pu_map = ps_codec->s_parse.pu1_pic_pu_map;
1055    ps_codec->s_parse.ps_pu = ps_codec->s_parse.ps_pic_pu;
1056
1057    {
1058        UWORD8 *pu1_buf;
1059        WORD32 ctb_luma_min_tu_cnt, ctb_chroma_min_tu_cnt, ctb_min_tu_cnt;
1060        WORD32 pic_size;
1061        WORD32 num_ctb;
1062
1063        pic_size = ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
1064                        ALIGN64(ps_sps->i2_pic_height_in_luma_samples);
1065
1066        ctb_luma_min_tu_cnt = pic_size / (MIN_TU_SIZE * MIN_TU_SIZE);
1067
1068        ctb_chroma_min_tu_cnt = ctb_luma_min_tu_cnt >> 1;
1069
1070        ctb_min_tu_cnt = ctb_luma_min_tu_cnt + ctb_chroma_min_tu_cnt;
1071
1072        num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);
1073        pu1_buf  = (UWORD8 *)ps_codec->pv_tu_data;
1074        ps_codec->s_parse.pu4_pic_tu_idx = (UWORD32 *)pu1_buf;
1075        pu1_buf += (num_ctb + 1) * sizeof(WORD32);
1076
1077        ps_codec->s_parse.pu1_pic_tu_map = pu1_buf;
1078        pu1_buf += ctb_min_tu_cnt;
1079
1080        ps_codec->s_parse.ps_pic_tu = (tu_t *)pu1_buf;
1081        pu1_buf += ctb_min_tu_cnt * sizeof(tu_t);
1082
1083        ps_codec->s_parse.pv_pic_tu_coeff_data = pu1_buf;
1084
1085        ps_codec->s_parse.pu1_tu_map = ps_codec->s_parse.pu1_pic_tu_map;
1086        ps_codec->s_parse.ps_tu = ps_codec->s_parse.ps_pic_tu;
1087        ps_codec->s_parse.pv_tu_coeff_data = ps_codec->s_parse.pv_pic_tu_coeff_data;
1088    }
1089
1090    ps_codec->s_parse.s_bs_ctxt.ps_pic_pu = ps_codec->s_parse.ps_pic_pu;
1091    ps_codec->s_parse.s_bs_ctxt.pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx;
1092    ps_codec->s_parse.s_bs_ctxt.pu4_pic_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx;
1093
1094
1095    /* Set number of CTBs to be processed simultaneously */
1096    ps_codec->i4_proc_nctb = ihevcd_nctb_cnt(ps_codec, ps_sps);
1097
1098    /* Memset Parse Map and process map at the start of frame */
1099    //TODO: In case of asynchronous API proc_map can not be set to zero here
1100    {
1101        WORD32 num_ctb;
1102
1103        num_ctb = ps_sps->i4_pic_size_in_ctb;
1104
1105        memset(ps_codec->pu1_parse_map, 0, num_ctb);
1106
1107        memset(ps_codec->pu1_proc_map, 0, num_ctb);
1108    }
1109
1110
1111
1112    /* Initialize disp buf id to -1, this will be updated at the end of frame if there is
1113     * buffer to be displayed
1114     */
1115    ps_codec->i4_disp_buf_id = -1;
1116    ps_codec->ps_disp_buf = NULL;
1117
1118    ps_codec->i4_disable_deblk_pic  = 0;
1119    ps_codec->i4_disable_sao_pic    = 0;
1120    ps_codec->i4_fullpel_inter_pred = 0;
1121    ps_codec->i4_mv_frac_mask       = 0x7FFFFFFF;
1122
1123    /* If degrade is enabled, set the degrade flags appropriately */
1124    if(ps_codec->i4_degrade_type && ps_codec->i4_degrade_pics)
1125    {
1126        WORD32 degrade_pic;
1127        ps_codec->i4_degrade_pic_cnt++;
1128        degrade_pic = 0;
1129
1130        /* If degrade is to be done in all frames, then do not check further */
1131        switch(ps_codec->i4_degrade_pics)
1132        {
1133            case 4:
1134            {
1135                degrade_pic = 1;
1136                break;
1137            }
1138            case 3:
1139            {
1140                if(ps_slice_hdr->i1_slice_type != ISLICE)
1141                    degrade_pic = 1;
1142
1143                break;
1144            }
1145            case 2:
1146            {
1147
1148                /* If pic count hits non-degrade interval or it is an islice, then do not degrade */
1149                if((ps_slice_hdr->i1_slice_type != ISLICE) &&
1150                   (ps_codec->i4_degrade_pic_cnt != ps_codec->i4_nondegrade_interval))
1151                    degrade_pic = 1;
1152
1153                break;
1154            }
1155            case 1:
1156            {
1157                /* Check if the current picture is non-ref */
1158                if((ps_slice_hdr->i1_nal_unit_type < NAL_BLA_W_LP) &&
1159                   (ps_slice_hdr->i1_nal_unit_type % 2 == 0))
1160                {
1161                    degrade_pic = 1;
1162                }
1163                break;
1164            }
1165
1166
1167        }
1168        if(degrade_pic)
1169        {
1170            if(ps_codec->i4_degrade_type & 0x1)
1171                ps_codec->i4_disable_sao_pic = 1;
1172
1173            if(ps_codec->i4_degrade_type & 0x2)
1174                ps_codec->i4_disable_deblk_pic = 1;
1175
1176            /* MC degrading is done only for non-ref pictures */
1177            if((ps_slice_hdr->i1_nal_unit_type < NAL_BLA_W_LP) &&
1178               (ps_slice_hdr->i1_nal_unit_type % 2 == 0))
1179            {
1180                if(ps_codec->i4_degrade_type & 0x4)
1181                    ps_codec->i4_mv_frac_mask = 0;
1182
1183                if(ps_codec->i4_degrade_type & 0x8)
1184                    ps_codec->i4_mv_frac_mask = 0;
1185            }
1186        }
1187        else
1188            ps_codec->i4_degrade_pic_cnt = 0;
1189    }
1190
1191
1192    {
1193        WORD32 i;
1194        for(i = 0; i < MAX_PROCESS_THREADS; i++)
1195        {
1196            ps_codec->as_process[i].pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx;
1197            ps_codec->as_process[i].ps_pic_pu = ps_codec->s_parse.ps_pic_pu;
1198            ps_codec->as_process[i].pu1_pic_pu_map = ps_codec->s_parse.pu1_pic_pu_map;
1199            ps_codec->as_process[i].pu4_pic_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx;
1200            ps_codec->as_process[i].ps_pic_tu = ps_codec->s_parse.ps_pic_tu;
1201            ps_codec->as_process[i].pu1_pic_tu_map = ps_codec->s_parse.pu1_pic_tu_map;
1202            ps_codec->as_process[i].pv_pic_tu_coeff_data = ps_codec->s_parse.pv_pic_tu_coeff_data;
1203            ps_codec->as_process[i].i4_cur_mv_bank_buf_id = cur_mv_bank_buf_id;
1204            ps_codec->as_process[i].s_sao_ctxt.pu1_slice_idx = ps_codec->as_process[i].pu1_slice_idx;
1205            ps_codec->as_process[i].s_sao_ctxt.pu1_tile_idx = ps_codec->as_process[i].pu1_tile_idx;
1206
1207            /* TODO: For asynchronous api the following initializations related to picture
1208             * buffer should be moved to processing side
1209             */
1210            ps_codec->as_process[i].pu1_cur_pic_luma = pu1_cur_pic_luma;
1211            ps_codec->as_process[i].pu1_cur_pic_chroma = pu1_cur_pic_chroma;
1212            ps_codec->as_process[i].ps_cur_pic = ps_cur_pic;
1213            ps_codec->as_process[i].i4_cur_pic_buf_id = cur_pic_buf_id;
1214
1215            ps_codec->as_process[i].ps_out_buffer = ps_codec->ps_out_buffer;
1216            if(1 < ps_codec->i4_num_cores)
1217            {
1218                ps_codec->as_process[i].i4_check_parse_status = 1;
1219                ps_codec->as_process[i].i4_check_proc_status = 1;
1220            }
1221            else
1222            {
1223                ps_codec->as_process[i].i4_check_parse_status = 0;
1224                ps_codec->as_process[i].i4_check_proc_status = 0;
1225            }
1226            ps_codec->as_process[i].pu1_pic_intra_flag = ps_codec->s_parse.pu1_pic_intra_flag;
1227            ps_codec->as_process[i].pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
1228            ps_codec->as_process[i].i4_init_done = 0;
1229
1230            ps_codec->as_process[i].s_bs_ctxt.pu4_pic_tu_idx = ps_codec->as_process[i].pu4_pic_tu_idx;
1231            ps_codec->as_process[i].s_bs_ctxt.pu4_pic_pu_idx = ps_codec->as_process[i].pu4_pic_pu_idx;
1232            ps_codec->as_process[i].s_bs_ctxt.ps_pic_pu = ps_codec->as_process[i].ps_pic_pu;
1233            ps_codec->as_process[i].s_deblk_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
1234            ps_codec->as_process[i].s_deblk_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
1235            ps_codec->as_process[i].s_deblk_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
1236            ps_codec->as_process[i].s_sao_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
1237            ps_codec->as_process[i].s_sao_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
1238            ps_codec->as_process[i].s_sao_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
1239            if(i < (ps_codec->i4_num_cores - 1))
1240            {
1241                ithread_create(ps_codec->apv_process_thread_handle[i], NULL,
1242                               (void *)ihevcd_process_thread,
1243                               (void *)&ps_codec->as_process[i]);
1244                ps_codec->ai4_process_thread_created[i] = 1;
1245            }
1246            else
1247            {
1248                ps_codec->ai4_process_thread_created[i] = 0;
1249            }
1250
1251        }
1252        ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
1253        ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
1254
1255        ps_codec->s_parse.s_sao_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
1256        ps_codec->s_parse.s_sao_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
1257    }
1258    /* Since any input bitstream buffer that contains slice data will be sent to output(even in
1259     * case of error, this buffer is added to display queue and next buffer in the display queue
1260     * will be returned as the display buffer.
1261     * Note: If format conversion (or frame copy) is used and is scheduled
1262     * in a different thread then it has to check if the processing for the current row is complete before
1263     * it copies/converts a given row. In case of low delay or in case of B pictures, current frame being decoded has to be
1264     * returned, which requires a status check to ensure that the current row is reconstructed before copying.
1265     */
1266    /* Add current picture to display manager */
1267    {
1268        WORD32 abs_poc;
1269        slice_header_t *ps_slice_hdr;
1270        ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr;
1271        abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
1272        ihevc_disp_mgr_add((disp_mgr_t *)ps_codec->pv_disp_buf_mgr,
1273                           ps_codec->as_process[0].i4_cur_pic_buf_id,
1274                           abs_poc,
1275                           ps_codec->as_process[0].ps_cur_pic);
1276    }
1277    ps_codec->ps_disp_buf = NULL;
1278    /* Get picture to be displayed if number of pictures decoded is more than max allowed reorder */
1279    /* Since the current will be decoded, check is fore >= instead of > */
1280    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]) ||
1281       (ps_codec->e_frm_out_mode == IVD_DECODE_FRAME_OUT))
1282
1283    {
1284        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);
1285        ps_codec->u4_disp_cnt++;
1286    }
1287
1288    ps_codec->s_fmt_conv.i4_cur_row = 0;
1289    /* Set number of rows to be processed at a time */
1290    ps_codec->s_fmt_conv.i4_num_rows = 4;
1291
1292    if(ps_codec->u4_enable_fmt_conv_ahead && (ps_codec->i4_num_cores > 1))
1293    {
1294        process_ctxt_t *ps_proc;
1295
1296        /* i4_num_cores - 1 contexts are currently being used by other threads */
1297        ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1];
1298
1299        /* If the frame being decoded and displayed are different, schedule format conversion jobs
1300         * this will keep the proc threads busy and lets parse thread decode few CTBs ahead
1301         * If the frame being decoded and displayed are same, then format conversion is scheduled later.
1302         */
1303        if((ps_codec->ps_disp_buf) && (ps_codec->i4_disp_buf_id != ps_proc->i4_cur_pic_buf_id) &&
1304           ((0 == ps_codec->i4_share_disp_buf) || (IV_YUV_420P == ps_codec->e_chroma_fmt)))
1305        {
1306
1307            for(i = 0; i < ps_sps->i2_pic_ht_in_ctb; i++)
1308            {
1309                proc_job_t s_job;
1310                IHEVCD_ERROR_T ret;
1311                s_job.i4_cmd = CMD_FMTCONV;
1312                s_job.i2_ctb_cnt = 0;
1313                s_job.i2_ctb_x = 0;
1314                s_job.i2_ctb_y = i;
1315                s_job.i2_slice_idx = 0;
1316                s_job.i4_tu_coeff_data_ofst = 0;
1317                ret = ihevcd_jobq_queue((jobq_t *)ps_codec->s_parse.pv_proc_jobq,
1318                                        &s_job, sizeof(proc_job_t), 1);
1319                if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
1320                    return ret;
1321            }
1322        }
1323    }
1324
1325    /* If parse_pic_init is called, then slice data is present in the input bitstrea stream */
1326    ps_codec->i4_pic_present = 1;
1327
1328    return ret;
1329}
1330
1331
1332