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