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