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