1 /******************************************************************************
2 *
3 * Copyright (C) 2022 The Android Open Source Project
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 * Originally developed and contributed by Ittiam Systems Pvt. Ltd, Bangalore
19 */
20 /**
21 *******************************************************************************
22 * @file
23 * isvcd_thread_parse_decode.c
24 *
25 * @brief
26 * Contains routines that for multi-thread decoder
27 *
28 * @author
29 * Kishore
30 *
31 * @remarks
32 * None
33 *
34 *******************************************************************************
35 */
36
37 #include <string.h>
38 #include "ih264d_error_handler.h"
39 #include "ih264d_debug.h"
40 #include "ithread.h"
41 #include "ih264d_defs.h"
42 #include "ih264d_debug.h"
43 #include "ih264d_tables.h"
44 #include "isvcd_structs.h"
45 #include "ih264d_defs.h"
46 #include "ih264d_mb_utils.h"
47 #include "ih264d_thread_parse_decode.h"
48 #include "ih264d_inter_pred.h"
49 #include "ih264d_process_pslice.h"
50 #include "isvcd_process_epslice.h"
51 #include "ih264d_process_intra_mb.h"
52 #include "ih264d_deblocking.h"
53 #include "ih264d_format_conv.h"
54 #include "isvcd_thread_parse_decode.h"
55
56 /*****************************************************************************/
57 /* */
58 /* Function Name : isvcd_decode_recon_tfr_nmb_thread */
59 /* */
60 /* Description : */
61 /* : */
62 /* : */
63 /* Inputs : */
64 /* Processing :Only for Target Layer processing */
65 /* */
66 /* Outputs : */
67 /* Returns : None */
68 /* */
69 /* Revision History: */
70 /* */
71 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
72 /* ITTIAM */
73 /*****************************************************************************/
isvcd_decode_recon_tfr_nmb_thread(svc_dec_lyr_struct_t * ps_svc_lyr_dec,UWORD8 u1_num_mbs,UWORD8 u1_num_mbs_next,UWORD8 u1_end_of_row)74 WORD32 isvcd_decode_recon_tfr_nmb_thread(svc_dec_lyr_struct_t *ps_svc_lyr_dec, UWORD8 u1_num_mbs,
75 UWORD8 u1_num_mbs_next, UWORD8 u1_end_of_row)
76 {
77 WORD32 i, j;
78 dec_mb_info_t *ps_cur_mb_info;
79 dec_svc_mb_info_t *ps_svc_cur_mb_info;
80 dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
81 const UWORD32 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag;
82 UWORD32 u1_slice_type, u1_B;
83 WORD32 u1_skip_th;
84 UWORD32 u1_ipcm_th;
85 UWORD32 u4_cond;
86 UWORD16 u2_slice_num, u2_cur_dec_mb_num;
87 UWORD32 u4_mb_num;
88 WORD32 nop_cnt = 8 * 128;
89 UWORD16 *pu2_res_luma_csbp;
90 WORD32 ret;
91 u1_slice_type = ps_dec->ps_decode_cur_slice->slice_type;
92
93 u1_B = (u1_slice_type == B_SLICE);
94 u1_skip_th = ((u1_slice_type != I_SLICE) ? (u1_B ? B_8x8 : PRED_8x8R0) : -1);
95 u1_ipcm_th = ((u1_slice_type != I_SLICE) ? (u1_B ? 23 : 5) : 0);
96 u2_cur_dec_mb_num = ps_dec->cur_dec_mb_num;
97
98 while(1)
99 {
100 UWORD32 u4_max_mb =
101 (UWORD32) (ps_dec->i2_dec_thread_mb_y + (1 << u1_mbaff)) * ps_dec->u2_frm_wd_in_mbs - 1;
102 u4_mb_num = u2_cur_dec_mb_num;
103 /*introducing 1 MB delay*/
104 u4_mb_num = MIN(u4_mb_num + u1_num_mbs + 1, u4_max_mb);
105
106 CHECK_MB_MAP_BYTE(u4_mb_num, ps_dec->pu1_dec_mb_map, u4_cond);
107 if(u4_cond)
108 {
109 break;
110 }
111 else
112 {
113 if(nop_cnt > 0)
114 {
115 nop_cnt -= 128;
116 NOP(128);
117 }
118 else
119 {
120 if(ps_dec->u4_output_present && (2 == ps_dec->u4_num_cores) &&
121 (ps_dec->u4_fmt_conv_cur_row < ps_dec->s_disp_frame_info.u4_y_ht))
122 {
123 ps_dec->u4_fmt_conv_num_rows =
124 MIN(FMT_CONV_NUM_ROWS,
125 (ps_dec->s_disp_frame_info.u4_y_ht - ps_dec->u4_fmt_conv_cur_row));
126 ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op), ps_dec->u4_fmt_conv_cur_row,
127 ps_dec->u4_fmt_conv_num_rows);
128 ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows;
129 }
130 else
131 {
132 nop_cnt = 8 * 128;
133 ithread_yield();
134 }
135 if(1 == ps_svc_lyr_dec->u1_error_in_cur_frame)
136 {
137 return NOT_OK;
138 }
139 }
140 }
141 }
142
143 /* N Mb MC Loop */
144 for(i = 0; i < u1_num_mbs; i++)
145 {
146 u4_mb_num = u2_cur_dec_mb_num;
147 GET_SLICE_NUM_MAP(ps_dec->pu2_slice_num_map, u2_cur_dec_mb_num, u2_slice_num);
148
149 if(u2_slice_num != ps_dec->u2_cur_slice_num_dec_thread)
150 {
151 ps_dec->u4_cur_slice_decode_done = 1;
152 break;
153 }
154
155 ps_cur_mb_info = &ps_dec->ps_frm_mb_info[u2_cur_dec_mb_num];
156
157 ps_dec->u4_dma_buf_idx = 0;
158 ps_dec->u4_pred_info_idx = 0;
159
160 /*Pointer assignment for Residual NNZ */
161 pu2_res_luma_csbp = ps_svc_lyr_dec->pu2_frm_res_luma_csbp + ps_cur_mb_info->u2_mbx;
162 pu2_res_luma_csbp += ps_cur_mb_info->u2_mby * ps_svc_lyr_dec->i4_frm_res_luma_csbp_stride;
163
164 if(ps_cur_mb_info->u1_mb_type <= u1_skip_th)
165 {
166 WORD32 pred_cnt = 0;
167 pred_info_pkd_t *ps_pred_pkd;
168 UWORD32 u4_pred_info_pkd_idx;
169
170 u4_pred_info_pkd_idx = ps_cur_mb_info->u4_pred_info_pkd_idx;
171
172 while(pred_cnt < ps_cur_mb_info->u1_num_pred_parts)
173 {
174 ps_pred_pkd = ps_dec->ps_pred_pkd + u4_pred_info_pkd_idx;
175
176 ps_dec->p_form_mb_part_info_thread(ps_pred_pkd, ps_dec, ps_cur_mb_info->u2_mbx,
177 ps_cur_mb_info->u2_mby, (i >> u1_mbaff),
178 ps_cur_mb_info);
179
180 u4_pred_info_pkd_idx++;
181 pred_cnt++;
182 }
183 ps_dec->p_mc_dec_thread(ps_dec, ps_cur_mb_info);
184 }
185 else if(ps_cur_mb_info->u1_mb_type == MB_SKIP)
186 {
187 WORD32 pred_cnt = 0;
188 pred_info_pkd_t *ps_pred_pkd;
189 UWORD32 u4_pred_info_pkd_idx;
190
191 u4_pred_info_pkd_idx = ps_cur_mb_info->u4_pred_info_pkd_idx;
192
193 while(pred_cnt < ps_cur_mb_info->u1_num_pred_parts)
194 {
195 ps_pred_pkd = ps_dec->ps_pred_pkd + u4_pred_info_pkd_idx;
196
197 ps_dec->p_form_mb_part_info_thread(ps_pred_pkd, ps_dec, ps_cur_mb_info->u2_mbx,
198 ps_cur_mb_info->u2_mby, (i >> u1_mbaff),
199 ps_cur_mb_info);
200
201 u4_pred_info_pkd_idx++;
202 pred_cnt++;
203 }
204 /* Decode MB skip */
205 ps_dec->p_mc_dec_thread(ps_dec, ps_cur_mb_info);
206
207 *pu2_res_luma_csbp = 0;
208 ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb =
209 ps_svc_lyr_dec->ps_inter_lyr_mb_prms_frm_start + ps_cur_mb_info->u2_mbx +
210 (ps_svc_lyr_dec->u2_inter_lyr_mb_prms_stride * (ps_cur_mb_info->u2_mby));
211 ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_mb_mode = SVC_INTER_MB;
212 ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_tx_size =
213 ps_cur_mb_info->u1_tran_form8x8;
214 ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u2_luma_nnz = 0;
215 ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->u1_chroma_nnz = 0;
216 }
217
218 u2_cur_dec_mb_num++;
219 }
220
221 /* N Mb IQ IT RECON Loop */
222 for(j = 0; j < i; j++)
223 {
224 ps_cur_mb_info = &ps_dec->ps_frm_mb_info[ps_dec->cur_dec_mb_num];
225 ps_svc_cur_mb_info = &ps_svc_lyr_dec->ps_svc_frm_mb_info[ps_dec->cur_dec_mb_num];
226
227 if(NULL == ps_cur_mb_info->ps_curmb)
228 {
229 return NOT_OK;
230 }
231
232 /*Pointer assignment for Residual NNZ */
233 pu2_res_luma_csbp = ps_svc_lyr_dec->pu2_frm_res_luma_csbp + ps_cur_mb_info->u2_mbx;
234 pu2_res_luma_csbp += ps_cur_mb_info->u2_mby * ps_svc_lyr_dec->i4_frm_res_luma_csbp_stride;
235
236 ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb =
237 ps_svc_lyr_dec->ps_inter_lyr_mb_prms_frm_start + ps_cur_mb_info->u2_mbx +
238 (ps_svc_lyr_dec->u2_inter_lyr_mb_prms_stride * (ps_cur_mb_info->u2_mby));
239
240 ps_svc_lyr_dec->ps_inter_lyr_mb_prms_cur_mb->i1_slice_id = (WORD8) ps_dec->u2_cur_slice_num;
241
242 if((ps_dec->u4_num_cores == 2) || !ps_dec->i1_recon_in_thread3_flag)
243 {
244 if(ps_cur_mb_info->u1_mb_type <= u1_skip_th)
245 {
246 {
247 /* inter intra pred generation */
248 if(SVCD_FALSE == ps_svc_lyr_dec->u1_dyadic_flag)
249 {
250 ret = isvcd_process_ii_mb(ps_svc_lyr_dec, ps_cur_mb_info,
251 ps_svc_cur_mb_info, j);
252 if(ret != OK) return ret;
253 }
254 if(0 == ps_svc_cur_mb_info->u1_residual_prediction_flag)
255 {
256 /* IT + Recon */
257 ih264d_process_inter_mb(ps_dec, ps_cur_mb_info, j);
258 isvcd_update_inter_mb_inter_layer_info(ps_svc_lyr_dec, ps_cur_mb_info, 0);
259 *pu2_res_luma_csbp = ps_cur_mb_info->u2_luma_csbp;
260 }
261 else
262 {
263 /* IT + Residual + Recon */
264 ret = isvcd_process_inter_mb_rsd_pred_target_lyr(
265 ps_svc_lyr_dec, ps_cur_mb_info, j, 0, pu2_res_luma_csbp);
266 if(ret != OK) return ret;
267 }
268 }
269 }
270
271 else if((ps_cur_mb_info->u1_mb_type != MB_SKIP) &&
272 (ps_cur_mb_info->u1_mb_type != MB_INFER))
273 {
274 if((u1_ipcm_th + 25) != ps_cur_mb_info->u1_mb_type)
275 {
276 ps_cur_mb_info->u1_mb_type -= (u1_skip_th + 1);
277 ih264d_process_intra_mb(ps_dec, ps_cur_mb_info, j);
278 isvcd_update_intra_mb_inter_layer_info(ps_svc_lyr_dec, ps_cur_mb_info);
279 }
280 else
281 {
282 isvcd_update_ipcm_mb_inter_layer_info(ps_svc_lyr_dec, ps_cur_mb_info);
283 }
284 *pu2_res_luma_csbp = 0;
285 }
286 else if(ps_cur_mb_info->u1_mb_type == MB_INFER)
287 {
288 /* inter layer intra prediction : intra upsample, IQ, IT ,deblock */
289 {
290 /* Intra resample for IBL mode */
291 ret = isvcd_process_ibl_mb(ps_svc_lyr_dec, ps_cur_mb_info, j, 0);
292 if(ret != OK) return ret;
293 /* Pass intra resample as pred to Recon generation */
294 ih264d_process_inter_mb(ps_dec, ps_cur_mb_info, j);
295 isvcd_update_inter_mb_inter_layer_info(ps_svc_lyr_dec, ps_cur_mb_info, 1);
296 *pu2_res_luma_csbp = ps_cur_mb_info->u2_luma_csbp;
297 }
298 ps_dec->pi1_left_pred_mode[0] = DC;
299 ps_dec->pi1_left_pred_mode[1] = DC;
300 ps_dec->pi1_left_pred_mode[2] = DC;
301 ps_dec->pi1_left_pred_mode[3] = DC;
302
303 ps_cur_mb_info->ps_curmb->pi1_intrapredmodes[0] = DC;
304 ps_cur_mb_info->ps_curmb->pi1_intrapredmodes[1] = DC;
305 ps_cur_mb_info->ps_curmb->pi1_intrapredmodes[2] = DC;
306 ps_cur_mb_info->ps_curmb->pi1_intrapredmodes[3] = DC;
307
308 isvcd_update_ibl_mb_inter_layer_info(ps_svc_lyr_dec, ps_cur_mb_info);
309 }
310
311 if(ps_dec->u4_use_intrapred_line_copy == 1)
312 ih264d_copy_intra_pred_line(ps_dec, ps_cur_mb_info, j);
313 }
314
315 DATA_SYNC();
316
317 u4_mb_num = ps_cur_mb_info->u2_mbx + ps_dec->u2_frm_wd_in_mbs * ps_cur_mb_info->u2_mby;
318 UPDATE_MB_MAP_MBNUM_BYTE(ps_dec->pu1_recon_mb_map, u4_mb_num);
319 ps_dec->cur_dec_mb_num++;
320 }
321
322 /*N MB deblocking*/
323 if(ps_dec->u4_nmb_deblk == 1)
324 {
325 UWORD32 u4_wd_y, u4_wd_uv;
326 tfr_ctxt_t *ps_tfr_cxt = &(ps_dec->s_tran_addrecon);
327 UWORD8 u1_field_pic_flag = ps_dec->ps_cur_slice->u1_field_pic_flag;
328 const WORD32 i4_cb_qp_idx_ofst = ps_dec->ps_cur_pps->i1_chroma_qp_index_offset;
329 const WORD32 i4_cr_qp_idx_ofst = ps_dec->ps_cur_pps->i1_second_chroma_qp_index_offset;
330
331 u4_wd_y = ps_dec->u2_frm_wd_y << u1_field_pic_flag;
332 u4_wd_uv = ps_dec->u2_frm_wd_uv << u1_field_pic_flag;
333
334 ps_cur_mb_info = &ps_dec->ps_frm_mb_info[ps_dec->u4_cur_deblk_mb_num];
335
336 ps_dec->u4_deblk_mb_x = ps_cur_mb_info->u2_mbx;
337 ps_dec->u4_deblk_mb_y = ps_cur_mb_info->u2_mby;
338
339 for(j = 0; j < i; j++)
340 {
341 ih264d_deblock_mb_nonmbaff(ps_dec, ps_tfr_cxt, i4_cb_qp_idx_ofst, i4_cr_qp_idx_ofst,
342 u4_wd_y, u4_wd_uv);
343 }
344 }
345
346 /*handle the last mb in picture case*/
347 if(ps_dec->cur_dec_mb_num > ps_dec->ps_cur_sps->u2_max_mb_addr)
348 ps_dec->u4_cur_slice_decode_done = 1;
349
350 if(i != u1_num_mbs)
351 {
352 u1_end_of_row = 0;
353 /*Number of MB's left in row*/
354 u1_num_mbs_next = u1_num_mbs_next + ((u1_num_mbs - i) >> u1_mbaff);
355 }
356
357 ih264d_decode_tfr_nmb(ps_dec, (i), u1_num_mbs_next, u1_end_of_row);
358
359 return OK;
360 }
361
362 /*****************************************************************************/
363 /* */
364 /* Function Name : isvcd_decode_slice_thread */
365 /* */
366 /* Description : */
367 /* : */
368 /* : */
369 /* Inputs : */
370 /* Processing : */
371 /* */
372 /* Outputs : */
373 /* Returns : 0 on success */
374 /* */
375 /* Revision History: */
376 /* */
377 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
378 /* ITTIAM */
379 /*****************************************************************************/
isvcd_decode_slice_thread(svc_dec_lyr_struct_t * ps_svc_lyr_dec)380 WORD32 isvcd_decode_slice_thread(svc_dec_lyr_struct_t *ps_svc_lyr_dec)
381 {
382 UWORD8 u1_num_mbs_next, u1_num_mbsleft, u1_end_of_row = 0;
383 dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
384 const UWORD32 i2_pic_wdin_mbs = ps_dec->u2_frm_wd_in_mbs;
385 UWORD8 u1_mbaff, u1_num_mbs;
386
387 UWORD16 u2_first_mb_in_slice;
388 UWORD16 i16_mb_x, i16_mb_y;
389 UWORD8 u1_field_pic;
390 UWORD32 u4_frame_stride, x_offset, y_offset;
391 WORD32 ret;
392 tfr_ctxt_t *ps_trns_addr;
393
394 /*check for mb map of first mb in slice to ensure slice header is parsed*/
395 while(1)
396 {
397 UWORD32 u4_mb_num = ps_dec->cur_dec_mb_num;
398 UWORD32 u4_cond = 0;
399 WORD32 nop_cnt = 8 * 128;
400 CHECK_MB_MAP_BYTE(u4_mb_num, ps_dec->pu1_dec_mb_map, u4_cond);
401 if(u4_cond)
402 {
403 break;
404 }
405 else
406 {
407 if(nop_cnt > 0)
408 {
409 nop_cnt -= 128;
410 NOP(128);
411 }
412 else if(ps_dec->u4_output_present && (2 == ps_dec->u4_num_cores) &&
413 (ps_dec->u4_fmt_conv_cur_row < ps_dec->s_disp_frame_info.u4_y_ht))
414 {
415 ps_dec->u4_fmt_conv_num_rows =
416 MIN(FMT_CONV_NUM_ROWS,
417 (ps_dec->s_disp_frame_info.u4_y_ht - ps_dec->u4_fmt_conv_cur_row));
418 ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op), ps_dec->u4_fmt_conv_cur_row,
419 ps_dec->u4_fmt_conv_num_rows);
420 ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows;
421 }
422 else
423 {
424 nop_cnt = 8 * 128;
425 ithread_yield();
426 }
427 if(1 == ps_svc_lyr_dec->u1_error_in_cur_frame)
428 {
429 return NOT_OK;
430 }
431 DEBUG_THREADS_PRINTF(
432 "waiting for mb mapcur_dec_mb_num = %d,ps_dec->u2_cur_mb_addr = "
433 "%d\n",
434 u2_cur_dec_mb_num, ps_dec->u2_cur_mb_addr);
435 }
436 }
437
438 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag;
439 u2_first_mb_in_slice = ps_dec->ps_decode_cur_slice->u4_first_mb_in_slice;
440 i16_mb_x = MOD(u2_first_mb_in_slice, i2_pic_wdin_mbs);
441 i16_mb_y = DIV(u2_first_mb_in_slice, i2_pic_wdin_mbs);
442 i16_mb_y <<= u1_mbaff;
443 ps_dec->i2_dec_thread_mb_y = i16_mb_y;
444 ps_dec->cur_dec_mb_num = u2_first_mb_in_slice << u1_mbaff;
445
446 if((ps_dec->u4_num_cores == 2) || !ps_dec->i1_recon_in_thread3_flag)
447 {
448 ps_dec->pv_proc_tu_coeff_data =
449 (void *) ps_dec->ps_decode_cur_slice->pv_tu_coeff_data_start;
450 }
451
452 // recalculate recon pointers
453 u1_field_pic = ps_dec->ps_cur_slice->u1_field_pic_flag;
454 u4_frame_stride = ps_dec->u2_frm_wd_y << u1_field_pic;
455 x_offset = i16_mb_x << 4;
456 y_offset = (i16_mb_y * u4_frame_stride) << 4;
457
458 ps_trns_addr = &(ps_dec->s_tran_addrecon);
459
460 ps_trns_addr->pu1_dest_y = ps_dec->s_cur_pic.pu1_buf1 + x_offset + y_offset;
461
462 u4_frame_stride = ps_dec->u2_frm_wd_uv << u1_field_pic;
463 x_offset >>= 1;
464 y_offset = (i16_mb_y * u4_frame_stride) << 3;
465 x_offset *= YUV420SP_FACTOR;
466
467 ps_trns_addr->pu1_dest_u = ps_dec->s_cur_pic.pu1_buf2 + x_offset + y_offset;
468 ps_trns_addr->pu1_dest_v = ps_dec->s_cur_pic.pu1_buf3 + x_offset + y_offset;
469
470 ps_trns_addr->pu1_mb_y = ps_trns_addr->pu1_dest_y;
471 ps_trns_addr->pu1_mb_u = ps_trns_addr->pu1_dest_u;
472 ps_trns_addr->pu1_mb_v = ps_trns_addr->pu1_dest_v;
473
474 /* Initialise MC and formMbPartInfo fn ptrs one time based on profile_idc */
475 {
476 ps_dec->p_mc_dec_thread = ih264d_motion_compensate_bp;
477 ps_dec->p_form_mb_part_info_thread = ih264d_form_mb_part_info_bp;
478 }
479 {
480 UWORD8 uc_nofield_nombaff;
481 uc_nofield_nombaff = ((ps_dec->ps_cur_slice->u1_field_pic_flag == 0) &&
482 (ps_dec->ps_cur_slice->u1_mbaff_frame_flag == 0) &&
483 (ps_dec->ps_decode_cur_slice->slice_type != B_SLICE) &&
484 (ps_dec->ps_cur_pps->u1_wted_pred_flag == 0));
485
486 if(uc_nofield_nombaff == 0)
487 {
488 ps_dec->p_mc_dec_thread = ih264d_motion_compensate_mp;
489 ps_dec->p_form_mb_part_info_thread = ih264d_form_mb_part_info_mp;
490 }
491 }
492
493 ps_dec->u4_cur_slice_decode_done = 0;
494
495 while(ps_dec->u4_cur_slice_decode_done != 1)
496 {
497 u1_num_mbsleft = ((i2_pic_wdin_mbs - i16_mb_x) << u1_mbaff);
498
499 if(u1_num_mbsleft <= ps_dec->u1_recon_mb_grp)
500 {
501 u1_num_mbs = u1_num_mbsleft;
502
503 /*Indicate number of mb's left in a row*/
504 u1_num_mbs_next = 0;
505 u1_end_of_row = 1;
506 i16_mb_x = 0;
507 }
508 else
509 {
510 u1_num_mbs = ps_dec->u1_recon_mb_grp;
511
512 /*Indicate number of mb's left in a row*/
513 u1_num_mbs_next = i2_pic_wdin_mbs - i16_mb_x - (ps_dec->u1_recon_mb_grp >> u1_mbaff);
514 i16_mb_x += (u1_num_mbs >> u1_mbaff);
515 u1_end_of_row = 0;
516 }
517 if(ps_svc_lyr_dec->u1_layer_identifier == TARGET_LAYER)
518 {
519 ret = isvcd_decode_recon_tfr_nmb_thread(ps_svc_lyr_dec, u1_num_mbs, u1_num_mbs_next,
520 u1_end_of_row);
521 }
522 if(ret != OK) return ret;
523 }
524 return OK;
525 }
526
527 /*****************************************************************************/
528 /* */
529 /* Function Name : isvcd_decode_picture_thread */
530 /* */
531 /* Description : */
532 /* : */
533 /* : */
534 /* Inputs : */
535 /* Processing : */
536 /* */
537 /* Outputs : */
538 /* Returns : None */
539 /* */
540 /* Revision History: */
541 /* */
542 /* DD MM YYYY Author(s) Changes (Describe the changes made) */
543 /* ITTIAM */
544 /*****************************************************************************/
isvcd_decode_picture_thread(svc_dec_lyr_struct_t * ps_svc_lyr_dec)545 void isvcd_decode_picture_thread(svc_dec_lyr_struct_t *ps_svc_lyr_dec)
546 {
547 dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
548 WORD32 ret;
549 ithread_set_name("isvcd_decode_picture_thread");
550 while(1)
551 {
552 #ifdef KEEP_THREADS_ACTIVE
553 ret = ithread_mutex_lock(ps_dec->apv_proc_start_mutex[0]);
554 if(OK != ret) break;
555
556 while(ps_dec->ai4_process_start[0] != PROC_START)
557 {
558 ithread_cond_wait(ps_dec->apv_proc_start_condition[0], ps_dec->apv_proc_start_mutex[0]);
559 }
560 ps_dec->ai4_process_start[0] = PROC_IN_PROGRESS;
561
562 ret = ithread_mutex_unlock(ps_dec->apv_proc_start_mutex[0]);
563 if(OK != ret || ps_dec->i4_break_threads == 1) break;
564 #endif
565 while(1)
566 {
567 /*Complete all writes before processing next slice*/
568
569 DEBUG_THREADS_PRINTF(" Entering decode slice svc ext\n");
570
571 ret = isvcd_decode_slice_thread(ps_svc_lyr_dec);
572 if(OK != ret) break;
573 DEBUG_THREADS_PRINTF(" Exit isvcd_decode_slice_thread\n");
574
575 if(ps_dec->cur_dec_mb_num > ps_dec->ps_cur_sps->u2_max_mb_addr)
576 {
577 /*Last slice in frame*/
578 break;
579 }
580 else
581 {
582 ps_dec->ps_decode_cur_slice++;
583 ps_dec->u2_cur_slice_num_dec_thread++;
584 }
585 }
586 if(ps_dec->u4_output_present && (2 == ps_dec->u4_num_cores) &&
587 (ps_dec->u4_fmt_conv_cur_row < ps_dec->s_disp_frame_info.u4_y_ht))
588 {
589 ps_dec->u4_fmt_conv_num_rows =
590 (ps_dec->s_disp_frame_info.u4_y_ht - ps_dec->u4_fmt_conv_cur_row);
591 ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op), ps_dec->u4_fmt_conv_cur_row,
592 ps_dec->u4_fmt_conv_num_rows);
593 ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows;
594 }
595 #ifdef KEEP_THREADS_ACTIVE
596 ret = ithread_mutex_lock(ps_dec->apv_proc_done_mutex[0]);
597 if(OK != ret) break;
598
599 ps_dec->ai4_process_done[0] = PROC_DONE;
600 ithread_cond_signal(ps_dec->apv_proc_done_condition[0]);
601
602 ret = ithread_mutex_unlock(ps_dec->apv_proc_done_mutex[0]);
603 if(OK != ret) break;
604 #else
605 break;
606 #endif
607 }
608 }
609