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