1 /******************************************************************************
2  *
3  * Copyright (C) 2015 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 ih264d_thread_parse_decode.c
23  *
24  * \brief
25  *    Contains routines that for multi-thread decoder
26  *
27  * Detailed_description
28  *
29  * \date
30  *    20/02/2012
31  *
32  * \author  ZR
33  **************************************************************************
34  */
35 
36 #include "ih264d_error_handler.h"
37 #include "ih264d_debug.h"
38 #include "ithread.h"
39 #include <string.h>
40 #include "ih264d_defs.h"
41 #include "ih264d_debug.h"
42 #include "ih264d_tables.h"
43 #include "ih264d_structs.h"
44 #include "ih264d_defs.h"
45 #include "ih264d_mb_utils.h"
46 #include "ih264d_thread_parse_decode.h"
47 #include "ih264d_inter_pred.h"
48 
49 #include "ih264d_process_pslice.h"
50 #include "ih264d_process_intra_mb.h"
51 #include "ih264d_deblocking.h"
52 #include "ih264d_format_conv.h"
53 
54 void ih264d_deblock_mb_level(dec_struct_t *ps_dec,
55                              dec_mb_info_t *ps_cur_mb_info,
56                              UWORD32 nmb_index);
57 
58 void ih264d_copy_intra_pred_line(dec_struct_t *ps_dec,
59                                  dec_mb_info_t *ps_cur_mb_info,
60                                  UWORD32 nmb_index);
61 
ih264d_parse_tfr_nmb(dec_struct_t * ps_dec,UWORD8 u1_mb_idx,UWORD8 u1_num_mbs,UWORD8 u1_num_mbs_next,UWORD8 u1_tfr_n_mb,UWORD8 u1_end_of_row)62 void ih264d_parse_tfr_nmb(dec_struct_t * ps_dec,
63                           UWORD8 u1_mb_idx,
64                           UWORD8 u1_num_mbs,
65                           UWORD8 u1_num_mbs_next,
66                           UWORD8 u1_tfr_n_mb,
67                           UWORD8 u1_end_of_row)
68 {
69     WORD32 i, u4_mb_num;
70 
71     const UWORD32 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag;
72     UWORD32 u4_n_mb_start;
73 
74     UNUSED(u1_mb_idx);
75     UNUSED(u1_num_mbs_next);
76     if(u1_tfr_n_mb)
77     {
78 
79 
80         u4_n_mb_start = (ps_dec->u2_cur_mb_addr + 1) - u1_num_mbs;
81 
82         // copy into s_frmMbInfo
83 
84         u4_mb_num = u4_n_mb_start;
85         u4_mb_num = (ps_dec->u2_cur_mb_addr + 1) - u1_num_mbs;
86 
87         for(i = 0; i < u1_num_mbs; i++)
88         {
89             UPDATE_SLICE_NUM_MAP(ps_dec->pu2_slice_num_map, u4_mb_num,
90                                  ps_dec->u2_cur_slice_num);
91             DATA_SYNC();
92             UPDATE_MB_MAP_MBNUM_BYTE(ps_dec->pu1_dec_mb_map, u4_mb_num);
93 
94             u4_mb_num++;
95         }
96 
97         /****************************************************************/
98         /* Check for End Of Row in Next iteration                       */
99         /****************************************************************/
100 
101         /****************************************************************/
102         /* Transfer the Following things                                */
103         /* N-Mb DeblkParams Data    ( To Ext DeblkParams Buffer )       */
104         /* N-Mb Recon Data          ( To Ext Frame Buffer )             */
105         /* N-Mb Intrapredline Data  ( Updated Internally)               */
106         /* N-Mb MV Data             ( To Ext MV Buffer )                */
107         /* N-Mb MVTop/TopRight Data ( To Int MV Top Scratch Buffers)    */
108         /****************************************************************/
109 
110         /* Swap top and current pointers */
111 
112         ps_dec->s_tran_addrecon_parse.pu1_dest_y +=
113                         ps_dec->s_tran_addrecon_parse.u4_inc_y[u1_end_of_row];
114         ps_dec->s_tran_addrecon_parse.pu1_dest_u +=
115                         ps_dec->s_tran_addrecon_parse.u4_inc_uv[u1_end_of_row];
116         ps_dec->s_tran_addrecon_parse.pu1_dest_v +=
117                         ps_dec->s_tran_addrecon_parse.u4_inc_uv[u1_end_of_row];
118 
119         if(u1_end_of_row)
120         {
121             UWORD16 u2_mb_y;
122             UWORD32 u4_frame_stride, y_offset;
123 
124             ps_dec->ps_top_mb_row = ps_dec->ps_cur_mb_row;
125             ps_dec->ps_cur_mb_row += ((ps_dec->u2_frm_wd_in_mbs) << u1_mbaff);
126 
127             u2_mb_y = ps_dec->u2_mby + (1 + u1_mbaff);
128             u4_frame_stride = ps_dec->u2_frm_wd_y
129                             << ps_dec->ps_cur_slice->u1_field_pic_flag;
130             y_offset = (u2_mb_y * u4_frame_stride) << 4;
131             ps_dec->s_tran_addrecon_parse.pu1_dest_y =
132                             ps_dec->s_cur_pic.pu1_buf1 + y_offset;
133 
134             u4_frame_stride = ps_dec->u2_frm_wd_uv
135                             << ps_dec->ps_cur_slice->u1_field_pic_flag;
136             y_offset = (u2_mb_y * u4_frame_stride) << 3;
137             ps_dec->s_tran_addrecon_parse.pu1_dest_u =
138                             ps_dec->s_cur_pic.pu1_buf2 + y_offset;
139             ps_dec->s_tran_addrecon_parse.pu1_dest_v =
140                             ps_dec->s_cur_pic.pu1_buf3 + y_offset;
141 
142         }
143 
144         ps_dec->ps_deblk_mbn += u1_num_mbs;
145 
146         /*
147          * The Slice boundary is also a valid condition to transfer. So recalculate
148          * the Left increment, in case the number of MBs is lesser than the
149          * N MB value. c_numMbs will be equal to N of N MB if the entire N Mb is
150          * decoded.
151          */
152         ps_dec->s_tran_addrecon.u2_mv_left_inc = ((u1_num_mbs >> u1_mbaff) - 1)
153                         << (4 + u1_mbaff);
154         ps_dec->s_tran_addrecon.u2_mv_top_left_inc = (u1_num_mbs << 2) - 1
155                         - (u1_mbaff << 2);
156 
157         /* reassign left MV and cur MV pointers */
158         ps_dec->ps_mv_left = ps_dec->ps_mv_cur
159                         + ps_dec->s_tran_addrecon.u2_mv_left_inc;
160 
161         ps_dec->ps_mv_cur += (u1_num_mbs << 4);
162         ps_dec->u4_num_mbs_prev_nmb = u1_num_mbs;
163 
164     }
165 }
166 
ih264d_decode_tfr_nmb(dec_struct_t * ps_dec,UWORD8 u1_num_mbs,UWORD8 u1_num_mbs_next,UWORD8 u1_end_of_row)167 void ih264d_decode_tfr_nmb(dec_struct_t * ps_dec,
168                            UWORD8 u1_num_mbs,
169                            UWORD8 u1_num_mbs_next,
170                            UWORD8 u1_end_of_row)
171 {
172 
173     UWORD32 u1_end_of_row_next;
174 
175     const UWORD32 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag;
176 
177     /****************************************************************/
178     /* Check for End Of Row in Next iteration                       */
179     /****************************************************************/
180     u1_end_of_row_next = u1_num_mbs_next &&
181                         ((u1_num_mbs_next) <= (ps_dec->u1_recon_mb_grp >> u1_mbaff));
182 
183     /****************************************************************/
184     /* Transfer the Following things                                */
185     /* N-Mb DeblkParams Data    ( To Ext DeblkParams Buffer )       */
186     /* N-Mb Recon Data          ( To Ext Frame Buffer )             */
187     /* N-Mb Intrapredline Data  ( Updated Internally)               */
188     /* N-Mb MV Data             ( To Ext MV Buffer )                */
189     /* N-Mb MVTop/TopRight Data ( To Int MV Top Scratch Buffers)    */
190     /****************************************************************/
191     if(u1_end_of_row)
192     {
193         ps_dec->i2_dec_thread_mb_y += (1 << u1_mbaff);
194     }
195     ih264d_transfer_mb_group_data(ps_dec, u1_num_mbs, u1_end_of_row,
196                                   u1_end_of_row_next);
197 
198 }
199 
ih264d_decode_recon_tfr_nmb_thread(dec_struct_t * ps_dec,UWORD8 u1_num_mbs,UWORD8 u1_num_mbs_next,UWORD8 u1_end_of_row)200 WORD32 ih264d_decode_recon_tfr_nmb_thread(dec_struct_t * ps_dec,
201                                           UWORD8 u1_num_mbs,
202                                           UWORD8 u1_num_mbs_next,
203                                           UWORD8 u1_end_of_row)
204 {
205     WORD32 i,j;
206     dec_mb_info_t * ps_cur_mb_info;
207     UWORD32 u4_update_mbaff = 0;
208     const UWORD32 u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag;
209     UWORD32 u1_slice_type, u1_B;
210     WORD32 u1_skip_th;
211     UWORD32 u1_ipcm_th;
212     UWORD32 u4_cond;
213     UWORD16 u2_slice_num,u2_cur_dec_mb_num;
214     WORD32 ret;
215     UWORD32 u4_mb_num;
216     WORD32 nop_cnt = 8*128;
217     u1_slice_type = ps_dec->ps_decode_cur_slice->slice_type;
218 
219     u1_B = (u1_slice_type == B_SLICE);
220 
221     u1_skip_th = ((u1_slice_type != I_SLICE) ?
222                                     (u1_B ? B_8x8 : PRED_8x8R0) : -1);
223 
224     u1_ipcm_th = ((u1_slice_type != I_SLICE) ? (u1_B ? 23 : 5) : 0);
225 
226     u2_cur_dec_mb_num = ps_dec->cur_dec_mb_num;
227 
228     while(1)
229     {
230 
231         UWORD32 u4_max_mb = (UWORD32)(ps_dec->i2_dec_thread_mb_y + (1 << u1_mbaff)) * ps_dec->u2_frm_wd_in_mbs - 1;
232         u4_mb_num = u2_cur_dec_mb_num;
233         /*introducing 1 MB delay*/
234         u4_mb_num = MIN(u4_mb_num + u1_num_mbs + 1, u4_max_mb);
235 
236         CHECK_MB_MAP_BYTE(u4_mb_num, ps_dec->pu1_dec_mb_map, u4_cond);
237         if(u4_cond)
238         {
239             break;
240         }
241         else
242         {
243             if(nop_cnt > 0)
244             {
245                 nop_cnt -= 128;
246                 NOP(128);
247             }
248             else
249             {
250                 if(ps_dec->u4_output_present && (2 == ps_dec->u4_num_cores) &&
251                    (ps_dec->u4_fmt_conv_cur_row < ps_dec->s_disp_frame_info.u4_y_ht))
252                 {
253                     ps_dec->u4_fmt_conv_num_rows =
254                                 MIN(FMT_CONV_NUM_ROWS,
255                                     (ps_dec->s_disp_frame_info.u4_y_ht
256                                                     - ps_dec->u4_fmt_conv_cur_row));
257                     ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op),
258                                           ps_dec->u4_fmt_conv_cur_row,
259                                           ps_dec->u4_fmt_conv_num_rows);
260                     ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows;
261                 }
262                 else
263                 {
264                     nop_cnt = 8*128;
265                     ithread_yield();
266                 }
267             }
268         }
269     }
270     /* N Mb MC Loop */
271     for(i = 0; i < u1_num_mbs; i++)
272     {
273         u4_mb_num = u2_cur_dec_mb_num;
274 
275         GET_SLICE_NUM_MAP(ps_dec->pu2_slice_num_map, u2_cur_dec_mb_num,
276                           u2_slice_num);
277 
278         if(u2_slice_num != ps_dec->u2_cur_slice_num_dec_thread)
279         {
280             ps_dec->u4_cur_slice_decode_done = 1;
281             break;
282         }
283 
284         ps_cur_mb_info = &ps_dec->ps_frm_mb_info[u2_cur_dec_mb_num];
285 
286         ps_dec->u4_dma_buf_idx = 0;
287         ps_dec->u4_pred_info_idx = 0;
288 
289         if(ps_cur_mb_info->u1_mb_type <= u1_skip_th)
290         {
291             WORD32 pred_cnt = 0;
292             pred_info_pkd_t *ps_pred_pkd;
293             UWORD32 u4_pred_info_pkd_idx;
294             WORD8 i1_pred;
295 
296             u4_pred_info_pkd_idx = ps_cur_mb_info->u4_pred_info_pkd_idx;
297 
298             while(pred_cnt < ps_cur_mb_info->u1_num_pred_parts)
299             {
300                 ps_pred_pkd = ps_dec->ps_pred_pkd + u4_pred_info_pkd_idx;
301 
302                 ps_dec->p_form_mb_part_info_thread(ps_pred_pkd,ps_dec,
303                                                    ps_cur_mb_info->u2_mbx,
304                                                    ps_cur_mb_info->u2_mby,
305                                                    (i >> u1_mbaff),
306                                                    ps_cur_mb_info);
307 
308                 u4_pred_info_pkd_idx++;
309                 pred_cnt++;
310             }
311             ps_dec->p_mc_dec_thread(ps_dec, ps_cur_mb_info);
312         }
313         else if(ps_cur_mb_info->u1_mb_type == MB_SKIP)
314         {
315             WORD32 pred_cnt = 0;
316             pred_info_pkd_t *ps_pred_pkd;
317             UWORD32 u4_pred_info_pkd_idx;
318             WORD8 i1_pred;
319 
320             u4_pred_info_pkd_idx = ps_cur_mb_info->u4_pred_info_pkd_idx;
321 
322             while(pred_cnt < ps_cur_mb_info->u1_num_pred_parts)
323             {
324                 ps_pred_pkd = ps_dec->ps_pred_pkd + u4_pred_info_pkd_idx;
325 
326                 ps_dec->p_form_mb_part_info_thread(ps_pred_pkd,ps_dec,
327                                                    ps_cur_mb_info->u2_mbx,
328                                                    ps_cur_mb_info->u2_mby,
329                                                    (i >> u1_mbaff),
330                                                    ps_cur_mb_info);
331 
332                 u4_pred_info_pkd_idx++;
333                 pred_cnt++;
334             }
335             /* Decode MB skip */
336             ps_dec->p_mc_dec_thread(ps_dec, ps_cur_mb_info);
337         }
338 
339         u2_cur_dec_mb_num++;
340     }
341 
342     /* N Mb IQ IT RECON  Loop */
343     for(j = 0; j < i; j++)
344     {
345         ps_cur_mb_info = &ps_dec->ps_frm_mb_info[ps_dec->cur_dec_mb_num];
346 
347         if((ps_dec->u4_num_cores == 2) || !ps_dec->i1_recon_in_thread3_flag)
348         {
349             if(ps_cur_mb_info->u1_mb_type <= u1_skip_th)
350             {
351                 ih264d_process_inter_mb(ps_dec, ps_cur_mb_info, j);
352             }
353             else if(ps_cur_mb_info->u1_mb_type != MB_SKIP)
354             {
355                 if((u1_ipcm_th + 25) != ps_cur_mb_info->u1_mb_type)
356                 {
357                     ps_cur_mb_info->u1_mb_type -= (u1_skip_th + 1);
358                     ih264d_process_intra_mb(ps_dec, ps_cur_mb_info, j);
359                 }
360             }
361 
362 
363          if(ps_dec->u4_use_intrapred_line_copy == 1)
364                 ih264d_copy_intra_pred_line(ps_dec, ps_cur_mb_info, j);
365         }
366 
367         DATA_SYNC();
368 
369         if(u1_mbaff)
370         {
371             if(u4_update_mbaff)
372             {
373                 UWORD32 u4_mb_num = ps_cur_mb_info->u2_mbx
374                                 + ps_dec->u2_frm_wd_in_mbs
375                                                 * (ps_cur_mb_info->u2_mby >> 1);
376                 UPDATE_MB_MAP_MBNUM_BYTE(ps_dec->pu1_recon_mb_map, u4_mb_num);
377                 u4_update_mbaff = 0;
378             }
379             else
380             {
381                 u4_update_mbaff = 1;
382             }
383         }
384         else
385         {
386             UWORD32 u4_mb_num = ps_cur_mb_info->u2_mbx
387                             + ps_dec->u2_frm_wd_in_mbs * ps_cur_mb_info->u2_mby;
388             UPDATE_MB_MAP_MBNUM_BYTE(ps_dec->pu1_recon_mb_map, u4_mb_num);
389         }
390         ps_dec->cur_dec_mb_num++;
391      }
392 
393     /*N MB deblocking*/
394     if(ps_dec->u4_nmb_deblk == 1)
395     {
396         UWORD32 u4_wd_y, u4_wd_uv;
397         tfr_ctxt_t *ps_tfr_cxt = &(ps_dec->s_tran_addrecon);
398         UWORD8 u1_field_pic_flag = ps_dec->ps_cur_slice->u1_field_pic_flag;
399         const WORD32 i4_cb_qp_idx_ofst =
400                        ps_dec->ps_cur_pps->i1_chroma_qp_index_offset;
401         const WORD32 i4_cr_qp_idx_ofst =
402                        ps_dec->ps_cur_pps->i1_second_chroma_qp_index_offset;
403 
404         u4_wd_y = ps_dec->u2_frm_wd_y << u1_field_pic_flag;
405         u4_wd_uv = ps_dec->u2_frm_wd_uv << u1_field_pic_flag;
406 
407         ps_cur_mb_info = &ps_dec->ps_frm_mb_info[ps_dec->u4_cur_deblk_mb_num];
408 
409         ps_dec->u4_deblk_mb_x = ps_cur_mb_info->u2_mbx;
410         ps_dec->u4_deblk_mb_y = ps_cur_mb_info->u2_mby;
411 
412 
413         for(j = 0; j < i; j++)
414         {
415             ih264d_deblock_mb_nonmbaff(ps_dec, ps_tfr_cxt,
416                                        i4_cb_qp_idx_ofst, i4_cr_qp_idx_ofst,
417                                         u4_wd_y, u4_wd_uv);
418 
419         }
420     }
421 
422     /*handle the last mb in picture case*/
423     if(ps_dec->cur_dec_mb_num > ps_dec->ps_cur_sps->u2_max_mb_addr)
424         ps_dec->u4_cur_slice_decode_done = 1;
425 
426     if(i != u1_num_mbs)
427     {
428         u1_end_of_row = 0;
429         /*Number of MB's left in row*/
430         u1_num_mbs_next = u1_num_mbs_next + ((u1_num_mbs - i) >> u1_mbaff);
431     }
432 
433     ih264d_decode_tfr_nmb(ps_dec, (i), u1_num_mbs_next, u1_end_of_row);
434 
435     return OK;
436 }
437 
ih264d_decode_slice_thread(dec_struct_t * ps_dec)438 WORD32 ih264d_decode_slice_thread(dec_struct_t *ps_dec)
439 {
440     UWORD8 u1_num_mbs_next, u1_num_mbsleft, u1_end_of_row = 0;
441     const UWORD32 i2_pic_wdin_mbs = ps_dec->u2_frm_wd_in_mbs;
442     UWORD8 u1_mbaff, u1_num_mbs;
443 
444     UWORD16 u2_first_mb_in_slice;
445     UWORD16 i16_mb_x, i16_mb_y;
446     UWORD8 u1_field_pic;
447     UWORD32 u4_frame_stride, x_offset, y_offset;
448     WORD32 ret;
449 
450     tfr_ctxt_t *ps_trns_addr;
451 
452     /*check for mb map of first mb in slice to ensure slice header is parsed*/
453     while(1)
454     {
455         UWORD32 u4_mb_num = ps_dec->cur_dec_mb_num;
456         UWORD32 u4_cond = 0;
457         WORD32 nop_cnt = 8 * 128;
458         CHECK_MB_MAP_BYTE(u4_mb_num, ps_dec->pu1_dec_mb_map, u4_cond);
459         if(u4_cond)
460         {
461             break;
462         }
463         else
464         {
465             if(nop_cnt > 0)
466             {
467                 nop_cnt -= 128;
468                 NOP(128);
469             }
470             else if(ps_dec->u4_output_present && (2 == ps_dec->u4_num_cores) &&
471                (ps_dec->u4_fmt_conv_cur_row < ps_dec->s_disp_frame_info.u4_y_ht))
472             {
473                 ps_dec->u4_fmt_conv_num_rows =
474                                 MIN(FMT_CONV_NUM_ROWS,
475                                     (ps_dec->s_disp_frame_info.u4_y_ht
476                                                     - ps_dec->u4_fmt_conv_cur_row));
477                 ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op),
478                                       ps_dec->u4_fmt_conv_cur_row,
479                                       ps_dec->u4_fmt_conv_num_rows);
480                 ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows;
481             }
482             else
483             {
484                 nop_cnt = 8*128;
485                 ithread_yield();
486             }
487             DEBUG_THREADS_PRINTF("waiting for mb mapcur_dec_mb_num = %d,ps_dec->u2_cur_mb_addr  = %d\n",u2_cur_dec_mb_num,
488                             ps_dec->u2_cur_mb_addr);
489 
490         }
491     }
492 
493 
494 
495     u1_mbaff = ps_dec->ps_cur_slice->u1_mbaff_frame_flag;
496 
497     u2_first_mb_in_slice = ps_dec->ps_decode_cur_slice->u4_first_mb_in_slice;
498 
499     i16_mb_x = MOD(u2_first_mb_in_slice, i2_pic_wdin_mbs);
500     i16_mb_y = DIV(u2_first_mb_in_slice, i2_pic_wdin_mbs);
501     i16_mb_y <<= u1_mbaff;
502     ps_dec->i2_dec_thread_mb_y = i16_mb_y;
503 
504 
505     ps_dec->cur_dec_mb_num = u2_first_mb_in_slice << u1_mbaff;
506 
507     if((ps_dec->u4_num_cores == 2) || !ps_dec->i1_recon_in_thread3_flag)
508     {
509         ps_dec->pv_proc_tu_coeff_data =
510                 (void *) ps_dec->ps_decode_cur_slice->pv_tu_coeff_data_start;
511     }
512 
513     // recalculate recon pointers
514     u1_field_pic = ps_dec->ps_cur_slice->u1_field_pic_flag;
515     u4_frame_stride = ps_dec->u2_frm_wd_y << u1_field_pic;
516     x_offset = i16_mb_x << 4;
517     y_offset = (i16_mb_y * u4_frame_stride) << 4;
518 
519     ps_trns_addr = &(ps_dec->s_tran_addrecon);
520 
521     ps_trns_addr->pu1_dest_y = ps_dec->s_cur_pic.pu1_buf1 + x_offset + y_offset;
522 
523     u4_frame_stride = ps_dec->u2_frm_wd_uv << u1_field_pic;
524     x_offset >>= 1;
525     y_offset = (i16_mb_y * u4_frame_stride) << 3;
526 
527     x_offset *= YUV420SP_FACTOR;
528 
529     ps_trns_addr->pu1_dest_u = ps_dec->s_cur_pic.pu1_buf2 + x_offset + y_offset;
530     ps_trns_addr->pu1_dest_v = ps_dec->s_cur_pic.pu1_buf3 + x_offset + y_offset;
531 
532     ps_trns_addr->pu1_mb_y = ps_trns_addr->pu1_dest_y;
533     ps_trns_addr->pu1_mb_u = ps_trns_addr->pu1_dest_u;
534     ps_trns_addr->pu1_mb_v = ps_trns_addr->pu1_dest_v;
535 
536 
537     /* Initialise MC and formMbPartInfo fn ptrs one time based on profile_idc */
538     {
539         ps_dec->p_mc_dec_thread = ih264d_motion_compensate_bp;
540         ps_dec->p_form_mb_part_info_thread = ih264d_form_mb_part_info_bp;
541     }
542     {
543         UWORD8 uc_nofield_nombaff;
544         uc_nofield_nombaff = ((ps_dec->ps_cur_slice->u1_field_pic_flag == 0)
545                         && (ps_dec->ps_cur_slice->u1_mbaff_frame_flag == 0)
546                         && (ps_dec->ps_decode_cur_slice->slice_type != B_SLICE)
547                         && (ps_dec->ps_cur_pps->u1_wted_pred_flag == 0));
548 
549         if(uc_nofield_nombaff == 0)
550         {
551             ps_dec->p_mc_dec_thread = ih264d_motion_compensate_mp;
552             ps_dec->p_form_mb_part_info_thread = ih264d_form_mb_part_info_mp;
553         }
554 
555     }
556 
557     ps_dec->u4_cur_slice_decode_done = 0;
558 
559 
560     while(ps_dec->u4_cur_slice_decode_done != 1)
561     {
562 
563         u1_num_mbsleft = ((i2_pic_wdin_mbs - i16_mb_x) << u1_mbaff);
564 
565         if(u1_num_mbsleft <= ps_dec->u1_recon_mb_grp)
566         {
567             u1_num_mbs = u1_num_mbsleft;
568 
569             /*Indicate number of mb's left in a row*/
570             u1_num_mbs_next = 0;
571             u1_end_of_row = 1;
572             i16_mb_x = 0;
573         }
574         else
575         {
576             u1_num_mbs = ps_dec->u1_recon_mb_grp;
577 
578             /*Indicate number of mb's left in a row*/
579             u1_num_mbs_next = i2_pic_wdin_mbs - i16_mb_x
580                             - (ps_dec->u1_recon_mb_grp >> u1_mbaff);
581             i16_mb_x += (u1_num_mbs >> u1_mbaff);
582             u1_end_of_row = 0;
583 
584         }
585         ret = ih264d_decode_recon_tfr_nmb_thread(ps_dec, u1_num_mbs, u1_num_mbs_next,
586                                            u1_end_of_row);
587         if(ret != OK)
588             return ret;
589     }
590     return OK;
591 }
592 
ih264d_decode_picture_thread(dec_struct_t * ps_dec)593 void ih264d_decode_picture_thread(dec_struct_t *ps_dec )
594 {
595     ithread_set_name("ih264d_decode_picture_thread");
596     while(1)
597     {
598         /*Complete all writes before processing next slice*/
599 
600         DEBUG_THREADS_PRINTF(" Entering decode slice\n");
601 
602         ih264d_decode_slice_thread(ps_dec);
603         DEBUG_THREADS_PRINTF(" Exit  ih264d_decode_slice_thread \n");
604 
605 
606         if(ps_dec->cur_dec_mb_num
607                         > ps_dec->ps_cur_sps->u2_max_mb_addr)
608         {
609             /*Last slice in frame*/
610             break;
611         }
612         else
613         {
614             ps_dec->ps_decode_cur_slice++;
615             ps_dec->u2_cur_slice_num_dec_thread++;
616         }
617 
618     }
619     if(ps_dec->u4_output_present && (2 == ps_dec->u4_num_cores) &&
620        (ps_dec->u4_fmt_conv_cur_row < ps_dec->s_disp_frame_info.u4_y_ht))
621     {
622         ps_dec->u4_fmt_conv_num_rows =
623                         (ps_dec->s_disp_frame_info.u4_y_ht
624                                         - ps_dec->u4_fmt_conv_cur_row);
625         ih264d_format_convert(ps_dec, &(ps_dec->s_disp_op),
626                               ps_dec->u4_fmt_conv_cur_row,
627                               ps_dec->u4_fmt_conv_num_rows);
628         ps_dec->u4_fmt_conv_cur_row += ps_dec->u4_fmt_conv_num_rows;
629     }
630 }
631 
ih264d_signal_decode_thread(dec_struct_t * ps_dec)632 void ih264d_signal_decode_thread(dec_struct_t *ps_dec)
633 {
634     if(ps_dec->u4_dec_thread_created == 1)
635     {
636         ithread_join(ps_dec->pv_dec_thread_handle, NULL);
637         ps_dec->u4_dec_thread_created = 0;
638     }
639 }
ih264d_signal_bs_deblk_thread(dec_struct_t * ps_dec)640 void ih264d_signal_bs_deblk_thread(dec_struct_t *ps_dec)
641 {
642     if(ps_dec->u4_bs_deblk_thread_created)
643     {
644         ithread_join(ps_dec->pv_bs_deblk_thread_handle, NULL);
645         ps_dec->u4_bs_deblk_thread_created = 0;
646     }
647 
648 }
649