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            buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, ps_pic_buf, i);
522
523
524            if(0 != buf_ret)
525            {
526                ps_codec->s_parse.i4_error_code = IHEVCD_BUF_MGR_ERROR;
527                return IHEVCD_BUF_MGR_ERROR;
528            }
529            ps_pic_buf++;
530        }
531    }
532    else
533    {
534        /* In case of shared mode, buffers are added without adjusting for padding.
535           Update luma and chroma pointers here to account for padding as per stride.
536           In some cases stride might not be available when set_display_frame is called.
537           Hence updated luma and chroma pointers here */
538
539        for(i = 0; i < BUF_MGR_MAX_CNT; i++)
540        {
541            ps_pic_buf = ihevc_buf_mgr_get_buf((buf_mgr_t *)ps_codec->pv_pic_buf_mgr, i);
542            if((NULL == ps_pic_buf) ||
543               (NULL == ps_pic_buf->pu1_luma) ||
544               (NULL == ps_pic_buf->pu1_chroma))
545            {
546                break;
547            }
548            ps_pic_buf->pu1_luma += ps_codec->i4_strd * PAD_TOP + PAD_LEFT;
549            ps_pic_buf->pu1_chroma += ps_codec->i4_strd * (PAD_TOP / 2) + PAD_LEFT;
550        }
551    }
552
553    return ret;
554}
555/**
556*******************************************************************************
557*
558* @brief
559*  Function to add buffers to MV Bank buffer manager
560*
561* @par Description:
562*  Function to add buffers to MV Bank buffer manager
563*  To be called once per stream or for every reset
564*
565* @param[in] ps_codec
566*  Pointer to codec context
567*
568* @returns  Error from IHEVCD_ERROR_T
569*
570* @remarks
571*
572*
573*******************************************************************************
574*/
575IHEVCD_ERROR_T ihevcd_mv_buf_mgr_add_bufs(codec_t *ps_codec)
576{
577    IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
578    WORD32 i;
579    WORD32 max_dpb_size;
580    WORD32 mv_bank_size_allocated;
581    WORD32 pic_mv_bank_size;
582
583    sps_t *ps_sps;
584    UWORD8 *pu1_buf;
585    mv_buf_t *ps_mv_buf;
586
587
588    /* Initialize MV Bank buffer manager */
589    ps_sps = ps_codec->s_parse.ps_sps;
590
591
592    /* Compute the number of MV Bank buffers needed */
593    max_dpb_size = ps_sps->ai1_sps_max_dec_pic_buffering[ps_sps->i1_sps_max_sub_layers - 1];
594
595    /* Allocate one extra MV Bank to handle current frame
596     * In case of asynchronous parsing and processing, number of buffers should increase here
597     * based on when parsing and processing threads are synchronized
598     */
599    max_dpb_size++;
600
601    pu1_buf = (UWORD8 *)ps_codec->pv_mv_bank_buf_base;
602
603    ps_mv_buf = (mv_buf_t *)pu1_buf;
604    pu1_buf += max_dpb_size * sizeof(mv_buf_t);
605    ps_codec->ps_mv_buf = ps_mv_buf;
606    mv_bank_size_allocated = ps_codec->i4_total_mv_bank_size - max_dpb_size  * sizeof(mv_buf_t);
607
608    /* Compute MV bank size per picture */
609    pic_mv_bank_size = ihevcd_get_pic_mv_bank_size(ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
610                                                   ALIGN64(ps_sps->i2_pic_height_in_luma_samples));
611
612    for(i = 0; i < max_dpb_size; i++)
613    {
614        WORD32 buf_ret;
615        WORD32 num_pu;
616        WORD32 num_ctb;
617        WORD32 pic_size;
618        pic_size = ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
619                        ALIGN64(ps_sps->i2_pic_height_in_luma_samples);
620
621
622        num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE);
623        num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);
624
625
626        mv_bank_size_allocated -= pic_mv_bank_size;
627
628        if(mv_bank_size_allocated < 0)
629        {
630            ps_codec->s_parse.i4_error_code = IHEVCD_INSUFFICIENT_MEM_MVBANK;
631            return IHEVCD_INSUFFICIENT_MEM_MVBANK;
632        }
633
634        ps_mv_buf->pu4_pic_pu_idx = (UWORD32 *)pu1_buf;
635        pu1_buf += (num_ctb + 1) * sizeof(WORD32);
636
637        ps_mv_buf->pu1_pic_pu_map = pu1_buf;
638        pu1_buf += num_pu;
639
640        ps_mv_buf->pu1_pic_slice_map = (UWORD16 *)pu1_buf;
641        pu1_buf += ALIGN4(num_ctb * sizeof(UWORD16));
642
643        ps_mv_buf->ps_pic_pu = (pu_t *)pu1_buf;
644        pu1_buf += num_pu * sizeof(pu_t);
645
646        buf_ret = ihevc_buf_mgr_add((buf_mgr_t *)ps_codec->pv_mv_buf_mgr, ps_mv_buf, i);
647
648        if(0 != buf_ret)
649        {
650            ps_codec->s_parse.i4_error_code = IHEVCD_BUF_MGR_ERROR;
651            return IHEVCD_BUF_MGR_ERROR;
652        }
653
654        ps_mv_buf++;
655
656    }
657    return ret;
658}
659/**
660*******************************************************************************
661*
662* @brief
663*  Picture level initializations required during parsing
664*
665* @par Description:
666*  Initialize picture level context variables during parsing Initialize mv
667* bank buffer manager in the first init call
668*
669* @param[in] ps_codec
670*  Pointer to codec context
671*
672* @returns  Error from IHEVCD_ERROR_T
673*
674* @remarks
675*
676*
677*******************************************************************************
678*/
679IHEVCD_ERROR_T ihevcd_parse_pic_init(codec_t *ps_codec)
680{
681    IHEVCD_ERROR_T ret = (IHEVCD_ERROR_T)IHEVCD_SUCCESS;
682    mv_buf_t *ps_mv_buf;
683    sps_t *ps_sps;
684    WORD32 num_min_cu;
685    WORD32 cur_pic_buf_id;
686    WORD32 cur_mv_bank_buf_id;
687    pic_buf_t *ps_cur_pic;
688    slice_header_t *ps_slice_hdr;
689    UWORD8 *pu1_cur_pic_luma, *pu1_cur_pic_chroma;
690    WORD32 i;
691
692    ps_codec->s_parse.i4_error_code = IHEVCD_SUCCESS;
693    ps_sps = ps_codec->s_parse.ps_sps;
694    ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr;
695    /* If parse_pic_init is called, then slice data is present in the input bitstrea stream */
696    ps_codec->i4_pic_present = 1;
697
698    /* Memset picture level intra map and transquant bypass map to zero */
699    num_min_cu = ((ps_sps->i2_pic_height_in_luma_samples + 7) / 8) * ((ps_sps->i2_pic_width_in_luma_samples + 63) / 64);
700    memset(ps_codec->s_parse.pu1_pic_intra_flag, 0, num_min_cu);
701    memset(ps_codec->s_parse.pu1_pic_no_loop_filter_flag, 0, num_min_cu);
702
703
704
705    if(0 == ps_codec->s_parse.i4_first_pic_init)
706    {
707        ret = ihevcd_mv_buf_mgr_add_bufs(ps_codec);
708        RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
709
710        ret = ihevcd_pic_buf_mgr_add_bufs(ps_codec);
711        RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
712
713        ps_codec->s_parse.i4_first_pic_init = 1;
714    }
715
716    /* Initialize all the slice headers' slice addresses to zero */
717    {
718        WORD32 slice_idx;
719        WORD32 slice_start_idx;
720
721        slice_start_idx = ps_codec->i4_slice_error ? 2 : 1;
722
723        for(slice_idx = slice_start_idx; slice_idx < MAX_SLICE_HDR_CNT; slice_idx++)
724        {
725            slice_header_t *ps_slice_hdr_tmp = ps_codec->ps_slice_hdr_base + slice_idx;
726            ps_slice_hdr_tmp->i2_ctb_x = -1;
727            ps_slice_hdr_tmp->i2_ctb_y = -1;
728
729        }
730    }
731
732    /* Get free MV Bank to hold current picture's motion vector data */
733    {
734        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);
735
736        /* If there are no free buffers then return with an error code.
737         * If the buffer is to be freed by another thread , change the
738         * following to call thread yield and wait for buffer to be freed
739         */
740        if(NULL == ps_mv_buf)
741        {
742            ps_codec->s_parse.i4_error_code = IHEVCD_NO_FREE_MVBANK;
743            ps_codec->i4_error_code = IHEVCD_NO_FREE_MVBANK;
744            return IHEVCD_NO_FREE_MVBANK;
745        }
746
747        ps_codec->s_parse.ps_cur_mv_buf = ps_mv_buf;
748        /* Set current ABS poc to ps_mv_buf, so that while freeing a reference buffer
749         * corresponding mv buffer can be found by looping through ps_codec->ps_mv_buf array
750         * and getting a buffer id to free
751         */
752        ps_mv_buf->i4_abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
753    }
754
755    /* Get free picture buffer to hold current picture recon data */
756    /* TODO: For asynchronous api the following initializations related to picture
757     * buffer should be moved to processing side
758     */
759    {
760
761        UWORD8 *pu1_buf;
762        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);
763
764        /* If there are no free buffers then return with an error code.
765         * TODO: If the buffer is to be freed by another thread , change the
766         * following to call thread yield and wait for buffer to be freed
767         */
768        if(NULL == ps_cur_pic)
769        {
770            ps_codec->s_parse.i4_error_code = IHEVCD_NO_FREE_PICBUF;
771            ps_codec->i4_error_code = IHEVCD_NO_FREE_PICBUF;
772            return IHEVCD_NO_FREE_PICBUF;
773        }
774
775        /* Store input timestamp sent with input buffer */
776        ps_cur_pic->u4_ts = ps_codec->u4_ts;
777        ps_cur_pic->i4_abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
778        ps_cur_pic->i4_poc_lsb = ps_slice_hdr->i4_pic_order_cnt_lsb;
779        pu1_buf = ps_cur_pic->pu1_luma;
780        pu1_cur_pic_luma = pu1_buf;
781
782        pu1_buf = ps_cur_pic->pu1_chroma;
783
784        pu1_cur_pic_chroma = pu1_buf;
785    }
786
787    if(0 == ps_codec->u4_pic_cnt)
788    {
789        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);
790        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);
791    }
792
793    /* Fill the remaining entries of the reference lists with the nearest POC
794     * This is done to handle cases where there is a corruption in the reference index */
795    {
796        pic_buf_t *ps_pic_buf_ref;
797        mv_buf_t *ps_mv_buf_ref;
798        WORD32 r_idx;
799        dpb_mgr_t *ps_dpb_mgr = (dpb_mgr_t *)ps_codec->pv_dpb_mgr;
800        buf_mgr_t *ps_mv_buf_mgr = (buf_mgr_t *)ps_codec->pv_mv_buf_mgr;
801
802        ps_pic_buf_ref = ihevc_dpb_mgr_get_ref_by_nearest_poc(ps_dpb_mgr, ps_slice_hdr->i4_abs_pic_order_cnt);
803        if(NULL == ps_pic_buf_ref)
804        {
805            WORD32 size;
806
807            WORD32 num_pu;
808            WORD32 num_ctb;
809            WORD32 pic_size;
810            /* In case current mv buffer itself is being used as reference mv buffer for colocated
811             * calculations, then memset all the buffers to zero.
812             */
813            pic_size = ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
814                            ALIGN64(ps_sps->i2_pic_height_in_luma_samples);
815
816            num_pu = pic_size / (MIN_PU_SIZE * MIN_PU_SIZE);
817            num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);
818
819            memset(ps_mv_buf->ai4_l0_collocated_poc, 0, sizeof(ps_mv_buf->ai4_l0_collocated_poc));
820            memset(ps_mv_buf->ai1_l0_collocated_poc_lt, 0, sizeof(ps_mv_buf->ai1_l0_collocated_poc_lt));
821            memset(ps_mv_buf->ai4_l1_collocated_poc, 0, sizeof(ps_mv_buf->ai4_l1_collocated_poc));
822            memset(ps_mv_buf->ai1_l1_collocated_poc_lt, 0, sizeof(ps_mv_buf->ai1_l1_collocated_poc_lt));
823
824            size = (num_ctb + 1) * sizeof(WORD32);
825            memset(ps_mv_buf->pu4_pic_pu_idx, 0, size);
826
827            size = num_pu;
828            memset(ps_mv_buf->pu1_pic_pu_map, 0, size);
829            size = ALIGN4(num_ctb * sizeof(UWORD16));
830            memset(ps_mv_buf->pu1_pic_slice_map, 0, size);
831            size = num_pu * sizeof(pu_t);
832            memset(ps_mv_buf->ps_pic_pu, 0, size);
833
834            ps_pic_buf_ref = ps_cur_pic;
835            ps_mv_buf_ref = ps_mv_buf;
836        }
837        else
838        {
839            ps_mv_buf_ref = ihevcd_mv_mgr_get_poc(ps_mv_buf_mgr, ps_pic_buf_ref->i4_abs_poc);
840        }
841
842        for(r_idx = 0; r_idx < ps_slice_hdr->i1_num_ref_idx_l0_active; r_idx++)
843        {
844            if(NULL == ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf)
845            {
846                ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
847                ps_slice_hdr->as_ref_pic_list0[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
848            }
849        }
850
851        for(r_idx = ps_slice_hdr->i1_num_ref_idx_l0_active; r_idx < MAX_DPB_SIZE; r_idx++)
852        {
853            ps_slice_hdr->as_ref_pic_list0[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
854            ps_slice_hdr->as_ref_pic_list0[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
855        }
856
857        for(r_idx = 0; r_idx < ps_slice_hdr->i1_num_ref_idx_l1_active; r_idx++)
858        {
859            if(NULL == ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf)
860            {
861                ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
862                ps_slice_hdr->as_ref_pic_list1[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
863            }
864        }
865
866        for(r_idx = ps_slice_hdr->i1_num_ref_idx_l1_active; r_idx < MAX_DPB_SIZE; r_idx++)
867        {
868            ps_slice_hdr->as_ref_pic_list1[r_idx].pv_pic_buf = (void *)ps_pic_buf_ref;
869            ps_slice_hdr->as_ref_pic_list1[r_idx].pv_mv_buf = (void *)ps_mv_buf_ref;
870        }
871    }
872
873
874    /* Reset the jobq to start of the jobq buffer */
875    ihevcd_jobq_reset((jobq_t *)ps_codec->pv_proc_jobq);
876
877    ps_codec->s_parse.i4_pic_pu_idx = 0;
878    ps_codec->s_parse.i4_pic_tu_idx = 0;
879
880    ps_codec->s_parse.pu1_pic_pu_map = ps_mv_buf->pu1_pic_pu_map;
881    ps_codec->s_parse.ps_pic_pu      = ps_mv_buf->ps_pic_pu;
882    ps_codec->s_parse.pu4_pic_pu_idx = ps_mv_buf->pu4_pic_pu_idx;
883    ps_codec->s_parse.pu1_slice_idx = (UWORD16 *)ps_mv_buf->pu1_pic_slice_map;
884    for(i = 0; i < MAX_PROCESS_THREADS; i++)
885    {
886        ps_codec->as_process[i].pu1_slice_idx = (UWORD16 *)ps_mv_buf->pu1_pic_slice_map;
887    }
888    ps_codec->s_parse.pu1_pu_map = ps_codec->s_parse.pu1_pic_pu_map;
889    ps_codec->s_parse.ps_pu = ps_codec->s_parse.ps_pic_pu;
890
891    {
892        UWORD8 *pu1_buf;
893        WORD32 ctb_luma_min_tu_cnt, ctb_chroma_min_tu_cnt, ctb_min_tu_cnt;
894        WORD32 pic_size;
895        WORD32 num_ctb;
896
897        pic_size = ALIGN64(ps_sps->i2_pic_width_in_luma_samples) *
898                        ALIGN64(ps_sps->i2_pic_height_in_luma_samples);
899
900        ctb_luma_min_tu_cnt = pic_size / (MIN_TU_SIZE * MIN_TU_SIZE);
901
902        ctb_chroma_min_tu_cnt = ctb_luma_min_tu_cnt >> 1;
903
904        ctb_min_tu_cnt = ctb_luma_min_tu_cnt + ctb_chroma_min_tu_cnt;
905
906        num_ctb = pic_size / (MIN_CTB_SIZE * MIN_CTB_SIZE);
907        pu1_buf  = (UWORD8 *)ps_codec->pv_tu_data;
908        ps_codec->s_parse.pu4_pic_tu_idx = (UWORD32 *)pu1_buf;
909        pu1_buf += (num_ctb + 1) * sizeof(WORD32);
910
911        ps_codec->s_parse.pu1_pic_tu_map = pu1_buf;
912        pu1_buf += ctb_min_tu_cnt;
913
914        ps_codec->s_parse.ps_pic_tu = (tu_t *)pu1_buf;
915        pu1_buf += ctb_min_tu_cnt * sizeof(tu_t);
916
917        ps_codec->s_parse.pv_pic_tu_coeff_data = pu1_buf;
918
919        ps_codec->s_parse.pu1_tu_map = ps_codec->s_parse.pu1_pic_tu_map;
920        ps_codec->s_parse.ps_tu = ps_codec->s_parse.ps_pic_tu;
921        ps_codec->s_parse.pv_tu_coeff_data = ps_codec->s_parse.pv_pic_tu_coeff_data;
922    }
923
924    ps_codec->s_parse.s_bs_ctxt.ps_pic_pu = ps_codec->s_parse.ps_pic_pu;
925    ps_codec->s_parse.s_bs_ctxt.pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx;
926    ps_codec->s_parse.s_bs_ctxt.pu4_pic_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx;
927
928
929    /* Set number of CTBs to be processed simultaneously */
930    ps_codec->i4_proc_nctb = ihevcd_nctb_cnt(ps_codec, ps_sps);
931
932    /* Memset Parse Map and process map at the start of frame */
933    //TODO: In case of asynchronous API proc_map can not be set to zero here
934    {
935        WORD32 num_ctb;
936
937        num_ctb = ps_sps->i4_pic_size_in_ctb;
938
939        memset(ps_codec->pu1_parse_map, 0, num_ctb);
940
941        memset(ps_codec->pu1_proc_map, 0, num_ctb);
942    }
943
944
945
946    /* Initialize disp buf id to -1, this will be updated at the end of frame if there is
947     * buffer to be displayed
948     */
949    ps_codec->i4_disp_buf_id = -1;
950    ps_codec->ps_disp_buf = NULL;
951
952    ps_codec->i4_disable_deblk_pic  = 0;
953    ps_codec->i4_disable_sao_pic    = 0;
954    ps_codec->i4_fullpel_inter_pred = 0;
955    ps_codec->i4_mv_frac_mask       = 0x7FFFFFFF;
956
957    /* If degrade is enabled, set the degrade flags appropriately */
958    if(ps_codec->i4_degrade_type && ps_codec->i4_degrade_pics)
959    {
960        WORD32 degrade_pic;
961        ps_codec->i4_degrade_pic_cnt++;
962        degrade_pic = 0;
963
964        /* If degrade is to be done in all frames, then do not check further */
965        switch(ps_codec->i4_degrade_pics)
966        {
967            case 4:
968            {
969                degrade_pic = 1;
970                break;
971            }
972            case 3:
973            {
974                if(ps_slice_hdr->i1_slice_type != ISLICE)
975                    degrade_pic = 1;
976
977                break;
978            }
979            case 2:
980            {
981
982                /* If pic count hits non-degrade interval or it is an islice, then do not degrade */
983                if((ps_slice_hdr->i1_slice_type != ISLICE) &&
984                   (ps_codec->i4_degrade_pic_cnt != ps_codec->i4_nondegrade_interval))
985                    degrade_pic = 1;
986
987                break;
988            }
989            case 1:
990            {
991                /* Check if the current picture is non-ref */
992                if((ps_slice_hdr->i1_nal_unit_type < NAL_BLA_W_LP) &&
993                   (ps_slice_hdr->i1_nal_unit_type % 2 == 0))
994                {
995                    degrade_pic = 1;
996                }
997                break;
998            }
999
1000
1001        }
1002        if(degrade_pic)
1003        {
1004            if(ps_codec->i4_degrade_type & 0x1)
1005                ps_codec->i4_disable_sao_pic = 1;
1006
1007            if(ps_codec->i4_degrade_type & 0x2)
1008                ps_codec->i4_disable_deblk_pic = 1;
1009
1010            /* MC degrading is done only for non-ref pictures */
1011            if((ps_slice_hdr->i1_nal_unit_type < NAL_BLA_W_LP) &&
1012               (ps_slice_hdr->i1_nal_unit_type % 2 == 0))
1013            {
1014                if(ps_codec->i4_degrade_type & 0x4)
1015                    ps_codec->i4_mv_frac_mask = 0;
1016
1017                if(ps_codec->i4_degrade_type & 0x8)
1018                    ps_codec->i4_mv_frac_mask = 0;
1019            }
1020        }
1021        else
1022            ps_codec->i4_degrade_pic_cnt = 0;
1023    }
1024
1025
1026    {
1027        WORD32 i;
1028        for(i = 0; i < MAX_PROCESS_THREADS; i++)
1029        {
1030            ps_codec->as_process[i].pu4_pic_pu_idx = ps_codec->s_parse.pu4_pic_pu_idx;
1031            ps_codec->as_process[i].ps_pic_pu = ps_codec->s_parse.ps_pic_pu;
1032            ps_codec->as_process[i].pu1_pic_pu_map = ps_codec->s_parse.pu1_pic_pu_map;
1033            ps_codec->as_process[i].pu4_pic_tu_idx = ps_codec->s_parse.pu4_pic_tu_idx;
1034            ps_codec->as_process[i].ps_pic_tu = ps_codec->s_parse.ps_pic_tu;
1035            ps_codec->as_process[i].pu1_pic_tu_map = ps_codec->s_parse.pu1_pic_tu_map;
1036            ps_codec->as_process[i].pv_pic_tu_coeff_data = ps_codec->s_parse.pv_pic_tu_coeff_data;
1037            ps_codec->as_process[i].i4_cur_mv_bank_buf_id = cur_mv_bank_buf_id;
1038            ps_codec->as_process[i].s_sao_ctxt.pu1_slice_idx = ps_codec->as_process[i].pu1_slice_idx;
1039            ps_codec->as_process[i].s_sao_ctxt.pu1_tile_idx = ps_codec->as_process[i].pu1_tile_idx;
1040
1041            /* TODO: For asynchronous api the following initializations related to picture
1042             * buffer should be moved to processing side
1043             */
1044            ps_codec->as_process[i].pu1_cur_pic_luma = pu1_cur_pic_luma;
1045            ps_codec->as_process[i].pu1_cur_pic_chroma = pu1_cur_pic_chroma;
1046            ps_codec->as_process[i].ps_cur_pic = ps_cur_pic;
1047            ps_codec->as_process[i].i4_cur_pic_buf_id = cur_pic_buf_id;
1048
1049            ps_codec->as_process[i].ps_out_buffer = ps_codec->ps_out_buffer;
1050            if(1 < ps_codec->i4_num_cores)
1051            {
1052                ps_codec->as_process[i].i4_check_parse_status = 1;
1053                ps_codec->as_process[i].i4_check_proc_status = 1;
1054            }
1055            else
1056            {
1057                ps_codec->as_process[i].i4_check_parse_status = 0;
1058                ps_codec->as_process[i].i4_check_proc_status = 0;
1059            }
1060            ps_codec->as_process[i].pu1_pic_intra_flag = ps_codec->s_parse.pu1_pic_intra_flag;
1061            ps_codec->as_process[i].pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
1062            ps_codec->as_process[i].i4_init_done = 0;
1063
1064            ps_codec->as_process[i].s_bs_ctxt.pu4_pic_tu_idx = ps_codec->as_process[i].pu4_pic_tu_idx;
1065            ps_codec->as_process[i].s_bs_ctxt.pu4_pic_pu_idx = ps_codec->as_process[i].pu4_pic_pu_idx;
1066            ps_codec->as_process[i].s_bs_ctxt.ps_pic_pu = ps_codec->as_process[i].ps_pic_pu;
1067            ps_codec->as_process[i].s_deblk_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
1068            ps_codec->as_process[i].s_deblk_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
1069            ps_codec->as_process[i].s_deblk_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
1070            ps_codec->as_process[i].s_sao_ctxt.pu1_pic_no_loop_filter_flag = ps_codec->s_parse.pu1_pic_no_loop_filter_flag;
1071            ps_codec->as_process[i].s_sao_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
1072            ps_codec->as_process[i].s_sao_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
1073            if(i < (ps_codec->i4_num_cores - 1))
1074            {
1075                ithread_create(ps_codec->apv_process_thread_handle[i], NULL,
1076                               (void *)ihevcd_process_thread,
1077                               (void *)&ps_codec->as_process[i]);
1078                ps_codec->ai4_process_thread_created[i] = 1;
1079            }
1080            else
1081            {
1082                ps_codec->ai4_process_thread_created[i] = 0;
1083            }
1084
1085        }
1086        ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
1087        ps_codec->s_parse.s_deblk_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
1088
1089        ps_codec->s_parse.s_sao_ctxt.pu1_cur_pic_luma = pu1_cur_pic_luma;
1090        ps_codec->s_parse.s_sao_ctxt.pu1_cur_pic_chroma = pu1_cur_pic_chroma;
1091    }
1092    /* Since any input bitstream buffer that contains slice data will be sent to output(even in
1093     * case of error, this buffer is added to display queue and next buffer in the display queue
1094     * will be returned as the display buffer.
1095     * Note: If format conversion (or frame copy) is used and is scheduled
1096     * in a different thread then it has to check if the processing for the current row is complete before
1097     * it copies/converts a given row. In case of low delay or in case of B pictures, current frame being decoded has to be
1098     * returned, which requires a status check to ensure that the current row is reconstructed before copying.
1099     */
1100    /* Add current picture to display manager */
1101    {
1102        WORD32 abs_poc;
1103        slice_header_t *ps_slice_hdr;
1104        ps_slice_hdr = ps_codec->s_parse.ps_slice_hdr;
1105        abs_poc = ps_slice_hdr->i4_abs_pic_order_cnt;
1106        ihevc_disp_mgr_add((disp_mgr_t *)ps_codec->pv_disp_buf_mgr,
1107                           ps_codec->as_process[0].i4_cur_pic_buf_id,
1108                           abs_poc,
1109                           ps_codec->as_process[0].ps_cur_pic);
1110    }
1111    ps_codec->ps_disp_buf = NULL;
1112    /* Get picture to be displayed if number of pictures decoded is more than max allowed reorder */
1113    /* Since the current will be decoded, check is fore >= instead of > */
1114    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]) ||
1115       (ps_codec->e_frm_out_mode == IVD_DECODE_FRAME_OUT))
1116
1117    {
1118        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);
1119        ps_codec->u4_disp_cnt++;
1120    }
1121
1122    ps_codec->s_fmt_conv.i4_cur_row = 0;
1123    /* Set number of rows to be processed at a time */
1124    ps_codec->s_fmt_conv.i4_num_rows = 4;
1125
1126    if(ps_codec->u4_enable_fmt_conv_ahead && (ps_codec->i4_num_cores > 1))
1127    {
1128        process_ctxt_t *ps_proc;
1129
1130        /* i4_num_cores - 1 contexts are currently being used by other threads */
1131        ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1];
1132
1133        /* If the frame being decoded and displayed are different, schedule format conversion jobs
1134         * this will keep the proc threads busy and lets parse thread decode few CTBs ahead
1135         * If the frame being decoded and displayed are same, then format conversion is scheduled later.
1136         */
1137        if((ps_codec->ps_disp_buf) && (ps_codec->i4_disp_buf_id != ps_proc->i4_cur_pic_buf_id) &&
1138           ((0 == ps_codec->i4_share_disp_buf) || (IV_YUV_420P == ps_codec->e_chroma_fmt)))
1139        {
1140
1141            for(i = 0; i < ps_sps->i2_pic_ht_in_ctb; i++)
1142            {
1143                proc_job_t s_job;
1144                IHEVCD_ERROR_T ret;
1145                s_job.i4_cmd = CMD_FMTCONV;
1146                s_job.i2_ctb_cnt = 0;
1147                s_job.i2_ctb_x = 0;
1148                s_job.i2_ctb_y = i;
1149                s_job.i2_slice_idx = 0;
1150                s_job.i4_tu_coeff_data_ofst = 0;
1151                ret = ihevcd_jobq_queue((jobq_t *)ps_codec->s_parse.pv_proc_jobq,
1152                                        &s_job, sizeof(proc_job_t), 1);
1153                if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
1154                    return ret;
1155            }
1156        }
1157    }
1158
1159
1160    return ret;
1161}
1162
1163
1164