xref: /aosp_15_r20/external/libhevc/decoder/ihevcd_decode.c (revision c83a76b084498d55f252f48b2e3786804cdf24b7)
1*c83a76b0SSuyog Pawar /******************************************************************************
2*c83a76b0SSuyog Pawar *
3*c83a76b0SSuyog Pawar * Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
4*c83a76b0SSuyog Pawar *
5*c83a76b0SSuyog Pawar * Licensed under the Apache License, Version 2.0 (the "License");
6*c83a76b0SSuyog Pawar * you may not use this file except in compliance with the License.
7*c83a76b0SSuyog Pawar * You may obtain a copy of the License at:
8*c83a76b0SSuyog Pawar *
9*c83a76b0SSuyog Pawar * http://www.apache.org/licenses/LICENSE-2.0
10*c83a76b0SSuyog Pawar *
11*c83a76b0SSuyog Pawar * Unless required by applicable law or agreed to in writing, software
12*c83a76b0SSuyog Pawar * distributed under the License is distributed on an "AS IS" BASIS,
13*c83a76b0SSuyog Pawar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*c83a76b0SSuyog Pawar * See the License for the specific language governing permissions and
15*c83a76b0SSuyog Pawar * limitations under the License.
16*c83a76b0SSuyog Pawar *
17*c83a76b0SSuyog Pawar ******************************************************************************/
18*c83a76b0SSuyog Pawar /**
19*c83a76b0SSuyog Pawar  *******************************************************************************
20*c83a76b0SSuyog Pawar  * @file
21*c83a76b0SSuyog Pawar  *  ihevcd_decode.c
22*c83a76b0SSuyog Pawar  *
23*c83a76b0SSuyog Pawar  * @brief
24*c83a76b0SSuyog Pawar  *  Contains codecs main decode function
25*c83a76b0SSuyog Pawar  *
26*c83a76b0SSuyog Pawar  * @author
27*c83a76b0SSuyog Pawar  *  Harish
28*c83a76b0SSuyog Pawar  *
29*c83a76b0SSuyog Pawar  * @par List of Functions:
30*c83a76b0SSuyog Pawar  * - fill_outargs()
31*c83a76b0SSuyog Pawar  * - ihevcd_decode
32*c83a76b0SSuyog Pawar  * @remarks
33*c83a76b0SSuyog Pawar  *  None
34*c83a76b0SSuyog Pawar  *
35*c83a76b0SSuyog Pawar  *******************************************************************************
36*c83a76b0SSuyog Pawar  */
37*c83a76b0SSuyog Pawar /*****************************************************************************/
38*c83a76b0SSuyog Pawar /* File Includes                                                             */
39*c83a76b0SSuyog Pawar /*****************************************************************************/
40*c83a76b0SSuyog Pawar #include <stdio.h>
41*c83a76b0SSuyog Pawar #include <stddef.h>
42*c83a76b0SSuyog Pawar #include <stdlib.h>
43*c83a76b0SSuyog Pawar #include <string.h>
44*c83a76b0SSuyog Pawar #include <assert.h>
45*c83a76b0SSuyog Pawar 
46*c83a76b0SSuyog Pawar #include "ihevc_typedefs.h"
47*c83a76b0SSuyog Pawar #include "iv.h"
48*c83a76b0SSuyog Pawar #include "ivd.h"
49*c83a76b0SSuyog Pawar #include "ihevcd_cxa.h"
50*c83a76b0SSuyog Pawar #include "ithread.h"
51*c83a76b0SSuyog Pawar 
52*c83a76b0SSuyog Pawar #include "ihevc_defs.h"
53*c83a76b0SSuyog Pawar #include "ihevc_debug.h"
54*c83a76b0SSuyog Pawar #include "ihevc_structs.h"
55*c83a76b0SSuyog Pawar #include "ihevc_macros.h"
56*c83a76b0SSuyog Pawar #include "ihevc_platform_macros.h"
57*c83a76b0SSuyog Pawar #include "ihevc_cabac_tables.h"
58*c83a76b0SSuyog Pawar #include "ihevc_disp_mgr.h"
59*c83a76b0SSuyog Pawar #include "ihevc_buf_mgr.h"
60*c83a76b0SSuyog Pawar #include "ihevc_dpb_mgr.h"
61*c83a76b0SSuyog Pawar #include "ihevc_error.h"
62*c83a76b0SSuyog Pawar 
63*c83a76b0SSuyog Pawar #include "ihevcd_defs.h"
64*c83a76b0SSuyog Pawar #include "ihevcd_function_selector.h"
65*c83a76b0SSuyog Pawar #include "ihevcd_structs.h"
66*c83a76b0SSuyog Pawar #include "ihevcd_error.h"
67*c83a76b0SSuyog Pawar #include "ihevcd_nal.h"
68*c83a76b0SSuyog Pawar #include "ihevcd_bitstream.h"
69*c83a76b0SSuyog Pawar #include "ihevcd_fmt_conv.h"
70*c83a76b0SSuyog Pawar #include "ihevcd_job_queue.h"
71*c83a76b0SSuyog Pawar #include "ihevcd_debug.h"
72*c83a76b0SSuyog Pawar #include "ihevcd_parse_slice.h"
73*c83a76b0SSuyog Pawar #include "ihevcd_process_slice.h"
74*c83a76b0SSuyog Pawar #include "ihevcd_ittiam_logo.h"
75*c83a76b0SSuyog Pawar #include "ihevcd_profile.h"
76*c83a76b0SSuyog Pawar 
77*c83a76b0SSuyog Pawar #define NUM_FRAMES_LIMIT_ENABLED 0
78*c83a76b0SSuyog Pawar 
79*c83a76b0SSuyog Pawar #if NUM_FRAMES_LIMIT_ENABLED
80*c83a76b0SSuyog Pawar #define NUM_FRAMES_LIMIT 10000
81*c83a76b0SSuyog Pawar #else
82*c83a76b0SSuyog Pawar #define NUM_FRAMES_LIMIT 0x7FFFFFFF
83*c83a76b0SSuyog Pawar #endif
84*c83a76b0SSuyog Pawar 
85*c83a76b0SSuyog Pawar IHEVCD_ERROR_T ihevcd_check_out_buf_size(codec_t *ps_codec);
86*c83a76b0SSuyog Pawar IHEVCD_ERROR_T ihevcd_fmt_conv(codec_t *ps_codec,
87*c83a76b0SSuyog Pawar                                process_ctxt_t *ps_proc,
88*c83a76b0SSuyog Pawar                                UWORD8 *pu1_y_dst,
89*c83a76b0SSuyog Pawar                                UWORD8 *pu1_u_dst,
90*c83a76b0SSuyog Pawar                                UWORD8 *pu1_v_dst,
91*c83a76b0SSuyog Pawar                                WORD32 cur_row,
92*c83a76b0SSuyog Pawar                                WORD32 num_rows);
93*c83a76b0SSuyog Pawar WORD32 ihevcd_init(codec_t *ps_codec);
94*c83a76b0SSuyog Pawar 
95*c83a76b0SSuyog Pawar WORD32 ihevcd_allocate_dynamic_bufs(codec_t *ps_codec);
96*c83a76b0SSuyog Pawar WORD32 ihevcd_free_dynamic_bufs(codec_t *ps_codec);
97*c83a76b0SSuyog Pawar /*****************************************************************************/
98*c83a76b0SSuyog Pawar /* Function Prototypes                                                       */
99*c83a76b0SSuyog Pawar /*****************************************************************************/
100*c83a76b0SSuyog Pawar 
101*c83a76b0SSuyog Pawar 
102*c83a76b0SSuyog Pawar /**
103*c83a76b0SSuyog Pawar  *******************************************************************************
104*c83a76b0SSuyog Pawar  *
105*c83a76b0SSuyog Pawar  * @brief Fills output arguments for decode process
106*c83a76b0SSuyog Pawar  *
107*c83a76b0SSuyog Pawar  * @par   Description
108*c83a76b0SSuyog Pawar  * Fills elements in the output structure based on the current state
109*c83a76b0SSuyog Pawar  *
110*c83a76b0SSuyog Pawar  * @param[in] ps_codec
111*c83a76b0SSuyog Pawar  * Codec context
112*c83a76b0SSuyog Pawar  *
113*c83a76b0SSuyog Pawar  * @param[in] ps_dec_ip
114*c83a76b0SSuyog Pawar  * Pointer to input structure
115*c83a76b0SSuyog Pawar  *
116*c83a76b0SSuyog Pawar  * @param[in] ps_dec_op
117*c83a76b0SSuyog Pawar  * Pointer to output structure
118*c83a76b0SSuyog Pawar  *
119*c83a76b0SSuyog Pawar  * @returns none
120*c83a76b0SSuyog Pawar  *
121*c83a76b0SSuyog Pawar  * @remarks
122*c83a76b0SSuyog Pawar  *
123*c83a76b0SSuyog Pawar  *******************************************************************************
124*c83a76b0SSuyog Pawar  */
ihevcd_map_error(IHEVCD_ERROR_T e_error)125*c83a76b0SSuyog Pawar static UWORD32 ihevcd_map_error(IHEVCD_ERROR_T e_error)
126*c83a76b0SSuyog Pawar {
127*c83a76b0SSuyog Pawar     UWORD32 error_code = 0;
128*c83a76b0SSuyog Pawar     error_code = e_error;
129*c83a76b0SSuyog Pawar     switch(error_code)
130*c83a76b0SSuyog Pawar     {
131*c83a76b0SSuyog Pawar         case IHEVCD_SUCCESS :
132*c83a76b0SSuyog Pawar             break;
133*c83a76b0SSuyog Pawar         case IHEVCD_INIT_NOT_DONE:
134*c83a76b0SSuyog Pawar         case IHEVCD_LEVEL_UNSUPPORTED:
135*c83a76b0SSuyog Pawar         case IHEVCD_NUM_REF_UNSUPPORTED:
136*c83a76b0SSuyog Pawar         case IHEVCD_NUM_REORDER_UNSUPPORTED:
137*c83a76b0SSuyog Pawar         case IHEVCD_NUM_EXTRA_DISP_UNSUPPORTED:
138*c83a76b0SSuyog Pawar         case IHEVCD_INSUFFICIENT_MEM_MVBANK:
139*c83a76b0SSuyog Pawar         case IHEVCD_INSUFFICIENT_MEM_PICBUF:
140*c83a76b0SSuyog Pawar         case IHEVCD_UNSUPPORTED_CHROMA_FMT_IDC:
141*c83a76b0SSuyog Pawar         case IHEVCD_UNSUPPORTED_BIT_DEPTH:
142*c83a76b0SSuyog Pawar         case IVD_MEM_ALLOC_FAILED:
143*c83a76b0SSuyog Pawar         case IVD_STREAM_WIDTH_HEIGHT_NOT_SUPPORTED:
144*c83a76b0SSuyog Pawar             error_code |= 1 << IVD_FATALERROR;
145*c83a76b0SSuyog Pawar             break;
146*c83a76b0SSuyog Pawar         case IHEVCD_INVALID_DISP_STRD:
147*c83a76b0SSuyog Pawar         case IHEVCD_CXA_VERS_BUF_INSUFFICIENT:
148*c83a76b0SSuyog Pawar         case IHEVCD_UNSUPPORTED_VPS_ID:
149*c83a76b0SSuyog Pawar         case IHEVCD_UNSUPPORTED_SPS_ID:
150*c83a76b0SSuyog Pawar         case IHEVCD_UNSUPPORTED_PPS_ID:
151*c83a76b0SSuyog Pawar         case IHEVCD_BUF_MGR_ERROR:
152*c83a76b0SSuyog Pawar         case IHEVCD_NO_FREE_MVBANK:
153*c83a76b0SSuyog Pawar         case IHEVCD_NO_FREE_PICBUF:
154*c83a76b0SSuyog Pawar         case IHEVCD_SLICE_IN_HEADER_MODE:
155*c83a76b0SSuyog Pawar         case IHEVCD_END_OF_SEQUENCE:
156*c83a76b0SSuyog Pawar             break;
157*c83a76b0SSuyog Pawar         default:
158*c83a76b0SSuyog Pawar             break;
159*c83a76b0SSuyog Pawar     }
160*c83a76b0SSuyog Pawar     return error_code;
161*c83a76b0SSuyog Pawar }
162*c83a76b0SSuyog Pawar /**
163*c83a76b0SSuyog Pawar  *******************************************************************************
164*c83a76b0SSuyog Pawar  *
165*c83a76b0SSuyog Pawar  * @brief Fills output arguments for decode process
166*c83a76b0SSuyog Pawar  *
167*c83a76b0SSuyog Pawar  * @par   Description
168*c83a76b0SSuyog Pawar  * Fills elements in the output structure based on the current state
169*c83a76b0SSuyog Pawar  *
170*c83a76b0SSuyog Pawar  * @param[in] ps_codec
171*c83a76b0SSuyog Pawar  * Codec context
172*c83a76b0SSuyog Pawar  *
173*c83a76b0SSuyog Pawar  * @param[in] ps_dec_ip
174*c83a76b0SSuyog Pawar  * Pointer to input structure
175*c83a76b0SSuyog Pawar  *
176*c83a76b0SSuyog Pawar  * @param[in] ps_dec_op
177*c83a76b0SSuyog Pawar  * Pointer to output structure
178*c83a76b0SSuyog Pawar  *
179*c83a76b0SSuyog Pawar  * @returns none
180*c83a76b0SSuyog Pawar  *
181*c83a76b0SSuyog Pawar  * @remarks
182*c83a76b0SSuyog Pawar  *
183*c83a76b0SSuyog Pawar  *******************************************************************************
184*c83a76b0SSuyog Pawar  */
ihevcd_fill_outargs(codec_t * ps_codec,void * pv_api_ip,void * pv_api_op)185*c83a76b0SSuyog Pawar static void ihevcd_fill_outargs(codec_t *ps_codec,
186*c83a76b0SSuyog Pawar                                 void *pv_api_ip,
187*c83a76b0SSuyog Pawar                                 void *pv_api_op)
188*c83a76b0SSuyog Pawar {
189*c83a76b0SSuyog Pawar 
190*c83a76b0SSuyog Pawar     ihevcd_cxa_video_decode_ip_t *ps_hevcd_dec_ip;
191*c83a76b0SSuyog Pawar     ihevcd_cxa_video_decode_op_t *ps_hevcd_dec_op;
192*c83a76b0SSuyog Pawar     ivd_video_decode_ip_t *ps_dec_ip;
193*c83a76b0SSuyog Pawar     ivd_video_decode_op_t *ps_dec_op;
194*c83a76b0SSuyog Pawar 
195*c83a76b0SSuyog Pawar     ps_hevcd_dec_ip = (ihevcd_cxa_video_decode_ip_t *)pv_api_ip;
196*c83a76b0SSuyog Pawar     ps_hevcd_dec_op = (ihevcd_cxa_video_decode_op_t *)pv_api_op;
197*c83a76b0SSuyog Pawar     ps_dec_ip = &ps_hevcd_dec_ip->s_ivd_video_decode_ip_t;
198*c83a76b0SSuyog Pawar     ps_dec_op = &ps_hevcd_dec_op->s_ivd_video_decode_op_t;
199*c83a76b0SSuyog Pawar 
200*c83a76b0SSuyog Pawar     ps_dec_op->u4_error_code = ihevcd_map_error((IHEVCD_ERROR_T)ps_codec->i4_error_code);
201*c83a76b0SSuyog Pawar     ps_dec_op->u4_num_bytes_consumed = ps_dec_ip->u4_num_Bytes
202*c83a76b0SSuyog Pawar                     - ps_codec->i4_bytes_remaining;
203*c83a76b0SSuyog Pawar     if(ps_codec->i4_sps_done)
204*c83a76b0SSuyog Pawar     {
205*c83a76b0SSuyog Pawar         ps_dec_op->u4_pic_wd = ps_codec->i4_disp_wd;
206*c83a76b0SSuyog Pawar         ps_dec_op->u4_pic_ht = ps_codec->i4_disp_ht;
207*c83a76b0SSuyog Pawar     }
208*c83a76b0SSuyog Pawar     else
209*c83a76b0SSuyog Pawar     {
210*c83a76b0SSuyog Pawar         ps_dec_op->u4_pic_wd = 0;
211*c83a76b0SSuyog Pawar         ps_dec_op->u4_pic_ht = 0;
212*c83a76b0SSuyog Pawar     }
213*c83a76b0SSuyog Pawar 
214*c83a76b0SSuyog Pawar     ps_dec_op->e_pic_type = ps_codec->e_dec_pic_type;
215*c83a76b0SSuyog Pawar     ps_dec_op->u4_frame_decoded_flag = ps_codec->i4_pic_present;
216*c83a76b0SSuyog Pawar     ps_dec_op->u4_new_seq = 0;
217*c83a76b0SSuyog Pawar 
218*c83a76b0SSuyog Pawar     ps_dec_op->u4_output_present = 0;
219*c83a76b0SSuyog Pawar     ps_dec_op->u4_progressive_frame_flag = 1;
220*c83a76b0SSuyog Pawar     ps_dec_op->i4_display_index = -1;
221*c83a76b0SSuyog Pawar     ps_dec_op->i4_reorder_depth = -1;
222*c83a76b0SSuyog Pawar     if(ps_codec->i4_sps_done)
223*c83a76b0SSuyog Pawar     {
224*c83a76b0SSuyog Pawar         sps_t *ps_sps = (ps_codec->s_parse.ps_sps_base + ps_codec->i4_sps_id);
225*c83a76b0SSuyog Pawar         profile_tier_lvl_info_t *ps_ptl;
226*c83a76b0SSuyog Pawar         ps_ptl = &ps_sps->s_ptl;
227*c83a76b0SSuyog Pawar         if((0 == ps_ptl->s_ptl_gen.i1_general_progressive_source_flag) &&
228*c83a76b0SSuyog Pawar            (1 == ps_ptl->s_ptl_gen.i1_general_interlaced_source_flag))
229*c83a76b0SSuyog Pawar         {
230*c83a76b0SSuyog Pawar             ps_dec_op->u4_progressive_frame_flag = 0;
231*c83a76b0SSuyog Pawar         }
232*c83a76b0SSuyog Pawar         ps_dec_op->i4_reorder_depth =
233*c83a76b0SSuyog Pawar                         ps_sps->ai1_sps_max_num_reorder_pics[ps_sps->i1_sps_max_sub_layers - 1];
234*c83a76b0SSuyog Pawar     }
235*c83a76b0SSuyog Pawar 
236*c83a76b0SSuyog Pawar     ps_dec_op->u4_is_ref_flag = 1;
237*c83a76b0SSuyog Pawar     ps_dec_op->e_output_format = ps_codec->e_chroma_fmt;
238*c83a76b0SSuyog Pawar     ps_dec_op->u4_is_ref_flag = 1;
239*c83a76b0SSuyog Pawar 
240*c83a76b0SSuyog Pawar     ps_dec_op->e4_fld_type = IV_FLD_TYPE_DEFAULT;
241*c83a76b0SSuyog Pawar     ps_dec_op->u4_ts = (UWORD32)(-1);
242*c83a76b0SSuyog Pawar     ps_dec_op->u4_disp_buf_id = ps_codec->i4_disp_buf_id;
243*c83a76b0SSuyog Pawar     if(ps_codec->i4_flush_mode)
244*c83a76b0SSuyog Pawar     {
245*c83a76b0SSuyog Pawar         ps_dec_op->u4_num_bytes_consumed = 0;
246*c83a76b0SSuyog Pawar         /*In the case of flush ,since no frame is decoded set pic type as invalid*/
247*c83a76b0SSuyog Pawar         ps_dec_op->u4_is_ref_flag = 0;
248*c83a76b0SSuyog Pawar         ps_dec_op->e_pic_type = IV_NA_FRAME;
249*c83a76b0SSuyog Pawar         ps_dec_op->u4_frame_decoded_flag = 0;
250*c83a76b0SSuyog Pawar 
251*c83a76b0SSuyog Pawar     }
252*c83a76b0SSuyog Pawar     /* If there is a display buffer */
253*c83a76b0SSuyog Pawar     if(ps_codec->ps_disp_buf)
254*c83a76b0SSuyog Pawar     {
255*c83a76b0SSuyog Pawar         pic_buf_t *ps_disp_buf = ps_codec->ps_disp_buf;
256*c83a76b0SSuyog Pawar #ifndef DISABLE_SEI
257*c83a76b0SSuyog Pawar         sei_params_t *ps_sei = &ps_disp_buf->s_sei_params;
258*c83a76b0SSuyog Pawar 
259*c83a76b0SSuyog Pawar         if(ps_sei->i1_sei_parameters_present_flag &&
260*c83a76b0SSuyog Pawar            ps_sei->i1_pic_timing_params_present_flag)
261*c83a76b0SSuyog Pawar         {
262*c83a76b0SSuyog Pawar             UWORD32 u4_pic_struct;
263*c83a76b0SSuyog Pawar             u4_pic_struct = ps_sei->s_pic_timing_sei_params.u4_pic_struct;
264*c83a76b0SSuyog Pawar             switch(u4_pic_struct)
265*c83a76b0SSuyog Pawar             {
266*c83a76b0SSuyog Pawar                 case 1:
267*c83a76b0SSuyog Pawar                     ps_dec_op->e4_fld_type = IV_TOP_FLD;
268*c83a76b0SSuyog Pawar                     ps_dec_op->u4_progressive_frame_flag = 0;
269*c83a76b0SSuyog Pawar                     break;
270*c83a76b0SSuyog Pawar                 case 2:
271*c83a76b0SSuyog Pawar                     ps_dec_op->e4_fld_type = IV_BOT_FLD;
272*c83a76b0SSuyog Pawar                     ps_dec_op->u4_progressive_frame_flag = 0;
273*c83a76b0SSuyog Pawar                     break;
274*c83a76b0SSuyog Pawar                 case 0:
275*c83a76b0SSuyog Pawar                 default:
276*c83a76b0SSuyog Pawar                     ps_dec_op->e4_fld_type = IV_FLD_TYPE_DEFAULT;
277*c83a76b0SSuyog Pawar                     ps_dec_op->u4_progressive_frame_flag = 1;
278*c83a76b0SSuyog Pawar                     break;
279*c83a76b0SSuyog Pawar             }
280*c83a76b0SSuyog Pawar         }
281*c83a76b0SSuyog Pawar #endif
282*c83a76b0SSuyog Pawar         ps_dec_op->i4_display_index = ps_disp_buf->i4_abs_poc;
283*c83a76b0SSuyog Pawar         ps_dec_op->u4_output_present = 1;
284*c83a76b0SSuyog Pawar         ps_dec_op->u4_ts = ps_disp_buf->u4_ts;
285*c83a76b0SSuyog Pawar         if((ps_codec->i4_flush_mode == 0) && (ps_codec->s_parse.i4_end_of_frame == 0))
286*c83a76b0SSuyog Pawar             ps_dec_op->u4_output_present = 0;
287*c83a76b0SSuyog Pawar         ps_dec_op->s_disp_frm_buf.u4_y_wd = ps_codec->i4_disp_wd;
288*c83a76b0SSuyog Pawar         ps_dec_op->s_disp_frm_buf.u4_y_ht = ps_codec->i4_disp_ht;
289*c83a76b0SSuyog Pawar 
290*c83a76b0SSuyog Pawar         if(ps_codec->i4_share_disp_buf)
291*c83a76b0SSuyog Pawar         {
292*c83a76b0SSuyog Pawar             ps_dec_op->s_disp_frm_buf.pv_y_buf = ps_disp_buf->pu1_luma;
293*c83a76b0SSuyog Pawar             if(ps_codec->e_chroma_fmt != IV_YUV_420P)
294*c83a76b0SSuyog Pawar             {
295*c83a76b0SSuyog Pawar                 ps_dec_op->s_disp_frm_buf.pv_u_buf = ps_disp_buf->pu1_chroma;
296*c83a76b0SSuyog Pawar                 ps_dec_op->s_disp_frm_buf.pv_v_buf = NULL;
297*c83a76b0SSuyog Pawar             }
298*c83a76b0SSuyog Pawar             else
299*c83a76b0SSuyog Pawar             {
300*c83a76b0SSuyog Pawar                 WORD32 i;
301*c83a76b0SSuyog Pawar                 UWORD8 *pu1_u_dst = NULL, *pu1_v_dst = NULL;
302*c83a76b0SSuyog Pawar                 for(i = 0; i < ps_codec->i4_share_disp_buf_cnt; i++)
303*c83a76b0SSuyog Pawar                 {
304*c83a76b0SSuyog Pawar                     WORD32 diff = ps_disp_buf->pu1_luma - ps_codec->s_disp_buffer[i].pu1_bufs[0];
305*c83a76b0SSuyog Pawar                     if(diff == (ps_codec->i4_strd * PAD_TOP + PAD_LEFT))
306*c83a76b0SSuyog Pawar                     {
307*c83a76b0SSuyog Pawar                         pu1_u_dst = ps_codec->s_disp_buffer[i].pu1_bufs[1];
308*c83a76b0SSuyog Pawar                         pu1_u_dst += (ps_codec->i4_strd * PAD_TOP) / 4 + (PAD_LEFT / 2);
309*c83a76b0SSuyog Pawar 
310*c83a76b0SSuyog Pawar                         pu1_v_dst = ps_codec->s_disp_buffer[i].pu1_bufs[2];
311*c83a76b0SSuyog Pawar                         pu1_v_dst += (ps_codec->i4_strd * PAD_TOP) / 4 + (PAD_LEFT / 2);
312*c83a76b0SSuyog Pawar                         break;
313*c83a76b0SSuyog Pawar                     }
314*c83a76b0SSuyog Pawar                 }
315*c83a76b0SSuyog Pawar                 ps_dec_op->s_disp_frm_buf.pv_u_buf = pu1_u_dst;
316*c83a76b0SSuyog Pawar                 ps_dec_op->s_disp_frm_buf.pv_v_buf = pu1_v_dst;
317*c83a76b0SSuyog Pawar             }
318*c83a76b0SSuyog Pawar             ps_dec_op->s_disp_frm_buf.u4_y_strd = ps_codec->i4_strd;
319*c83a76b0SSuyog Pawar         }
320*c83a76b0SSuyog Pawar         else
321*c83a76b0SSuyog Pawar         {
322*c83a76b0SSuyog Pawar             ps_dec_op->s_disp_frm_buf.pv_y_buf =
323*c83a76b0SSuyog Pawar                             ps_dec_ip->s_out_buffer.pu1_bufs[0];
324*c83a76b0SSuyog Pawar             ps_dec_op->s_disp_frm_buf.pv_u_buf =
325*c83a76b0SSuyog Pawar                             ps_dec_ip->s_out_buffer.pu1_bufs[1];
326*c83a76b0SSuyog Pawar             ps_dec_op->s_disp_frm_buf.pv_v_buf =
327*c83a76b0SSuyog Pawar                             ps_dec_ip->s_out_buffer.pu1_bufs[2];
328*c83a76b0SSuyog Pawar             ps_dec_op->s_disp_frm_buf.u4_y_strd = ps_codec->i4_disp_strd;
329*c83a76b0SSuyog Pawar         }
330*c83a76b0SSuyog Pawar 
331*c83a76b0SSuyog Pawar         if((IV_YUV_420SP_VU == ps_codec->e_chroma_fmt)
332*c83a76b0SSuyog Pawar                         || (IV_YUV_420SP_UV == ps_codec->e_chroma_fmt))
333*c83a76b0SSuyog Pawar         {
334*c83a76b0SSuyog Pawar             ps_dec_op->s_disp_frm_buf.u4_u_strd =
335*c83a76b0SSuyog Pawar                             ps_dec_op->s_disp_frm_buf.u4_y_strd;
336*c83a76b0SSuyog Pawar             ps_dec_op->s_disp_frm_buf.u4_v_strd = 0;
337*c83a76b0SSuyog Pawar             ps_dec_op->s_disp_frm_buf.u4_u_wd =
338*c83a76b0SSuyog Pawar                             ps_dec_op->s_disp_frm_buf.u4_y_wd;
339*c83a76b0SSuyog Pawar             ps_dec_op->s_disp_frm_buf.u4_v_wd = 0;
340*c83a76b0SSuyog Pawar             ps_dec_op->s_disp_frm_buf.u4_u_ht =
341*c83a76b0SSuyog Pawar                             ps_dec_op->s_disp_frm_buf.u4_y_ht / 2;
342*c83a76b0SSuyog Pawar             ps_dec_op->s_disp_frm_buf.u4_v_ht = 0;
343*c83a76b0SSuyog Pawar         }
344*c83a76b0SSuyog Pawar         else if(IV_YUV_420P == ps_codec->e_chroma_fmt)
345*c83a76b0SSuyog Pawar         {
346*c83a76b0SSuyog Pawar             ps_dec_op->s_disp_frm_buf.u4_u_strd =
347*c83a76b0SSuyog Pawar                             ps_dec_op->s_disp_frm_buf.u4_y_strd / 2;
348*c83a76b0SSuyog Pawar             ps_dec_op->s_disp_frm_buf.u4_v_strd =
349*c83a76b0SSuyog Pawar                             ps_dec_op->s_disp_frm_buf.u4_y_strd / 2;
350*c83a76b0SSuyog Pawar             ps_dec_op->s_disp_frm_buf.u4_u_wd =
351*c83a76b0SSuyog Pawar                             ps_dec_op->s_disp_frm_buf.u4_y_wd / 2;
352*c83a76b0SSuyog Pawar             ps_dec_op->s_disp_frm_buf.u4_v_wd =
353*c83a76b0SSuyog Pawar                             ps_dec_op->s_disp_frm_buf.u4_y_wd / 2;
354*c83a76b0SSuyog Pawar             ps_dec_op->s_disp_frm_buf.u4_u_ht =
355*c83a76b0SSuyog Pawar                             ps_dec_op->s_disp_frm_buf.u4_y_ht / 2;
356*c83a76b0SSuyog Pawar             ps_dec_op->s_disp_frm_buf.u4_v_ht =
357*c83a76b0SSuyog Pawar                             ps_dec_op->s_disp_frm_buf.u4_y_ht / 2;
358*c83a76b0SSuyog Pawar         }
359*c83a76b0SSuyog Pawar 
360*c83a76b0SSuyog Pawar     }
361*c83a76b0SSuyog Pawar     else if(ps_codec->i4_flush_mode)
362*c83a76b0SSuyog Pawar     {
363*c83a76b0SSuyog Pawar         ps_dec_op->u4_error_code = IHEVCD_END_OF_SEQUENCE;
364*c83a76b0SSuyog Pawar         /* Come out of flush mode */
365*c83a76b0SSuyog Pawar         ps_codec->i4_flush_mode = 0;
366*c83a76b0SSuyog Pawar     }
367*c83a76b0SSuyog Pawar 
368*c83a76b0SSuyog Pawar     if(ps_codec->u1_enable_cu_info && ps_dec_op->u4_output_present)
369*c83a76b0SSuyog Pawar     {
370*c83a76b0SSuyog Pawar         WORD32 info_map_dst_strd = ALIGN8(ps_codec->i4_wd) >> 3;
371*c83a76b0SSuyog Pawar         WORD32 info_map_src_strd = ALIGN64(ps_codec->i4_wd) >> 3;
372*c83a76b0SSuyog Pawar         WORD32 info_map_ht = ALIGN8(ps_codec->i4_ht);
373*c83a76b0SSuyog Pawar         UWORD32 info_map_size = (ALIGN8(ps_codec->i4_wd) * info_map_ht) >> 6;
374*c83a76b0SSuyog Pawar         WORD32 vert_8x8;
375*c83a76b0SSuyog Pawar         UWORD8 *pu1_out_qp_map, *pu1_qp_map;
376*c83a76b0SSuyog Pawar         UWORD8 *pu1_out_blk_type_map, *pu1_type_map;
377*c83a76b0SSuyog Pawar 
378*c83a76b0SSuyog Pawar         if(ps_hevcd_dec_ip->pu1_8x8_blk_qp_map)
379*c83a76b0SSuyog Pawar         {
380*c83a76b0SSuyog Pawar             ps_hevcd_dec_op->pu1_8x8_blk_qp_map = ps_hevcd_dec_ip->pu1_8x8_blk_qp_map;
381*c83a76b0SSuyog Pawar             ps_hevcd_dec_op->u4_8x8_blk_qp_map_size = info_map_size;
382*c83a76b0SSuyog Pawar 
383*c83a76b0SSuyog Pawar             pu1_out_qp_map = ps_hevcd_dec_op->pu1_8x8_blk_qp_map;
384*c83a76b0SSuyog Pawar             pu1_qp_map = ps_codec->as_buf_id_info_map[ps_codec->i4_disp_buf_id].pu1_qp_map;
385*c83a76b0SSuyog Pawar             for(vert_8x8 = 0; vert_8x8 < info_map_ht; vert_8x8++)
386*c83a76b0SSuyog Pawar             {
387*c83a76b0SSuyog Pawar                 memcpy(pu1_out_qp_map, pu1_qp_map, info_map_dst_strd);
388*c83a76b0SSuyog Pawar                 pu1_out_qp_map += info_map_dst_strd;
389*c83a76b0SSuyog Pawar                 pu1_qp_map += info_map_src_strd;
390*c83a76b0SSuyog Pawar             }
391*c83a76b0SSuyog Pawar         }
392*c83a76b0SSuyog Pawar 
393*c83a76b0SSuyog Pawar         if(ps_hevcd_dec_ip->pu1_8x8_blk_type_map)
394*c83a76b0SSuyog Pawar         {
395*c83a76b0SSuyog Pawar             ps_hevcd_dec_op->pu1_8x8_blk_type_map = ps_hevcd_dec_ip->pu1_8x8_blk_type_map;
396*c83a76b0SSuyog Pawar             ps_hevcd_dec_op->u4_8x8_blk_type_map_size = info_map_size;
397*c83a76b0SSuyog Pawar 
398*c83a76b0SSuyog Pawar             pu1_out_blk_type_map = ps_hevcd_dec_op->pu1_8x8_blk_type_map;
399*c83a76b0SSuyog Pawar             pu1_type_map =
400*c83a76b0SSuyog Pawar                 ps_codec->as_buf_id_info_map[ps_codec->i4_disp_buf_id].pu1_cu_type_map;
401*c83a76b0SSuyog Pawar             for(vert_8x8 = 0; vert_8x8 < info_map_ht; vert_8x8++)
402*c83a76b0SSuyog Pawar             {
403*c83a76b0SSuyog Pawar                 memcpy(pu1_out_blk_type_map, pu1_type_map, info_map_dst_strd);
404*c83a76b0SSuyog Pawar                 pu1_out_blk_type_map += info_map_dst_strd;
405*c83a76b0SSuyog Pawar                 pu1_type_map += info_map_src_strd;
406*c83a76b0SSuyog Pawar             }
407*c83a76b0SSuyog Pawar         }
408*c83a76b0SSuyog Pawar     }
409*c83a76b0SSuyog Pawar }
410*c83a76b0SSuyog Pawar 
411*c83a76b0SSuyog Pawar /**
412*c83a76b0SSuyog Pawar  *******************************************************************************
413*c83a76b0SSuyog Pawar  *
414*c83a76b0SSuyog Pawar  * @brief
415*c83a76b0SSuyog Pawar  *  Codec process call
416*c83a76b0SSuyog Pawar  *
417*c83a76b0SSuyog Pawar  * @par Description:
418*c83a76b0SSuyog Pawar  *  Codec process call  Tests for few error checks  Handle flush and decode
419*c83a76b0SSuyog Pawar  * header related code  Parse bitstream for start codes  For each NAL unit
420*c83a76b0SSuyog Pawar  * call decode NAL function  Once a complete frame is decoded (in frame
421*c83a76b0SSuyog Pawar  * decode mode)  Fill output arguments and return
422*c83a76b0SSuyog Pawar  *
423*c83a76b0SSuyog Pawar  * @param[in] ps_codec_obj
424*c83a76b0SSuyog Pawar  *  Pointer to codec object at API level
425*c83a76b0SSuyog Pawar  *
426*c83a76b0SSuyog Pawar  * @param[in] pv_api_ip
427*c83a76b0SSuyog Pawar  *  Pointer to input argument structure
428*c83a76b0SSuyog Pawar  *
429*c83a76b0SSuyog Pawar  * @param[in] pv_api_op
430*c83a76b0SSuyog Pawar  *  Pointer to output argument structure
431*c83a76b0SSuyog Pawar  *
432*c83a76b0SSuyog Pawar  * @returns  Status
433*c83a76b0SSuyog Pawar  *
434*c83a76b0SSuyog Pawar  * @remarks
435*c83a76b0SSuyog Pawar  *
436*c83a76b0SSuyog Pawar  *
437*c83a76b0SSuyog Pawar  *******************************************************************************
438*c83a76b0SSuyog Pawar  */
ihevcd_decode(iv_obj_t * ps_codec_obj,void * pv_api_ip,void * pv_api_op)439*c83a76b0SSuyog Pawar WORD32 ihevcd_decode(iv_obj_t *ps_codec_obj, void *pv_api_ip, void *pv_api_op)
440*c83a76b0SSuyog Pawar {
441*c83a76b0SSuyog Pawar     WORD32 ret = IV_SUCCESS;
442*c83a76b0SSuyog Pawar     codec_t *ps_codec = (codec_t *)(ps_codec_obj->pv_codec_handle);
443*c83a76b0SSuyog Pawar     ihevcd_cxa_video_decode_ip_t s_hevcd_dec_ip = {};
444*c83a76b0SSuyog Pawar     ihevcd_cxa_video_decode_ip_t *ps_hevcd_dec_ip;
445*c83a76b0SSuyog Pawar     ihevcd_cxa_video_decode_op_t *ps_hevcd_dec_op;
446*c83a76b0SSuyog Pawar     ivd_video_decode_ip_t *ps_dec_ip;
447*c83a76b0SSuyog Pawar     ivd_video_decode_op_t *ps_dec_op;
448*c83a76b0SSuyog Pawar 
449*c83a76b0SSuyog Pawar     WORD32 proc_idx = 0;
450*c83a76b0SSuyog Pawar     WORD32 prev_proc_idx = 0;
451*c83a76b0SSuyog Pawar 
452*c83a76b0SSuyog Pawar     /* Initialize error code */
453*c83a76b0SSuyog Pawar     ps_codec->i4_error_code = 0;
454*c83a76b0SSuyog Pawar     /* Initialize bytes remaining */
455*c83a76b0SSuyog Pawar     ps_codec->i4_bytes_remaining = 0;
456*c83a76b0SSuyog Pawar 
457*c83a76b0SSuyog Pawar     ps_dec_ip = (ivd_video_decode_ip_t *)pv_api_ip;
458*c83a76b0SSuyog Pawar     memcpy(&s_hevcd_dec_ip, ps_dec_ip, ps_dec_ip->u4_size);
459*c83a76b0SSuyog Pawar     s_hevcd_dec_ip.s_ivd_video_decode_ip_t.u4_size = sizeof(ihevcd_cxa_video_decode_ip_t);
460*c83a76b0SSuyog Pawar 
461*c83a76b0SSuyog Pawar     ps_hevcd_dec_ip = &s_hevcd_dec_ip;
462*c83a76b0SSuyog Pawar     ps_dec_ip = &ps_hevcd_dec_ip->s_ivd_video_decode_ip_t;
463*c83a76b0SSuyog Pawar 
464*c83a76b0SSuyog Pawar     ps_hevcd_dec_op = (ihevcd_cxa_video_decode_op_t *)pv_api_op;
465*c83a76b0SSuyog Pawar     ps_dec_op = &ps_hevcd_dec_op->s_ivd_video_decode_op_t;
466*c83a76b0SSuyog Pawar 
467*c83a76b0SSuyog Pawar     {
468*c83a76b0SSuyog Pawar         UWORD32 u4_size = ps_dec_op->u4_size;
469*c83a76b0SSuyog Pawar         memset(ps_hevcd_dec_op, 0, u4_size);
470*c83a76b0SSuyog Pawar         ps_dec_op->u4_size = u4_size; //Restore size field
471*c83a76b0SSuyog Pawar     }
472*c83a76b0SSuyog Pawar     if(ps_codec->i4_init_done != 1)
473*c83a76b0SSuyog Pawar     {
474*c83a76b0SSuyog Pawar         ps_dec_op->u4_error_code |= 1 << IVD_FATALERROR;
475*c83a76b0SSuyog Pawar         ps_dec_op->u4_error_code |= IHEVCD_INIT_NOT_DONE;
476*c83a76b0SSuyog Pawar         return IV_FAIL;
477*c83a76b0SSuyog Pawar     }
478*c83a76b0SSuyog Pawar 
479*c83a76b0SSuyog Pawar     if(ps_codec->u4_pic_cnt >= NUM_FRAMES_LIMIT)
480*c83a76b0SSuyog Pawar     {
481*c83a76b0SSuyog Pawar         ps_dec_op->u4_error_code |= 1 << IVD_FATALERROR;
482*c83a76b0SSuyog Pawar         ps_dec_op->u4_error_code |= IHEVCD_NUM_FRAMES_LIMIT_REACHED;
483*c83a76b0SSuyog Pawar         return IV_FAIL;
484*c83a76b0SSuyog Pawar     }
485*c83a76b0SSuyog Pawar 
486*c83a76b0SSuyog Pawar     if(ps_codec->u1_enable_cu_info && ps_codec->i4_sps_done)
487*c83a76b0SSuyog Pawar     {
488*c83a76b0SSuyog Pawar         UWORD32 blk_qp_map_size = ps_hevcd_dec_ip->u4_8x8_blk_qp_map_size;
489*c83a76b0SSuyog Pawar         UWORD32 blk_type_map_size = ps_hevcd_dec_ip->u4_8x8_blk_type_map_size;
490*c83a76b0SSuyog Pawar         UWORD32 blk_8x8_map_size = (ALIGN8(ps_codec->i4_wd) * ALIGN8(ps_codec->i4_ht)) >> 6;
491*c83a76b0SSuyog Pawar 
492*c83a76b0SSuyog Pawar         if ((ps_hevcd_dec_ip->pu1_8x8_blk_qp_map && blk_qp_map_size < blk_8x8_map_size) ||
493*c83a76b0SSuyog Pawar             (ps_hevcd_dec_ip->pu1_8x8_blk_type_map && blk_type_map_size < blk_8x8_map_size))
494*c83a76b0SSuyog Pawar         {
495*c83a76b0SSuyog Pawar             ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
496*c83a76b0SSuyog Pawar             ps_dec_op->u4_error_code |= IHEVCD_INSUFFICIENT_METADATA_BUFFER;
497*c83a76b0SSuyog Pawar             return IV_FAIL;
498*c83a76b0SSuyog Pawar         }
499*c83a76b0SSuyog Pawar      }
500*c83a76b0SSuyog Pawar 
501*c83a76b0SSuyog Pawar     /* If reset flag is set, flush the existing buffers */
502*c83a76b0SSuyog Pawar     if(ps_codec->i4_reset_flag)
503*c83a76b0SSuyog Pawar     {
504*c83a76b0SSuyog Pawar         ps_codec->i4_flush_mode = 1;
505*c83a76b0SSuyog Pawar     }
506*c83a76b0SSuyog Pawar 
507*c83a76b0SSuyog Pawar     /*Data memory barries instruction,so that bitstream write by the application is complete*/
508*c83a76b0SSuyog Pawar     //arm_dsb();
509*c83a76b0SSuyog Pawar     /* In case the decoder is not in flush mode check for input buffer validity */
510*c83a76b0SSuyog Pawar     if(0 == ps_codec->i4_flush_mode)
511*c83a76b0SSuyog Pawar     {
512*c83a76b0SSuyog Pawar         if(ps_dec_ip->pv_stream_buffer == NULL)
513*c83a76b0SSuyog Pawar         {
514*c83a76b0SSuyog Pawar             ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
515*c83a76b0SSuyog Pawar             ps_dec_op->u4_error_code |= IVD_DEC_FRM_BS_BUF_NULL;
516*c83a76b0SSuyog Pawar             return IV_FAIL;
517*c83a76b0SSuyog Pawar         }
518*c83a76b0SSuyog Pawar         if(ps_dec_ip->u4_num_Bytes <= MIN_START_CODE_LEN)
519*c83a76b0SSuyog Pawar         {
520*c83a76b0SSuyog Pawar             if((WORD32)ps_dec_ip->u4_num_Bytes > 0)
521*c83a76b0SSuyog Pawar                 ps_dec_op->u4_num_bytes_consumed = ps_dec_ip->u4_num_Bytes;
522*c83a76b0SSuyog Pawar             else
523*c83a76b0SSuyog Pawar                 ps_dec_op->u4_num_bytes_consumed = 0;
524*c83a76b0SSuyog Pawar 
525*c83a76b0SSuyog Pawar             ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
526*c83a76b0SSuyog Pawar             ps_dec_op->u4_error_code |= IVD_DEC_NUMBYTES_INV;
527*c83a76b0SSuyog Pawar             return IV_FAIL;
528*c83a76b0SSuyog Pawar 
529*c83a76b0SSuyog Pawar         }
530*c83a76b0SSuyog Pawar     }
531*c83a76b0SSuyog Pawar 
532*c83a76b0SSuyog Pawar #ifdef APPLY_CONCEALMENT
533*c83a76b0SSuyog Pawar     {
534*c83a76b0SSuyog Pawar         WORD32 num_mbs;
535*c83a76b0SSuyog Pawar 
536*c83a76b0SSuyog Pawar         num_mbs = (ps_codec->i4_wd * ps_codec->i4_ht + 255) >> 8;
537*c83a76b0SSuyog Pawar         /* Reset MB Count at the beginning of every process call */
538*c83a76b0SSuyog Pawar         ps_codec->mb_count = 0;
539*c83a76b0SSuyog Pawar         memset(ps_codec->mb_map, 0, ((num_mbs + 7) >> 3));
540*c83a76b0SSuyog Pawar     }
541*c83a76b0SSuyog Pawar #endif
542*c83a76b0SSuyog Pawar 
543*c83a76b0SSuyog Pawar     if(0 == ps_codec->i4_share_disp_buf && ps_codec->i4_header_mode == 0)
544*c83a76b0SSuyog Pawar     {
545*c83a76b0SSuyog Pawar         UWORD32 i;
546*c83a76b0SSuyog Pawar         if((ps_dec_ip->s_out_buffer.u4_num_bufs <= 0) ||
547*c83a76b0SSuyog Pawar            (ps_dec_ip->s_out_buffer.u4_num_bufs > IVD_VIDDEC_MAX_IO_BUFFERS))
548*c83a76b0SSuyog Pawar         {
549*c83a76b0SSuyog Pawar             ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
550*c83a76b0SSuyog Pawar             ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUFS;
551*c83a76b0SSuyog Pawar             return IV_FAIL;
552*c83a76b0SSuyog Pawar         }
553*c83a76b0SSuyog Pawar 
554*c83a76b0SSuyog Pawar         for(i = 0; i < ps_dec_ip->s_out_buffer.u4_num_bufs; i++)
555*c83a76b0SSuyog Pawar         {
556*c83a76b0SSuyog Pawar             if(ps_dec_ip->s_out_buffer.pu1_bufs[i] == NULL)
557*c83a76b0SSuyog Pawar             {
558*c83a76b0SSuyog Pawar                 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
559*c83a76b0SSuyog Pawar                 ps_dec_op->u4_error_code |= IVD_DISP_FRM_OP_BUF_NULL;
560*c83a76b0SSuyog Pawar                 return IV_FAIL;
561*c83a76b0SSuyog Pawar             }
562*c83a76b0SSuyog Pawar 
563*c83a76b0SSuyog Pawar             if(ps_dec_ip->s_out_buffer.u4_min_out_buf_size[i] == 0)
564*c83a76b0SSuyog Pawar             {
565*c83a76b0SSuyog Pawar                 ps_dec_op->u4_error_code |= 1 << IVD_UNSUPPORTEDPARAM;
566*c83a76b0SSuyog Pawar                 ps_dec_op->u4_error_code |= IVD_DISP_FRM_ZERO_OP_BUF_SIZE;
567*c83a76b0SSuyog Pawar                 return IV_FAIL;
568*c83a76b0SSuyog Pawar             }
569*c83a76b0SSuyog Pawar         }
570*c83a76b0SSuyog Pawar     }
571*c83a76b0SSuyog Pawar 
572*c83a76b0SSuyog Pawar     ps_codec->ps_out_buffer = &ps_dec_ip->s_out_buffer;
573*c83a76b0SSuyog Pawar     ps_codec->u4_ts = ps_dec_ip->u4_ts;
574*c83a76b0SSuyog Pawar     if(ps_codec->i4_flush_mode)
575*c83a76b0SSuyog Pawar     {
576*c83a76b0SSuyog Pawar 
577*c83a76b0SSuyog Pawar         ps_dec_op->u4_pic_wd = ps_codec->i4_disp_wd;
578*c83a76b0SSuyog Pawar         ps_dec_op->u4_pic_ht = ps_codec->i4_disp_ht;
579*c83a76b0SSuyog Pawar 
580*c83a76b0SSuyog Pawar         ps_dec_op->u4_new_seq = 0;
581*c83a76b0SSuyog Pawar 
582*c83a76b0SSuyog Pawar         ps_codec->ps_disp_buf = (pic_buf_t *)ihevc_disp_mgr_get(
583*c83a76b0SSuyog Pawar                         (disp_mgr_t *)ps_codec->pv_disp_buf_mgr, &ps_codec->i4_disp_buf_id);
584*c83a76b0SSuyog Pawar         /* In case of non-shared mode, then convert/copy the frame to output buffer */
585*c83a76b0SSuyog Pawar         /* Only if the codec is in non-shared mode or in shared mode but needs 420P output */
586*c83a76b0SSuyog Pawar         if((ps_codec->ps_disp_buf)
587*c83a76b0SSuyog Pawar                         && ((0 == ps_codec->i4_share_disp_buf)
588*c83a76b0SSuyog Pawar                                         || (IV_YUV_420P
589*c83a76b0SSuyog Pawar                                                         == ps_codec->e_chroma_fmt)))
590*c83a76b0SSuyog Pawar         {
591*c83a76b0SSuyog Pawar 
592*c83a76b0SSuyog Pawar             process_ctxt_t *ps_proc = &ps_codec->as_process[prev_proc_idx];
593*c83a76b0SSuyog Pawar             if(0 == ps_proc->i4_init_done)
594*c83a76b0SSuyog Pawar             {
595*c83a76b0SSuyog Pawar                 ihevcd_init_proc_ctxt(ps_proc, 0);
596*c83a76b0SSuyog Pawar             }
597*c83a76b0SSuyog Pawar 
598*c83a76b0SSuyog Pawar             /* Output buffer check */
599*c83a76b0SSuyog Pawar             ret = ihevcd_check_out_buf_size(ps_codec);
600*c83a76b0SSuyog Pawar             RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
601*c83a76b0SSuyog Pawar 
602*c83a76b0SSuyog Pawar             /* Set remaining number of rows to be processed */
603*c83a76b0SSuyog Pawar             ret = ihevcd_fmt_conv(ps_codec, &ps_codec->as_process[prev_proc_idx],
604*c83a76b0SSuyog Pawar                                   ps_dec_ip->s_out_buffer.pu1_bufs[0],
605*c83a76b0SSuyog Pawar                                   ps_dec_ip->s_out_buffer.pu1_bufs[1],
606*c83a76b0SSuyog Pawar                                   ps_dec_ip->s_out_buffer.pu1_bufs[2], 0,
607*c83a76b0SSuyog Pawar                                   ps_codec->i4_disp_ht);
608*c83a76b0SSuyog Pawar 
609*c83a76b0SSuyog Pawar             ihevc_buf_mgr_release((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
610*c83a76b0SSuyog Pawar                                   ps_codec->i4_disp_buf_id, BUF_MGR_DISP);
611*c83a76b0SSuyog Pawar         }
612*c83a76b0SSuyog Pawar 
613*c83a76b0SSuyog Pawar         ihevcd_fill_outargs(ps_codec, ps_hevcd_dec_ip, ps_hevcd_dec_op);
614*c83a76b0SSuyog Pawar 
615*c83a76b0SSuyog Pawar         if(1 == ps_dec_op->u4_output_present)
616*c83a76b0SSuyog Pawar         {
617*c83a76b0SSuyog Pawar             WORD32 xpos = ps_codec->i4_disp_wd - 32 - LOGO_WD;
618*c83a76b0SSuyog Pawar             WORD32 ypos = ps_codec->i4_disp_ht - 32 - LOGO_HT;
619*c83a76b0SSuyog Pawar 
620*c83a76b0SSuyog Pawar             if(ypos < 0)
621*c83a76b0SSuyog Pawar                 ypos = 0;
622*c83a76b0SSuyog Pawar 
623*c83a76b0SSuyog Pawar             if(xpos < 0)
624*c83a76b0SSuyog Pawar                 xpos = 0;
625*c83a76b0SSuyog Pawar 
626*c83a76b0SSuyog Pawar             INSERT_LOGO(ps_dec_ip->s_out_buffer.pu1_bufs[0],
627*c83a76b0SSuyog Pawar                         ps_dec_ip->s_out_buffer.pu1_bufs[1],
628*c83a76b0SSuyog Pawar                         ps_dec_ip->s_out_buffer.pu1_bufs[2], ps_codec->i4_disp_strd,
629*c83a76b0SSuyog Pawar                         xpos,
630*c83a76b0SSuyog Pawar                         ypos,
631*c83a76b0SSuyog Pawar                         ps_codec->e_chroma_fmt,
632*c83a76b0SSuyog Pawar                         ps_codec->i4_disp_wd,
633*c83a76b0SSuyog Pawar                         ps_codec->i4_disp_ht);
634*c83a76b0SSuyog Pawar         }
635*c83a76b0SSuyog Pawar 
636*c83a76b0SSuyog Pawar 
637*c83a76b0SSuyog Pawar         if(NULL == ps_codec->ps_disp_buf)
638*c83a76b0SSuyog Pawar         {
639*c83a76b0SSuyog Pawar             /* If in flush mode and there are no more buffers to flush,
640*c83a76b0SSuyog Pawar              * check for the reset flag and reset the decoder */
641*c83a76b0SSuyog Pawar             if(ps_codec->i4_reset_flag)
642*c83a76b0SSuyog Pawar             {
643*c83a76b0SSuyog Pawar                 ihevcd_init(ps_codec);
644*c83a76b0SSuyog Pawar             }
645*c83a76b0SSuyog Pawar             return (IV_FAIL);
646*c83a76b0SSuyog Pawar         }
647*c83a76b0SSuyog Pawar 
648*c83a76b0SSuyog Pawar         return (IV_SUCCESS);
649*c83a76b0SSuyog Pawar 
650*c83a76b0SSuyog Pawar     }
651*c83a76b0SSuyog Pawar     /* In case of shared mode, check if there is a free buffer for reconstruction */
652*c83a76b0SSuyog Pawar     if((0 == ps_codec->i4_header_mode) && (1 == ps_codec->i4_share_disp_buf))
653*c83a76b0SSuyog Pawar     {
654*c83a76b0SSuyog Pawar         WORD32 buf_status;
655*c83a76b0SSuyog Pawar         buf_status = 1;
656*c83a76b0SSuyog Pawar         if(ps_codec->pv_pic_buf_mgr)
657*c83a76b0SSuyog Pawar             buf_status = ihevc_buf_mgr_check_free((buf_mgr_t *)ps_codec->pv_pic_buf_mgr);
658*c83a76b0SSuyog Pawar 
659*c83a76b0SSuyog Pawar         /* If there is no free buffer, then return with an error code */
660*c83a76b0SSuyog Pawar         if(0 == buf_status)
661*c83a76b0SSuyog Pawar         {
662*c83a76b0SSuyog Pawar             ps_dec_op->u4_error_code = IVD_DEC_REF_BUF_NULL;
663*c83a76b0SSuyog Pawar             ps_dec_op->u4_error_code |= (1 << IVD_UNSUPPORTEDPARAM);
664*c83a76b0SSuyog Pawar             return IV_FAIL;
665*c83a76b0SSuyog Pawar         }
666*c83a76b0SSuyog Pawar     }
667*c83a76b0SSuyog Pawar     ps_codec->i4_bytes_remaining = ps_dec_ip->u4_num_Bytes;
668*c83a76b0SSuyog Pawar     ps_codec->pu1_inp_bitsbuf = (UWORD8 *)ps_dec_ip->pv_stream_buffer;
669*c83a76b0SSuyog Pawar     ps_codec->s_parse.i4_end_of_frame = 0;
670*c83a76b0SSuyog Pawar 
671*c83a76b0SSuyog Pawar     ps_codec->i4_pic_present = 0;
672*c83a76b0SSuyog Pawar     ps_codec->i4_slice_error = 0;
673*c83a76b0SSuyog Pawar     ps_codec->ps_disp_buf = NULL;
674*c83a76b0SSuyog Pawar 
675*c83a76b0SSuyog Pawar     if(ps_codec->i4_num_cores > 1)
676*c83a76b0SSuyog Pawar     {
677*c83a76b0SSuyog Pawar         ithread_set_affinity(0);
678*c83a76b0SSuyog Pawar     }
679*c83a76b0SSuyog Pawar     while(MIN_START_CODE_LEN < ps_codec->i4_bytes_remaining)
680*c83a76b0SSuyog Pawar     {
681*c83a76b0SSuyog Pawar         WORD32 nal_len;
682*c83a76b0SSuyog Pawar         WORD32 nal_ofst;
683*c83a76b0SSuyog Pawar         WORD32 bits_len;
684*c83a76b0SSuyog Pawar 
685*c83a76b0SSuyog Pawar         if(ps_codec->i4_slice_error)
686*c83a76b0SSuyog Pawar         {
687*c83a76b0SSuyog Pawar             slice_header_t *ps_slice_hdr_next = ps_codec->s_parse.ps_slice_hdr_base + (ps_codec->s_parse.i4_cur_slice_idx & (MAX_SLICE_HDR_CNT - 1));
688*c83a76b0SSuyog Pawar             WORD32 next_slice_addr = ps_slice_hdr_next->i2_ctb_x +
689*c83a76b0SSuyog Pawar                             ps_slice_hdr_next->i2_ctb_y * ps_codec->s_parse.ps_sps->i2_pic_wd_in_ctb;
690*c83a76b0SSuyog Pawar             if(ps_codec->s_parse.i4_next_ctb_indx == next_slice_addr)
691*c83a76b0SSuyog Pawar                 ps_codec->i4_slice_error = 0;
692*c83a76b0SSuyog Pawar         }
693*c83a76b0SSuyog Pawar 
694*c83a76b0SSuyog Pawar         if(ps_codec->pu1_bitsbuf_dynamic)
695*c83a76b0SSuyog Pawar         {
696*c83a76b0SSuyog Pawar             ps_codec->pu1_bitsbuf = ps_codec->pu1_bitsbuf_dynamic;
697*c83a76b0SSuyog Pawar             ps_codec->u4_bitsbuf_size = ps_codec->u4_bitsbuf_size_dynamic;
698*c83a76b0SSuyog Pawar         }
699*c83a76b0SSuyog Pawar         else
700*c83a76b0SSuyog Pawar         {
701*c83a76b0SSuyog Pawar             ps_codec->pu1_bitsbuf = ps_codec->pu1_bitsbuf_static;
702*c83a76b0SSuyog Pawar             ps_codec->u4_bitsbuf_size = ps_codec->u4_bitsbuf_size_static;
703*c83a76b0SSuyog Pawar         }
704*c83a76b0SSuyog Pawar 
705*c83a76b0SSuyog Pawar         nal_ofst = ihevcd_nal_search_start_code(ps_codec->pu1_inp_bitsbuf,
706*c83a76b0SSuyog Pawar                                                 ps_codec->i4_bytes_remaining);
707*c83a76b0SSuyog Pawar         /* If there is no start code found, consume the data and break */
708*c83a76b0SSuyog Pawar         if(nal_ofst == ps_codec->i4_bytes_remaining)
709*c83a76b0SSuyog Pawar         {
710*c83a76b0SSuyog Pawar             ps_codec->pu1_inp_bitsbuf += nal_ofst;
711*c83a76b0SSuyog Pawar             ps_codec->i4_bytes_remaining -= nal_ofst;
712*c83a76b0SSuyog Pawar             break;
713*c83a76b0SSuyog Pawar         }
714*c83a76b0SSuyog Pawar 
715*c83a76b0SSuyog Pawar         ps_codec->i4_nal_ofst = nal_ofst;
716*c83a76b0SSuyog Pawar         {
717*c83a76b0SSuyog Pawar             WORD32 bytes_remaining = ps_codec->i4_bytes_remaining - nal_ofst;
718*c83a76b0SSuyog Pawar 
719*c83a76b0SSuyog Pawar             bytes_remaining = MIN((UWORD32)bytes_remaining, ps_codec->u4_bitsbuf_size);
720*c83a76b0SSuyog Pawar             ihevcd_nal_remv_emuln_bytes(ps_codec->pu1_inp_bitsbuf + nal_ofst,
721*c83a76b0SSuyog Pawar                                         ps_codec->pu1_bitsbuf,
722*c83a76b0SSuyog Pawar                                         bytes_remaining,
723*c83a76b0SSuyog Pawar                                         &nal_len, &bits_len);
724*c83a76b0SSuyog Pawar 
725*c83a76b0SSuyog Pawar             /* Decoder may read upto 8 extra bytes at the end of frame */
726*c83a76b0SSuyog Pawar             /* These are not used, but still set them to zero to avoid uninitialized reads */
727*c83a76b0SSuyog Pawar             if(bits_len < (WORD32)(ps_codec->u4_bitsbuf_size - 8))
728*c83a76b0SSuyog Pawar             {
729*c83a76b0SSuyog Pawar                 memset(ps_codec->pu1_bitsbuf + bits_len, 0, 2 * sizeof(UWORD32));
730*c83a76b0SSuyog Pawar             }
731*c83a76b0SSuyog Pawar         }
732*c83a76b0SSuyog Pawar         /* This may be used to update the offsets for tiles and entropy sync row offsets */
733*c83a76b0SSuyog Pawar         ps_codec->i4_num_emln_bytes = nal_len - bits_len;
734*c83a76b0SSuyog Pawar         ps_codec->i4_nal_len = nal_len;
735*c83a76b0SSuyog Pawar 
736*c83a76b0SSuyog Pawar         ihevcd_bits_init(&ps_codec->s_parse.s_bitstrm, ps_codec->pu1_bitsbuf,
737*c83a76b0SSuyog Pawar                          bits_len);
738*c83a76b0SSuyog Pawar 
739*c83a76b0SSuyog Pawar         ret = ihevcd_nal_unit(ps_codec);
740*c83a76b0SSuyog Pawar 
741*c83a76b0SSuyog Pawar         /* If the frame is incomplete and
742*c83a76b0SSuyog Pawar          * the bytes remaining is zero or a header is received,
743*c83a76b0SSuyog Pawar          * complete the frame treating it to be in error */
744*c83a76b0SSuyog Pawar         if(ps_codec->i4_pic_present &&
745*c83a76b0SSuyog Pawar                         (ps_codec->s_parse.i4_next_ctb_indx != ps_codec->s_parse.ps_sps->i4_pic_size_in_ctb))
746*c83a76b0SSuyog Pawar         {
747*c83a76b0SSuyog Pawar             if((ps_codec->i4_bytes_remaining - (nal_len + nal_ofst) <= MIN_START_CODE_LEN) ||
748*c83a76b0SSuyog Pawar                             (ps_codec->i4_header_in_slice_mode))
749*c83a76b0SSuyog Pawar             {
750*c83a76b0SSuyog Pawar                 slice_header_t *ps_slice_hdr_next;
751*c83a76b0SSuyog Pawar 
752*c83a76b0SSuyog Pawar                 ps_codec->s_parse.i4_cur_slice_idx--;
753*c83a76b0SSuyog Pawar                 if(ps_codec->s_parse.i4_cur_slice_idx < 0)
754*c83a76b0SSuyog Pawar                     ps_codec->s_parse.i4_cur_slice_idx = 0;
755*c83a76b0SSuyog Pawar 
756*c83a76b0SSuyog Pawar                 ps_slice_hdr_next = ps_codec->s_parse.ps_slice_hdr_base + ((ps_codec->s_parse.i4_cur_slice_idx + 1) & (MAX_SLICE_HDR_CNT - 1));
757*c83a76b0SSuyog Pawar                 ps_slice_hdr_next->i2_ctb_x = 0;
758*c83a76b0SSuyog Pawar                 ps_slice_hdr_next->i2_ctb_y = ps_codec->s_parse.ps_sps->i2_pic_ht_in_ctb;
759*c83a76b0SSuyog Pawar                 ps_codec->i4_slice_error = 1;
760*c83a76b0SSuyog Pawar                 continue;
761*c83a76b0SSuyog Pawar             }
762*c83a76b0SSuyog Pawar         }
763*c83a76b0SSuyog Pawar 
764*c83a76b0SSuyog Pawar         if(IHEVCD_IGNORE_SLICE == ret)
765*c83a76b0SSuyog Pawar         {
766*c83a76b0SSuyog Pawar             ps_codec->pu1_inp_bitsbuf += (nal_ofst + nal_len);
767*c83a76b0SSuyog Pawar             ps_codec->i4_bytes_remaining -= (nal_ofst + nal_len);
768*c83a76b0SSuyog Pawar 
769*c83a76b0SSuyog Pawar             continue;
770*c83a76b0SSuyog Pawar         }
771*c83a76b0SSuyog Pawar 
772*c83a76b0SSuyog Pawar         if(IVD_RES_CHANGED == ret)
773*c83a76b0SSuyog Pawar         {
774*c83a76b0SSuyog Pawar             break;
775*c83a76b0SSuyog Pawar         }
776*c83a76b0SSuyog Pawar 
777*c83a76b0SSuyog Pawar         /* Update bytes remaining and bytes consumed and input bitstream pointer */
778*c83a76b0SSuyog Pawar         /* Do not consume the NAL in the following cases */
779*c83a76b0SSuyog Pawar         /* Slice header reached during header decode mode */
780*c83a76b0SSuyog Pawar         /* TODO: Next picture's slice reached */
781*c83a76b0SSuyog Pawar         if(ret != IHEVCD_SLICE_IN_HEADER_MODE)
782*c83a76b0SSuyog Pawar         {
783*c83a76b0SSuyog Pawar             if((0 == ps_codec->i4_slice_error) ||
784*c83a76b0SSuyog Pawar                             (ps_codec->i4_bytes_remaining - (nal_len + nal_ofst) <= MIN_START_CODE_LEN))
785*c83a76b0SSuyog Pawar             {
786*c83a76b0SSuyog Pawar                 ps_codec->pu1_inp_bitsbuf += (nal_ofst + nal_len);
787*c83a76b0SSuyog Pawar                 ps_codec->i4_bytes_remaining -= (nal_ofst + nal_len);
788*c83a76b0SSuyog Pawar             }
789*c83a76b0SSuyog Pawar             if(ret != IHEVCD_SUCCESS)
790*c83a76b0SSuyog Pawar                 break;
791*c83a76b0SSuyog Pawar 
792*c83a76b0SSuyog Pawar             if(ps_codec->s_parse.i4_end_of_frame)
793*c83a76b0SSuyog Pawar                 break;
794*c83a76b0SSuyog Pawar         }
795*c83a76b0SSuyog Pawar         else
796*c83a76b0SSuyog Pawar         {
797*c83a76b0SSuyog Pawar             ret = IHEVCD_SUCCESS;
798*c83a76b0SSuyog Pawar             break;
799*c83a76b0SSuyog Pawar         }
800*c83a76b0SSuyog Pawar 
801*c83a76b0SSuyog Pawar         /* Allocate dynamic bitstream buffer once SPS is decoded */
802*c83a76b0SSuyog Pawar         if((ps_codec->u4_allocate_dynamic_done == 0) && ps_codec->i4_sps_done)
803*c83a76b0SSuyog Pawar         {
804*c83a76b0SSuyog Pawar             WORD32 ret;
805*c83a76b0SSuyog Pawar             ret = ihevcd_allocate_dynamic_bufs(ps_codec);
806*c83a76b0SSuyog Pawar             if(ret != IV_SUCCESS)
807*c83a76b0SSuyog Pawar             {
808*c83a76b0SSuyog Pawar                 /* Free any dynamic buffers that are allocated */
809*c83a76b0SSuyog Pawar                 ihevcd_free_dynamic_bufs(ps_codec);
810*c83a76b0SSuyog Pawar                 ps_codec->i4_error_code = IVD_MEM_ALLOC_FAILED;
811*c83a76b0SSuyog Pawar                 ps_dec_op->u4_error_code = 1 << IVD_FATALERROR;
812*c83a76b0SSuyog Pawar                 ps_dec_op->u4_error_code |= IVD_MEM_ALLOC_FAILED;
813*c83a76b0SSuyog Pawar 
814*c83a76b0SSuyog Pawar                 return IV_FAIL;
815*c83a76b0SSuyog Pawar             }
816*c83a76b0SSuyog Pawar         }
817*c83a76b0SSuyog Pawar 
818*c83a76b0SSuyog Pawar         BREAK_AFTER_SLICE_NAL();
819*c83a76b0SSuyog Pawar     }
820*c83a76b0SSuyog Pawar 
821*c83a76b0SSuyog Pawar     if(1 == ps_codec->i4_pic_present && 0 == ps_codec->s_parse.i4_end_of_frame)
822*c83a76b0SSuyog Pawar     {
823*c83a76b0SSuyog Pawar         slice_header_t *ps_slice_hdr_next;
824*c83a76b0SSuyog Pawar         ps_codec->i4_slice_error = 1;
825*c83a76b0SSuyog Pawar         ps_codec->s_parse.i4_cur_slice_idx--;
826*c83a76b0SSuyog Pawar         if(ps_codec->s_parse.i4_cur_slice_idx < 0)
827*c83a76b0SSuyog Pawar             ps_codec->s_parse.i4_cur_slice_idx = 0;
828*c83a76b0SSuyog Pawar 
829*c83a76b0SSuyog Pawar         ps_slice_hdr_next = ps_codec->s_parse.ps_slice_hdr_base + ((ps_codec->s_parse.i4_cur_slice_idx + 1) & (MAX_SLICE_HDR_CNT - 1));
830*c83a76b0SSuyog Pawar         ps_slice_hdr_next->i2_ctb_x = -1;
831*c83a76b0SSuyog Pawar         ps_slice_hdr_next->i2_ctb_y = -1;
832*c83a76b0SSuyog Pawar 
833*c83a76b0SSuyog Pawar         ihevcd_parse_slice_data(ps_codec);
834*c83a76b0SSuyog Pawar         ASSERT(ps_codec->s_parse.i4_end_of_frame != 0);
835*c83a76b0SSuyog Pawar     }
836*c83a76b0SSuyog Pawar 
837*c83a76b0SSuyog Pawar     if(1 == ps_codec->i4_pic_present)
838*c83a76b0SSuyog Pawar     {
839*c83a76b0SSuyog Pawar         WORD32 i;
840*c83a76b0SSuyog Pawar         sps_t *ps_sps = ps_codec->s_parse.ps_sps;
841*c83a76b0SSuyog Pawar         ps_codec->i4_first_pic_done = 1;
842*c83a76b0SSuyog Pawar 
843*c83a76b0SSuyog Pawar         /*TODO temporary fix: end_of_frame is checked before adding format conversion to job queue         */
844*c83a76b0SSuyog Pawar         if(ps_codec->i4_num_cores > 1 && ps_codec->s_parse.i4_end_of_frame)
845*c83a76b0SSuyog Pawar         {
846*c83a76b0SSuyog Pawar 
847*c83a76b0SSuyog Pawar             /* Add job queue for format conversion / frame copy for each ctb row */
848*c83a76b0SSuyog Pawar             /* Only if the codec is in non-shared mode or in shared mode but needs 420P output */
849*c83a76b0SSuyog Pawar             process_ctxt_t *ps_proc;
850*c83a76b0SSuyog Pawar 
851*c83a76b0SSuyog Pawar             /* i4_num_cores - 1 contexts are currently being used by other threads */
852*c83a76b0SSuyog Pawar             ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1];
853*c83a76b0SSuyog Pawar 
854*c83a76b0SSuyog Pawar             if((ps_codec->ps_disp_buf) &&
855*c83a76b0SSuyog Pawar                ((0 == ps_codec->i4_share_disp_buf) || (IV_YUV_420P == ps_codec->e_chroma_fmt)))
856*c83a76b0SSuyog Pawar             {
857*c83a76b0SSuyog Pawar                 /* If format conversion jobs were not issued in pic_init() add them here */
858*c83a76b0SSuyog Pawar                 if((0 == ps_codec->u4_enable_fmt_conv_ahead) ||
859*c83a76b0SSuyog Pawar                                 (ps_codec->i4_disp_buf_id == ps_proc->i4_cur_pic_buf_id))
860*c83a76b0SSuyog Pawar                     for(i = 0; i < ps_sps->i2_pic_ht_in_ctb; i++)
861*c83a76b0SSuyog Pawar                     {
862*c83a76b0SSuyog Pawar                         proc_job_t s_job;
863*c83a76b0SSuyog Pawar                         IHEVCD_ERROR_T ret;
864*c83a76b0SSuyog Pawar                         s_job.i4_cmd = CMD_FMTCONV;
865*c83a76b0SSuyog Pawar                         s_job.i2_ctb_cnt = 0;
866*c83a76b0SSuyog Pawar                         s_job.i2_ctb_x = 0;
867*c83a76b0SSuyog Pawar                         s_job.i2_ctb_y = i;
868*c83a76b0SSuyog Pawar                         s_job.i2_slice_idx = 0;
869*c83a76b0SSuyog Pawar                         s_job.i4_tu_coeff_data_ofst = 0;
870*c83a76b0SSuyog Pawar                         ret = ihevcd_jobq_queue((jobq_t *)ps_codec->s_parse.pv_proc_jobq,
871*c83a76b0SSuyog Pawar                                                 &s_job, sizeof(proc_job_t), 1);
872*c83a76b0SSuyog Pawar                         if(ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS)
873*c83a76b0SSuyog Pawar                             return (WORD32)ret;
874*c83a76b0SSuyog Pawar                     }
875*c83a76b0SSuyog Pawar             }
876*c83a76b0SSuyog Pawar             /* Reached end of frame : Signal terminate */
877*c83a76b0SSuyog Pawar             /* The terminate flag is checked only after all the jobs are dequeued */
878*c83a76b0SSuyog Pawar             ret = ihevcd_jobq_terminate((jobq_t *)ps_codec->s_parse.pv_proc_jobq);
879*c83a76b0SSuyog Pawar 
880*c83a76b0SSuyog Pawar             while(1)
881*c83a76b0SSuyog Pawar             {
882*c83a76b0SSuyog Pawar                 IHEVCD_ERROR_T ret;
883*c83a76b0SSuyog Pawar                 proc_job_t s_job;
884*c83a76b0SSuyog Pawar                 process_ctxt_t *ps_proc;
885*c83a76b0SSuyog Pawar 
886*c83a76b0SSuyog Pawar                 /* i4_num_cores - 1 contexts are currently being used by other threads */
887*c83a76b0SSuyog Pawar                 ps_proc = &ps_codec->as_process[ps_codec->i4_num_cores - 1];
888*c83a76b0SSuyog Pawar 
889*c83a76b0SSuyog Pawar                 ret = ihevcd_jobq_dequeue((jobq_t *)ps_proc->pv_proc_jobq, &s_job,
890*c83a76b0SSuyog Pawar                                           sizeof(proc_job_t), 1);
891*c83a76b0SSuyog Pawar                 if((IHEVCD_ERROR_T)IHEVCD_SUCCESS != ret)
892*c83a76b0SSuyog Pawar                     break;
893*c83a76b0SSuyog Pawar 
894*c83a76b0SSuyog Pawar                 ps_proc->i4_ctb_cnt = s_job.i2_ctb_cnt;
895*c83a76b0SSuyog Pawar                 ps_proc->i4_ctb_x = s_job.i2_ctb_x;
896*c83a76b0SSuyog Pawar                 ps_proc->i4_ctb_y = s_job.i2_ctb_y;
897*c83a76b0SSuyog Pawar                 ps_proc->i4_cur_slice_idx = s_job.i2_slice_idx;
898*c83a76b0SSuyog Pawar 
899*c83a76b0SSuyog Pawar                 if(CMD_PROCESS == s_job.i4_cmd)
900*c83a76b0SSuyog Pawar                 {
901*c83a76b0SSuyog Pawar                     ihevcd_init_proc_ctxt(ps_proc, s_job.i4_tu_coeff_data_ofst);
902*c83a76b0SSuyog Pawar 
903*c83a76b0SSuyog Pawar                     ihevcd_process(ps_proc);
904*c83a76b0SSuyog Pawar                 }
905*c83a76b0SSuyog Pawar                 else if(CMD_FMTCONV == s_job.i4_cmd)
906*c83a76b0SSuyog Pawar                 {
907*c83a76b0SSuyog Pawar                     sps_t *ps_sps = ps_codec->s_parse.ps_sps;
908*c83a76b0SSuyog Pawar                     WORD32 num_rows = 1 << ps_sps->i1_log2_ctb_size;
909*c83a76b0SSuyog Pawar                     if(0 == ps_proc->i4_init_done)
910*c83a76b0SSuyog Pawar                     {
911*c83a76b0SSuyog Pawar                         ihevcd_init_proc_ctxt(ps_proc, 0);
912*c83a76b0SSuyog Pawar                     }
913*c83a76b0SSuyog Pawar 
914*c83a76b0SSuyog Pawar                     num_rows = MIN(num_rows, (ps_codec->i4_disp_ht - (s_job.i2_ctb_y << ps_sps->i1_log2_ctb_size)));
915*c83a76b0SSuyog Pawar                     if(num_rows < 0)
916*c83a76b0SSuyog Pawar                         num_rows = 0;
917*c83a76b0SSuyog Pawar 
918*c83a76b0SSuyog Pawar                     ihevcd_fmt_conv(ps_codec, ps_proc,
919*c83a76b0SSuyog Pawar                                     ps_dec_ip->s_out_buffer.pu1_bufs[0],
920*c83a76b0SSuyog Pawar                                     ps_dec_ip->s_out_buffer.pu1_bufs[1],
921*c83a76b0SSuyog Pawar                                     ps_dec_ip->s_out_buffer.pu1_bufs[2],
922*c83a76b0SSuyog Pawar                                     s_job.i2_ctb_y << ps_sps->i1_log2_ctb_size,
923*c83a76b0SSuyog Pawar                                     num_rows);
924*c83a76b0SSuyog Pawar                 }
925*c83a76b0SSuyog Pawar             }
926*c83a76b0SSuyog Pawar         }
927*c83a76b0SSuyog Pawar         /* In case of non-shared mode and while running in single core mode, then convert/copy the frame to output buffer */
928*c83a76b0SSuyog Pawar         /* Only if the codec is in non-shared mode or in shared mode but needs 420P output */
929*c83a76b0SSuyog Pawar         else if((ps_codec->ps_disp_buf) && ((0 == ps_codec->i4_share_disp_buf) ||
930*c83a76b0SSuyog Pawar                                             (IV_YUV_420P == ps_codec->e_chroma_fmt)) &&
931*c83a76b0SSuyog Pawar                         (ps_codec->s_parse.i4_end_of_frame))
932*c83a76b0SSuyog Pawar         {
933*c83a76b0SSuyog Pawar             process_ctxt_t *ps_proc = &ps_codec->as_process[proc_idx];
934*c83a76b0SSuyog Pawar             /* Set remaining number of rows to be processed */
935*c83a76b0SSuyog Pawar             ps_codec->s_fmt_conv.i4_num_rows = ps_codec->i4_disp_ht
936*c83a76b0SSuyog Pawar                             - ps_codec->s_fmt_conv.i4_cur_row;
937*c83a76b0SSuyog Pawar             if(0 == ps_proc->i4_init_done)
938*c83a76b0SSuyog Pawar             {
939*c83a76b0SSuyog Pawar                 ihevcd_init_proc_ctxt(ps_proc, 0);
940*c83a76b0SSuyog Pawar             }
941*c83a76b0SSuyog Pawar 
942*c83a76b0SSuyog Pawar             if(ps_codec->s_fmt_conv.i4_num_rows < 0)
943*c83a76b0SSuyog Pawar                 ps_codec->s_fmt_conv.i4_num_rows = 0;
944*c83a76b0SSuyog Pawar 
945*c83a76b0SSuyog Pawar             ret = ihevcd_fmt_conv(ps_codec, ps_proc,
946*c83a76b0SSuyog Pawar                                   ps_dec_ip->s_out_buffer.pu1_bufs[0],
947*c83a76b0SSuyog Pawar                                   ps_dec_ip->s_out_buffer.pu1_bufs[1],
948*c83a76b0SSuyog Pawar                                   ps_dec_ip->s_out_buffer.pu1_bufs[2],
949*c83a76b0SSuyog Pawar                                   ps_codec->s_fmt_conv.i4_cur_row,
950*c83a76b0SSuyog Pawar                                   ps_codec->s_fmt_conv.i4_num_rows);
951*c83a76b0SSuyog Pawar             ps_codec->s_fmt_conv.i4_cur_row += ps_codec->s_fmt_conv.i4_num_rows;
952*c83a76b0SSuyog Pawar 
953*c83a76b0SSuyog Pawar         }
954*c83a76b0SSuyog Pawar 
955*c83a76b0SSuyog Pawar 
956*c83a76b0SSuyog Pawar         DEBUG_DUMP_MV_MAP(ps_codec);
957*c83a76b0SSuyog Pawar 
958*c83a76b0SSuyog Pawar         /* Mark MV Buf as needed for reference */
959*c83a76b0SSuyog Pawar         ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_mv_buf_mgr,
960*c83a76b0SSuyog Pawar                                  ps_codec->as_process[proc_idx].i4_cur_mv_bank_buf_id,
961*c83a76b0SSuyog Pawar                                  BUF_MGR_REF);
962*c83a76b0SSuyog Pawar 
963*c83a76b0SSuyog Pawar         /* Mark pic buf as needed for reference */
964*c83a76b0SSuyog Pawar         ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
965*c83a76b0SSuyog Pawar                                  ps_codec->as_process[proc_idx].i4_cur_pic_buf_id,
966*c83a76b0SSuyog Pawar                                  BUF_MGR_REF);
967*c83a76b0SSuyog Pawar 
968*c83a76b0SSuyog Pawar         /* Mark pic buf as needed for display */
969*c83a76b0SSuyog Pawar         ihevc_buf_mgr_set_status((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
970*c83a76b0SSuyog Pawar                                  ps_codec->as_process[proc_idx].i4_cur_pic_buf_id,
971*c83a76b0SSuyog Pawar                                  BUF_MGR_DISP);
972*c83a76b0SSuyog Pawar 
973*c83a76b0SSuyog Pawar         /* Insert the current picture as short term reference */
974*c83a76b0SSuyog Pawar         ihevc_dpb_mgr_insert_ref((dpb_mgr_t *)ps_codec->pv_dpb_mgr,
975*c83a76b0SSuyog Pawar                                  ps_codec->as_process[proc_idx].ps_cur_pic,
976*c83a76b0SSuyog Pawar                                  ps_codec->as_process[proc_idx].i4_cur_pic_buf_id);
977*c83a76b0SSuyog Pawar 
978*c83a76b0SSuyog Pawar         /* If a frame was displayed (in non-shared mode), then release it from display manager */
979*c83a76b0SSuyog Pawar         if((0 == ps_codec->i4_share_disp_buf) && (ps_codec->ps_disp_buf))
980*c83a76b0SSuyog Pawar             ihevc_buf_mgr_release((buf_mgr_t *)ps_codec->pv_pic_buf_mgr,
981*c83a76b0SSuyog Pawar                                   ps_codec->i4_disp_buf_id, BUF_MGR_DISP);
982*c83a76b0SSuyog Pawar 
983*c83a76b0SSuyog Pawar         /* Wait for threads */
984*c83a76b0SSuyog Pawar         for(i = 0; i < (ps_codec->i4_num_cores - 1); i++)
985*c83a76b0SSuyog Pawar         {
986*c83a76b0SSuyog Pawar             if(ps_codec->ai4_process_thread_created[i])
987*c83a76b0SSuyog Pawar             {
988*c83a76b0SSuyog Pawar                 if(ps_codec->i4_threads_active)
989*c83a76b0SSuyog Pawar                 {
990*c83a76b0SSuyog Pawar                     ret = ithread_mutex_lock(ps_codec->apv_proc_done_mutex[i]);
991*c83a76b0SSuyog Pawar                     RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
992*c83a76b0SSuyog Pawar 
993*c83a76b0SSuyog Pawar                     while(!ps_codec->ai4_process_done[i])
994*c83a76b0SSuyog Pawar                     {
995*c83a76b0SSuyog Pawar                         ithread_cond_wait(ps_codec->apv_proc_done_condition[i],
996*c83a76b0SSuyog Pawar                                           ps_codec->apv_proc_done_mutex[i]);
997*c83a76b0SSuyog Pawar                     }
998*c83a76b0SSuyog Pawar                     ps_codec->ai4_process_done[i] = 0;
999*c83a76b0SSuyog Pawar                     ret = ithread_mutex_unlock(ps_codec->apv_proc_done_mutex[i]);
1000*c83a76b0SSuyog Pawar                     RETURN_IF((ret != (IHEVCD_ERROR_T)IHEVCD_SUCCESS), ret);
1001*c83a76b0SSuyog Pawar                 }
1002*c83a76b0SSuyog Pawar                 else
1003*c83a76b0SSuyog Pawar                 {
1004*c83a76b0SSuyog Pawar                     ithread_join(ps_codec->apv_process_thread_handle[i], NULL);
1005*c83a76b0SSuyog Pawar                     ps_codec->ai4_process_thread_created[i] = 0;
1006*c83a76b0SSuyog Pawar                 }
1007*c83a76b0SSuyog Pawar             }
1008*c83a76b0SSuyog Pawar         }
1009*c83a76b0SSuyog Pawar 
1010*c83a76b0SSuyog Pawar         DEBUG_VALIDATE_PADDED_REGION(&ps_codec->as_process[proc_idx]);
1011*c83a76b0SSuyog Pawar         if(ps_codec->u4_pic_cnt > 0)
1012*c83a76b0SSuyog Pawar         {
1013*c83a76b0SSuyog Pawar             DEBUG_DUMP_PIC_PU(ps_codec);
1014*c83a76b0SSuyog Pawar         }
1015*c83a76b0SSuyog Pawar         DEBUG_DUMP_PIC_BUFFERS(ps_codec);
1016*c83a76b0SSuyog Pawar 
1017*c83a76b0SSuyog Pawar         /* Increment the number of pictures decoded */
1018*c83a76b0SSuyog Pawar         ps_codec->u4_pic_cnt++;
1019*c83a76b0SSuyog Pawar     }
1020*c83a76b0SSuyog Pawar     ihevcd_fill_outargs(ps_codec, ps_hevcd_dec_ip, ps_hevcd_dec_op);
1021*c83a76b0SSuyog Pawar 
1022*c83a76b0SSuyog Pawar     if(1 == ps_dec_op->u4_output_present)
1023*c83a76b0SSuyog Pawar     {
1024*c83a76b0SSuyog Pawar         WORD32 xpos = ps_codec->i4_disp_wd - 32 - LOGO_WD;
1025*c83a76b0SSuyog Pawar         WORD32 ypos = ps_codec->i4_disp_ht - 32 - LOGO_HT;
1026*c83a76b0SSuyog Pawar 
1027*c83a76b0SSuyog Pawar         if(ypos < 0)
1028*c83a76b0SSuyog Pawar             ypos = 0;
1029*c83a76b0SSuyog Pawar 
1030*c83a76b0SSuyog Pawar         if(xpos < 0)
1031*c83a76b0SSuyog Pawar             xpos = 0;
1032*c83a76b0SSuyog Pawar 
1033*c83a76b0SSuyog Pawar         INSERT_LOGO(ps_dec_ip->s_out_buffer.pu1_bufs[0],
1034*c83a76b0SSuyog Pawar                     ps_dec_ip->s_out_buffer.pu1_bufs[1],
1035*c83a76b0SSuyog Pawar                     ps_dec_ip->s_out_buffer.pu1_bufs[2], ps_codec->i4_disp_strd,
1036*c83a76b0SSuyog Pawar                     xpos,
1037*c83a76b0SSuyog Pawar                     ypos,
1038*c83a76b0SSuyog Pawar                     ps_codec->e_chroma_fmt,
1039*c83a76b0SSuyog Pawar                     ps_codec->i4_disp_wd,
1040*c83a76b0SSuyog Pawar                     ps_codec->i4_disp_ht);
1041*c83a76b0SSuyog Pawar     }
1042*c83a76b0SSuyog Pawar 
1043*c83a76b0SSuyog Pawar 
1044*c83a76b0SSuyog Pawar     return ret;
1045*c83a76b0SSuyog Pawar }
1046*c83a76b0SSuyog Pawar 
1047