xref: /aosp_15_r20/external/libavc/decoder/svc/isvcd_ii_pred.c (revision 495ae853bb871d1e5a258cb02c2cc13cde8ddb9a)
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_ii_pred.c
24  *
25  * @brief
26  *  Contains routines that resample for SVC resampling
27  *
28  * @author
29  *  Kishore
30  *
31  * @par List of Functions:
32  *  - isvcd_ii_pred_res_init()
33  *  - isvcd_ii_get_ref_mb_mode()
34  *  - isvcd_ii_get_ref_projections()
35  *  - isvcd_ii_pred_compute_flags_mb()
36  *  - isvcd_ii_pred_mb()
37  *
38  * @remarks
39  *  None
40  *
41  *******************************************************************************
42  */
43 
44 #include <assert.h>
45 #include <string.h>
46 #include "ih264_typedefs.h"
47 #include "ih264_macros.h"
48 #include "ih264_platform_macros.h"
49 #include "ih264_defs.h"
50 #include "ih264d_bitstrm.h"
51 #include "ih264d_defs.h"
52 #include "ih264d_debug.h"
53 #include "isvcd_structs.h"
54 #include "ih264d_parse_cavlc.h"
55 #include "ih264d_mb_utils.h"
56 #include "ih264d_deblocking.h"
57 #include "ih264d_dpb_manager.h"
58 #include "ih264d_mvpred.h"
59 #include "ih264d_inter_pred.h"
60 #include "ih264d_process_pslice.h"
61 #include "ih264d_error_handler.h"
62 #include "ih264d_cabac.h"
63 #include "ih264d_tables.h"
64 #include "ih264d_parse_slice.h"
65 #include "ih264d_utils.h"
66 #include "ih264d_parse_islice.h"
67 #include "ih264d_process_bslice.h"
68 #include "ih264d_process_intra_mb.h"
69 #include "isvcd_mode_mv_resamp.h"
70 #include "isvcd_ii_pred.h"
71 #include "ih264_debug.h"
72 
73 /*****************************************************************************/
74 /*                                                                           */
75 /*  Function Name : isvcd_ii_pred_res_init                                    */
76 /*                                                                           */
77 /*  Description   : this function initialises the resolution level params    */
78 /*                  into the context structure                               */
79 /*                                                                           */
80 /*  Inputs        : pv_ii_pred_ctxt: Intra inter pred  handle                */
81 /*                  pi2_ref_loc_x             : pointer to buffer having the */
82 /*                                              projected locations horz     */
83 /*                  pi2_ref_loc_y             : pointer to buffer having the */
84 /*                                              projected location vertical  */
85 /*  Globals       : none                                                     */
86 /*  Processing    :                                                          */
87 /*                                                                           */
88 /*  Outputs       : none                                                     */
89 /*  Returns       : none                                                     */
90 /*                                                                           */
91 /*  Issues        : none                                                     */
92 /*                                                                           */
93 /*  Revision History:                                                        */
94 /*                                                                           */
95 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
96 /*         06 09 2021   Vijay                creation                        */
97 /*                                                                           */
98 /*****************************************************************************/
isvcd_ii_pred_res_init(void * pv_svc_dec)99 WORD32 isvcd_ii_pred_res_init(void *pv_svc_dec)
100 {
101     /* local vaiables */
102     intra_inter_pred_ctxt_t *ps_ii_pred_ctxt;
103     mode_motion_ctxt_t *ps_ctxt;
104     mode_motion_lyr_ctxt *ps_lyr_mem;
105     WORD32 i4_base_res_flag;
106     svc_dec_lyr_struct_t *ps_svc_lyr_dec = (svc_dec_lyr_struct_t *) pv_svc_dec;
107 
108     res_prms_t *ps_res_prms = &ps_svc_lyr_dec->s_res_prms;
109     ps_ii_pred_ctxt = (intra_inter_pred_ctxt_t *) ps_svc_lyr_dec->pv_ii_pred_ctxt;
110     ps_ctxt = (mode_motion_ctxt_t *) ps_svc_lyr_dec->pv_mode_mv_sample_ctxt;
111     i4_base_res_flag = ps_svc_lyr_dec->u1_base_res_flag;
112 
113     if((0 != ps_svc_lyr_dec->u1_layer_id) && (SVCD_FALSE == i4_base_res_flag))
114     {
115         /* if not first resolution layer */
116         ps_ii_pred_ctxt->i4_ref_res_lyr_wd = ps_ii_pred_ctxt->i4_cur_res_lyr_wd;
117         ps_ii_pred_ctxt->i4_ref_res_lyr_ht = ps_ii_pred_ctxt->i4_cur_res_lyr_ht;
118     }
119 
120     if ((ps_ctxt->i4_res_id >= 0) && (ps_ctxt->i4_res_id <= 2))
121     {
122         ps_lyr_mem = &ps_ctxt->as_res_lyr_mem[ps_ctxt->i4_res_id];
123 
124         ps_ii_pred_ctxt->pi2_ref_loc_x = ps_lyr_mem->pi2_ref_loc_x;
125         ps_ii_pred_ctxt->pi2_ref_loc_y = ps_lyr_mem->pi2_ref_loc_y;
126     }
127     /* Store the dimensions */
128     ps_ii_pred_ctxt->i4_cur_res_lyr_wd = ps_res_prms->i4_res_width;
129     ps_ii_pred_ctxt->i4_cur_res_lyr_ht = ps_res_prms->i4_res_height;
130 
131     return (OK);
132 }
133 
134 /*****************************************************************************/
135 /*                                                                           */
136 /*  Function Name : isvcd_ii_get_ref_mb_mode                                  */
137 /*                                                                           */
138 /*  Description   : This function is used to find the mb type of the         */
139 /*                  corresponding MB in the reference layer is INTER or      */
140 /*                  INTRA                                                    */
141 /*  Inputs        : pu1_ref_mb_modes : ref mb modes buffer pointer           */
142 /*                  i4_ref_mode_stride : mb mode buffer stride               */
143 /*                  i4_x_ref : reference location X                          */
144 /*                  i4_y_ref : reference location Y                          */
145 /*  Globals       : none                                                     */
146 /*  Processing    : it derives the byte corresponding to reference MB and    */
147 /*                  and gets the mb type                                     */
148 /*  Outputs       : none                                                     */
149 /*  Returns       : SVCD_TRUE if INTRA MB else SVCD_FALSE                    */
150 /*                                                                           */
151 /*  Issues        : none                                                     */
152 /*                                                                           */
153 /*  Revision History:                                                        */
154 /*                                                                           */
155 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
156 /*         06 09 2021   Vijay                creation                        */
157 /*                                                                           */
158 /*****************************************************************************/
isvcd_ii_get_ref_mb_mode(WORD8 * pi1_ref_mb_modes,WORD32 i4_ref_mode_stride,WORD32 i4_ref_mode_size,WORD32 i4_x_ref,WORD32 i4_y_ref)159 WORD32 isvcd_ii_get_ref_mb_mode(WORD8 *pi1_ref_mb_modes, WORD32 i4_ref_mode_stride,
160                                 WORD32 i4_ref_mode_size, WORD32 i4_x_ref, WORD32 i4_y_ref)
161 {
162     WORD32 i4_mb_x, i4_mb_y;
163     inter_lyr_mb_prms_t *ps_inter_lyr_mb_prms;
164     WORD8 i1_mb_mode;
165 
166     i4_mb_x = (i4_x_ref >> MB_WIDTH_SHIFT);
167     i4_mb_y = (i4_y_ref >> MB_HEIGHT_SHIFT);
168 
169     /* get the location of the byte which has the current mb mode */
170     pi1_ref_mb_modes += (i4_mb_y * i4_ref_mode_stride * i4_ref_mode_size);
171     pi1_ref_mb_modes += (i4_mb_x * i4_ref_mode_size);
172     ps_inter_lyr_mb_prms = (inter_lyr_mb_prms_t *) pi1_ref_mb_modes;
173     i1_mb_mode = ps_inter_lyr_mb_prms->i1_mb_mode;
174 
175     if(i1_mb_mode <= SVC_INTER_MB)
176     {
177         /* INTER */
178         return (SVCD_FALSE);
179     }
180     else
181     {
182         /* INTRA */
183         return (SVCD_TRUE);
184     }
185 }
186 /*****************************************************************************/
187 /*                                                                           */
188 /*  Function Name : isvcd_ii_get_ref_projections                              */
189 /*                                                                           */
190 /*  Description   : this function projects the corners of current MB and     */
191 /*                  finds out if any point is falling into an INTRA MB in    */
192 /*                  reference layer. it also calculates the intersection     */
193 /*                  point of MB boundaries in the projected region           */
194 /*  Inputs        : ps_ctxt : Intra Inter context pointer                    */
195 /*                  ps_ii_mb_ctxt : Curretn MB context pointer               */
196 /*                  ps_ref_mb_mode : reference MB mode buffer descriptor     */
197 /*                  i4_mb_x : MB_X of current MB                             */
198 /*                  i4_mb_y : MB_Y of current MB                             */
199 /*  Globals       : none                                                     */
200 /*  Processing    : it derives the intra status of the corners and calculates*/
201 /*                  the intersection point                                   */
202 /*  Outputs       : non                                                      */
203 /*  Returns       : SVCD_TRUE or SVCD_FALSE                                  */
204 /*                                                                           */
205 /*  Issues        : none                                                     */
206 /*                                                                           */
207 /*  Revision History:                                                        */
208 /*                                                                           */
209 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
210 /*         06 09 2021   Vijay                creation                        */
211 /*                                                                           */
212 /*****************************************************************************/
isvcd_ii_get_ref_projections(intra_inter_pred_ctxt_t * ps_ctxt,intra_inter_mb_t * ps_ii_mb_ctxt,mem_element_t * ps_ref_mb_mode,WORD32 i4_mb_x,WORD32 i4_mb_y)213 WORD32 isvcd_ii_get_ref_projections(intra_inter_pred_ctxt_t *ps_ctxt,
214                                     intra_inter_mb_t *ps_ii_mb_ctxt, mem_element_t *ps_ref_mb_mode,
215                                     WORD32 i4_mb_x, WORD32 i4_mb_y)
216 {
217     WORD16 *pi2_ref_loc_x;
218     WORD16 *pi2_ref_loc_y;
219     WORD8 *pi1_ref_mb_mode;
220     WORD32 i4_ref_mode_stride;
221     WORD32 i4_element_size;
222     WORD32 i4_ref_x, i4_ref_y;
223     WORD32 i4_frame_x, i4_frame_y;
224     WORD32 i4_flag;
225 
226     pi2_ref_loc_x = ps_ctxt->pi2_ref_loc_x;
227     pi2_ref_loc_y = ps_ctxt->pi2_ref_loc_y;
228 
229     pi1_ref_mb_mode = (WORD8 *) ps_ref_mb_mode->pv_buffer;
230     i4_ref_mode_stride = ps_ref_mb_mode->i4_num_element_stride;
231     i4_element_size = ps_ref_mb_mode->i4_element_size;
232 
233     /* get the current MB frame positions */
234     i4_frame_x = i4_mb_x << 4;
235     i4_frame_y = i4_mb_y << 4;
236 
237     /* reset the flag */
238     i4_flag = SVCD_FALSE;
239 
240     /* project the (0,0) of current MB and get the ref MB mode */
241     i4_ref_x = pi2_ref_loc_x[i4_frame_x];
242     i4_ref_y = pi2_ref_loc_y[i4_frame_y];
243 
244     if((i4_ref_x < ps_ctxt->i4_ref_res_lyr_wd) && (i4_ref_y < ps_ctxt->i4_ref_res_lyr_ht))
245     {
246         ps_ii_mb_ctxt->u1_top_left_intra_flag = isvcd_ii_get_ref_mb_mode(
247             pi1_ref_mb_mode, i4_ref_mode_stride, i4_element_size, i4_ref_x, i4_ref_y);
248     }
249     else
250     {
251         /* If projection is outside the picture boundary */
252         ps_ii_mb_ctxt->u1_top_left_intra_flag = SVCD_FALSE;
253     }
254     /* project the (15,0) of current MB and get the ref MB mode */
255     i4_ref_x = pi2_ref_loc_x[i4_frame_x + 15];
256     i4_ref_y = pi2_ref_loc_y[i4_frame_y];
257 
258     if((i4_ref_x < ps_ctxt->i4_ref_res_lyr_wd) && (i4_ref_y < ps_ctxt->i4_ref_res_lyr_ht))
259     {
260         ps_ii_mb_ctxt->u1_top_rt_intra_flag = isvcd_ii_get_ref_mb_mode(
261             pi1_ref_mb_mode, i4_ref_mode_stride, i4_element_size, i4_ref_x, i4_ref_y);
262     }
263     else
264     {
265         ps_ii_mb_ctxt->u1_top_rt_intra_flag = SVCD_FALSE;
266     }
267 
268     /* project the (0,15) of current MB and get the ref MB mode */
269     i4_ref_x = pi2_ref_loc_x[i4_frame_x];
270     i4_ref_y = pi2_ref_loc_y[i4_frame_y + 15];
271 
272     if((i4_ref_x < ps_ctxt->i4_ref_res_lyr_wd) && (i4_ref_y < ps_ctxt->i4_ref_res_lyr_ht))
273     {
274         ps_ii_mb_ctxt->u1_bot_left_intra_flag = isvcd_ii_get_ref_mb_mode(
275             pi1_ref_mb_mode, i4_ref_mode_stride, i4_element_size, i4_ref_x, i4_ref_y);
276     }
277     else
278     {
279         ps_ii_mb_ctxt->u1_bot_left_intra_flag = SVCD_FALSE;
280     }
281 
282     /* project the (15,15) of current MB and get the ref MB mode */
283     i4_ref_x = pi2_ref_loc_x[i4_frame_x + 15];
284     i4_ref_y = pi2_ref_loc_y[i4_frame_y + 15];
285 
286     if((i4_ref_x < ps_ctxt->i4_ref_res_lyr_wd) && (i4_ref_y < ps_ctxt->i4_ref_res_lyr_ht))
287     {
288         ps_ii_mb_ctxt->u1_bot_rt_intra_flag = isvcd_ii_get_ref_mb_mode(
289             pi1_ref_mb_mode, i4_ref_mode_stride, i4_element_size, i4_ref_x, i4_ref_y);
290     }
291     else
292     {
293         ps_ii_mb_ctxt->u1_bot_rt_intra_flag = SVCD_FALSE;
294     }
295 
296     /* if any of the 4 cormers are falling into intra region
297       set the INTRA INTER Flag */
298     if((SVCD_TRUE == ps_ii_mb_ctxt->u1_top_left_intra_flag) ||
299        (SVCD_TRUE == ps_ii_mb_ctxt->u1_top_rt_intra_flag) ||
300        (SVCD_TRUE == ps_ii_mb_ctxt->u1_bot_left_intra_flag) ||
301        (SVCD_TRUE == ps_ii_mb_ctxt->u1_bot_rt_intra_flag))
302     {
303         i4_flag = SVCD_TRUE;
304     }
305 
306     /* derive the intersection point of MB boundaries */
307     if(SVCD_TRUE == i4_flag)
308     {
309         WORD32 i4_intr_x, i4_intr_y;
310         WORD32 i4_ref_mb_init_x, i4_ref_mb_init_y;
311         WORD32 i4_ctr;
312 
313         /* set the variables to initial values */
314         i4_intr_x = 0;
315         i4_intr_y = 0;
316         i4_ref_mb_init_x = pi2_ref_loc_x[i4_frame_x] >> MB_WIDTH_SHIFT;
317         i4_ref_mb_init_y = pi2_ref_loc_y[i4_frame_y] >> MB_HEIGHT_SHIFT;
318 
319         /* loop until an Mb boundary is found in horizontal direction */
320         for(i4_ctr = 0; i4_ctr < MB_WIDTH; i4_ctr++)
321         {
322             i4_ref_x = pi2_ref_loc_x[i4_frame_x + i4_ctr];
323             i4_ref_x >>= MB_WIDTH_SHIFT;
324 
325             /* check if the locations are falling into same MB */
326             if(i4_ref_x != i4_ref_mb_init_x)
327             {
328                 break;
329             }
330             /* increment the position */
331             i4_intr_x++;
332         }
333 
334         /* loop until an Mb boundary is found in vertical direction */
335         for(i4_ctr = 0; i4_ctr < MB_HEIGHT; i4_ctr++)
336         {
337             i4_ref_y = pi2_ref_loc_y[i4_frame_y + i4_ctr];
338             i4_ref_y >>= MB_HEIGHT_SHIFT;
339 
340             /* check if the locations are falling into same MB */
341             if(i4_ref_y != i4_ref_mb_init_y)
342             {
343                 break;
344             }
345             /* increment the position */
346             i4_intr_y++;
347         }
348         /* store the intersection points */
349         ps_ii_mb_ctxt->u1_intersection_x = i4_intr_x;
350         ps_ii_mb_ctxt->u1_intersection_y = i4_intr_y;
351     }
352     else
353     {
354         /* set to default value */
355         ps_ii_mb_ctxt->u1_intersection_x = 0;
356         ps_ii_mb_ctxt->u1_intersection_y = 0;
357     }
358 
359     return (i4_flag);
360 }
361 /*****************************************************************************/
362 /*                                                                           */
363 /*  Function Name : isvcd_ii_pred_compute_flags_mb                            */
364 /*                                                                           */
365 /*  Description   : this function checks all the criteria for an MB to       */
366 /*                  under go Inter-Intra prediction  and stores the MB mode  */
367 /*                   as INTER_INTRA for appropriate MBs                      */
368 /*  Inputs        : refer to comments below                                  */
369 /*  Globals       : none                                                     */
370 /*  Processing    : it checks the criteria for anMB to undergo Inter-Intra   */
371 /*                  pred process and updates the MB mode                     */
372 /*  Outputs       : MB mode set for each MB with INTRA-INTER status          */
373 /*  Returns       : SVCD_EOK or SVCD_EFAIL                                   */
374 /*                                                                           */
375 /*  Issues        : none                                                     */
376 /*                                                                           */
377 /*  Revision History:                                                        */
378 /*                                                                           */
379 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
380 /*         06 09 2021   Vijay                creation                        */
381 /*                                                                           */
382 /*****************************************************************************/
isvcd_ii_pred_compute_flags_mb(void * pv_ii_pred_ctxt,mem_element_t * ps_ref_mb_mode,mb_coord_t * ps_coord,void * pv_mb_prms,void * pv_svc_mb_prms,UWORD8 * pu1_ii_mb_mode)383 WORD32 isvcd_ii_pred_compute_flags_mb(void *pv_ii_pred_ctxt, mem_element_t *ps_ref_mb_mode,
384                                       mb_coord_t *ps_coord, void *pv_mb_prms, void *pv_svc_mb_prms,
385                                       UWORD8 *pu1_ii_mb_mode)
386 {
387     intra_inter_pred_ctxt_t *ps_ctxt;
388     WORD32 i4_mb_x, i4_mb_y;
389     dec_svc_mb_info_t *ps_svc_mb_prms;
390     UNUSED(pv_mb_prms);
391 
392     if((NULL == pv_ii_pred_ctxt) || (NULL == ps_ref_mb_mode) || (NULL == ps_coord) ||
393        (NULL == pu1_ii_mb_mode))
394     {
395         return NOT_OK;
396     }
397 
398     ps_ctxt = (intra_inter_pred_ctxt_t *) pv_ii_pred_ctxt;
399     ps_svc_mb_prms = (dec_svc_mb_info_t *) pv_svc_mb_prms;
400 
401     /* get mb co-ordinates */
402     i4_mb_x = ps_coord->u2_mb_x;
403     i4_mb_y = ps_coord->u2_mb_y;
404 
405     {
406         intra_inter_mb_t *ps_ii_mb_ctxt;
407         WORD32 i4_ii_flag;
408 
409         /* get the current MB strcuture pointer */
410         ps_ii_mb_ctxt = &ps_ctxt->s_intra_inter_mb_prms;
411 
412         /* reset the Intra Inter qualified flag for current MB */
413         i4_ii_flag = SVCD_FALSE;
414 
415         /* check for base mode flag and Inter MB status */
416         if(1 == ps_svc_mb_prms->u1_base_mode_flag)
417         {
418             /* call the function which calculates the projections
419                and returns whether current MB has to under go
420                Inter Intra Prediction */
421             i4_ii_flag = isvcd_ii_get_ref_projections(ps_ctxt, ps_ii_mb_ctxt, ps_ref_mb_mode,
422                                                       i4_mb_x, i4_mb_y);
423         }
424 
425         /* If the current MB requires Intra Inter prediction */
426         if(SVCD_TRUE == i4_ii_flag)
427         {
428             /* set the mb mode */
429             *pu1_ii_mb_mode = SVC_INTRA_INTER_MB;
430         }
431         else
432         {
433             /* set all MB params to default values */
434             ps_ii_mb_ctxt->u1_bot_left_intra_flag = SVCD_FALSE;
435             ps_ii_mb_ctxt->u1_bot_rt_intra_flag = SVCD_FALSE;
436             ps_ii_mb_ctxt->u1_top_left_intra_flag = SVCD_FALSE;
437             ps_ii_mb_ctxt->u1_top_rt_intra_flag = SVCD_FALSE;
438             ps_ii_mb_ctxt->u1_intersection_x = 0;
439             ps_ii_mb_ctxt->u1_intersection_y = 0;
440 
441             /* set the mb mode to 0 (which has no interpretation) */
442             *pu1_ii_mb_mode = 0;
443         }
444     }
445     return (OK);
446 }
447 
448 /*****************************************************************************/
449 /*                                                                           */
450 /*  Function Name : isvcd_ii_pred_mb                                          */
451 /*                                                                           */
452 /*  Description   : This function performs the Intra-Inter Preduction of the */
453 /*                  given MB                                                 */
454 /*                                                                           */
455 /*  Inputs        : ps_mb_ctxt : Intra Inter mb context strcuture            */
456 /*                  ps_mb_buf : current MB buffers strcuture pointer         */
457 /*  Globals       : none                                                     */
458 /*  Processing    : it processes all partitions based on the Intra flag      */
459 /*                                                                           */
460 /*  Outputs       : Intra Inter Predecited and reconstructed MB              */
461 /*  Returns       : none                                                     */
462 /*                                                                           */
463 /*  Issues        : none                                                     */
464 /*                                                                           */
465 /*  Revision History:                                                        */
466 /*                                                                           */
467 /*         DD MM YYYY   Author(s)       Changes (Describe the changes made)  */
468 /*         06 09 2021   Vijay                creation                        */
469 /*                                                                           */
470 /*****************************************************************************/
isvcd_ii_pred_mb(void * pv_svc_dec,dec_mb_info_t * ps_cur_mb_info)471 void isvcd_ii_pred_mb(void *pv_svc_dec, dec_mb_info_t *ps_cur_mb_info)
472 {
473     intra_inter_mb_t *ps_mb_ctxt;
474     UWORD8 *pu1_rec_y, *pu1_rec_uv;
475     UWORD8 *pu1_recon_luma;
476     WORD32 i4_recon_luma_stride;
477     UWORD8 *pu1_recon_chroma;
478     WORD32 i4_recon_chroma_stride;
479     UWORD8 *pu1_pred_luma;
480     UWORD8 *pu1_pred_chroma;
481     WORD32 i4_pred_luma_stride;
482     WORD32 i4_pred_chroma_stride;
483     WORD32 i4_intr_x, i4_intr_y;
484     intra_inter_pred_ctxt_t *ps_ctxt;
485     pic_buffer_t *ps_frame_buf;
486     svc_dec_lyr_struct_t *ps_svc_lyr_dec = (svc_dec_lyr_struct_t *) pv_svc_dec;
487     dec_struct_t *ps_dec = &ps_svc_lyr_dec->s_dec;
488 
489     ps_ctxt = (intra_inter_pred_ctxt_t *) ps_svc_lyr_dec->pv_ii_pred_ctxt;
490     ps_mb_ctxt = &ps_ctxt->s_intra_inter_mb_prms;
491     ps_frame_buf = ps_dec->ps_cur_pic;
492     i4_recon_luma_stride = ps_dec->u2_frm_wd_y;
493     i4_recon_chroma_stride = ps_dec->u2_frm_wd_uv;
494 
495     /* derive the intersection point */
496     i4_intr_x = ps_mb_ctxt->u1_intersection_x;
497     i4_intr_y = ps_mb_ctxt->u1_intersection_y;
498 
499     pu1_rec_y = ps_frame_buf->pu1_buf1 + (ps_cur_mb_info->u2_mbx << 4) +
500                 (i4_recon_luma_stride * (ps_cur_mb_info->u2_mby << 4));
501 
502     pu1_rec_uv = ps_frame_buf->pu1_buf2 + (ps_cur_mb_info->u2_mbx << 3) * YUV420SP_FACTOR +
503                  (i4_recon_chroma_stride * (ps_cur_mb_info->u2_mby << 3));
504 
505     pu1_pred_luma = ps_svc_lyr_dec->pu1_ii_resamp_buffer_luma;
506     pu1_pred_chroma = ps_svc_lyr_dec->pu1_ii_resamp_buffer_chroma;
507     i4_pred_luma_stride = MB_SIZE;
508     i4_pred_chroma_stride = MB_SIZE;
509 
510     /* get the recon and residual buffer pointer */
511     pu1_recon_luma = pu1_rec_y;
512     pu1_recon_chroma = pu1_rec_uv;
513 
514     /*-----------------------------------------------------------------------*/
515     /* Reconstruct TOP_LEFT Partition                                        */
516     /*-----------------------------------------------------------------------*/
517     {
518         WORD32 i4_width, i4_height;
519 
520         /* assign the appropriate buffer params based on Intra status */
521         if(SVCD_TRUE == ps_mb_ctxt->u1_top_left_intra_flag)
522         {
523             /* Luma Processing */
524             isvcd_copy_data(pu1_pred_luma, i4_pred_luma_stride, pu1_recon_luma,
525                             i4_recon_luma_stride, i4_intr_x, i4_intr_y);
526 
527             /* assign appropriate width and height for chroma */
528             i4_width = (((i4_intr_x + 1) >> 1) << 1);
529             i4_height = ((i4_intr_y + 1) & ~1);
530             i4_height >>= 1;
531             /* Chroma Processing (cb and cr interleaved) */
532             isvcd_copy_data(pu1_pred_chroma, i4_pred_chroma_stride, pu1_recon_chroma,
533                             i4_recon_chroma_stride, i4_width, i4_height);
534         }
535     }
536 
537     /*-----------------------------------------------------------------------*/
538     /* Reconstruct TOP_RIGHT Partition                                       */
539     /*-----------------------------------------------------------------------*/
540     {
541         WORD32 i4_width, i4_height;
542 
543         /* assign the appropriate buffer params based on Intra status */
544         if(SVCD_TRUE == ps_mb_ctxt->u1_top_rt_intra_flag)
545         {
546             pu1_pred_luma += i4_intr_x;
547             pu1_pred_chroma += (((i4_intr_x + 1) >> 1) << 1);
548 
549             /* ----------------------- Luma ------------------------ */
550             /* get the recon and residual buffer pointer */
551             pu1_recon_luma = pu1_rec_y + i4_intr_x;
552 
553             /* assign appropriate width and height for luma */
554             i4_width = MB_WIDTH - i4_intr_x;
555             i4_height = i4_intr_y;
556 
557             /* Luma Processing */
558             /* Luma Processing */
559             isvcd_copy_data(pu1_pred_luma, i4_pred_luma_stride, pu1_recon_luma,
560                             i4_recon_luma_stride, i4_width, i4_height);
561 
562             /* ----------------------- Chroma ----------------------- */
563             /* assign appropriate width and height for luma */
564             i4_width = (BLOCK_WIDTH - ((i4_intr_x + 1) >> 1)) << 1;
565 
566             /* Height includes for both Cb & Cr */
567             i4_height = ((i4_intr_y + 1) & ~1);
568             i4_height >>= 1;
569             /* get the recon and residual buffer pointer */
570             pu1_recon_chroma = pu1_rec_uv;
571             {
572                 WORD32 i4_temp;
573                 i4_temp = (((i4_intr_x + 1) >> 1) << 1);
574                 pu1_recon_chroma += i4_temp;
575             }
576 
577             /* Chroma Processing (cb and cr  interleaved) */
578             isvcd_copy_data(pu1_pred_chroma, i4_pred_chroma_stride, pu1_recon_chroma,
579                             i4_recon_chroma_stride, i4_width, i4_height);
580         }
581     }
582 
583     /*-----------------------------------------------------------------------*/
584     /* Reconstruct BOTTOM_LEFT Partition                                     */
585     /*-----------------------------------------------------------------------*/
586     {
587         WORD32 i4_width, i4_height;
588 
589         /* assign the appropriate buffer params based on Intra status */
590         if(SVCD_TRUE == ps_mb_ctxt->u1_bot_left_intra_flag)
591         {
592             pu1_pred_luma = ps_svc_lyr_dec->pu1_ii_resamp_buffer_luma;
593             pu1_pred_chroma = ps_svc_lyr_dec->pu1_ii_resamp_buffer_chroma;
594 
595             /* increment to current vertical offset */
596             pu1_pred_luma += i4_intr_y * i4_pred_luma_stride;
597             pu1_pred_chroma += (((i4_intr_y + 1) & ~1) >> 1) * i4_pred_chroma_stride;
598 
599             /* ----------------------- Luma ----------------------- */
600             /* get the recon and residual buffer pointer */
601             pu1_recon_luma = pu1_rec_y;
602             pu1_recon_luma += i4_intr_y * i4_recon_luma_stride;
603 
604             /* assign appropriate width and height */
605             i4_width = i4_intr_x;
606             i4_height = MB_HEIGHT - i4_intr_y;
607 
608             /* Luma Processing */
609             isvcd_copy_data(pu1_pred_luma, i4_pred_luma_stride, pu1_recon_luma,
610                             i4_recon_luma_stride, i4_width, i4_height);
611 
612             /* ----------------------- Chroma ----------------------- */
613             pu1_recon_chroma = pu1_rec_uv;
614             {
615                 WORD32 i4_temp;
616                 i4_temp = ((i4_intr_y + 1) & ~1) >> 1;
617                 pu1_recon_chroma += (i4_temp * i4_recon_chroma_stride);
618             }
619             /* assign appropriate width and height */
620             i4_width = ((i4_intr_x + 1) >> 1) << 1;
621             i4_height = MB_HEIGHT - (i4_intr_y & ~1);
622             i4_height >>= 1;
623             /* Chroma Processing (cb and cr interleaved) */
624             isvcd_copy_data(pu1_pred_chroma, i4_pred_chroma_stride, pu1_recon_chroma,
625                             i4_recon_chroma_stride, i4_width, i4_height);
626         }
627     }
628 
629     /*-----------------------------------------------------------------------*/
630     /* Reconstruct BOTTOM_RIGHT Partition                                    */
631     /*-----------------------------------------------------------------------*/
632     {
633         WORD32 i4_width, i4_height;
634 
635         /* assign the appropriate buffer params based on Intra status */
636         if(SVCD_TRUE == ps_mb_ctxt->u1_bot_rt_intra_flag)
637         {
638             pu1_pred_luma = ps_svc_lyr_dec->pu1_ii_resamp_buffer_luma;
639             pu1_pred_chroma = ps_svc_lyr_dec->pu1_ii_resamp_buffer_chroma;
640 
641             /* increment to current vertical offset */
642             pu1_pred_luma += i4_intr_x;
643             pu1_pred_luma += i4_intr_y * i4_pred_luma_stride;
644             pu1_pred_chroma += (((i4_intr_y + 1) & ~1) >> 1) * i4_pred_chroma_stride;
645             pu1_pred_chroma += ((i4_intr_x + 1) >> 1) << 1;
646 
647             /* ----------------------- Luma ----------------------- */
648             /* get the recon and residual buffer pointer horz */
649             pu1_recon_luma = pu1_rec_y + i4_intr_x;
650 
651             /* get the recon and residual buffer pointer vertical */
652             pu1_recon_luma += (i4_intr_y * i4_recon_luma_stride);
653 
654             /* assign appropriate width and height */
655             i4_width = MB_WIDTH - i4_intr_x;
656             i4_height = MB_HEIGHT - i4_intr_y;
657 
658             /* Luma Processing */
659             isvcd_copy_data(pu1_pred_luma, i4_pred_luma_stride, pu1_recon_luma,
660                             i4_recon_luma_stride, i4_width, i4_height);
661 
662             /* ----------------------- Chroma ----------------------- */
663             /* get the recon and residual buffer pointer horz */
664             pu1_recon_chroma = pu1_rec_uv;
665             {
666                 WORD32 i4_temp;
667                 i4_temp = ((i4_intr_y + 1) & ~1) >> 1;
668                 i4_temp *= i4_recon_chroma_stride;
669                 i4_temp += (((i4_intr_x + 1) >> 1) << 1);
670                 pu1_recon_chroma += i4_temp;
671             }
672 
673             /* assign appropriate width and height */
674             i4_width = (BLOCK_WIDTH - ((i4_intr_x + 1) >> 1)) << 1;
675             i4_height = MB_HEIGHT - (i4_intr_y & ~1);
676             i4_height >>= 1;
677             /* Chroma Processing (cb and cr interleaved) */
678             isvcd_copy_data(pu1_pred_chroma, i4_pred_chroma_stride, pu1_recon_chroma,
679                             i4_recon_chroma_stride, i4_width, i4_height);
680         }
681     }
682     return;
683 }