1 /******************************************************************************
2 *
3 * Copyright (C) 2018 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 ******************************************************************************
23 * \file ihevce_enc_subpel_gen.c
24 *
25 * \brief
26 * This file contains Padding and Subpel plane generation functions
27 * at CTB level
28 *
29 * \date
30 * 29/12/2012
31 *
32 * \author
33 * Ittiam
34 *
35 *
36 * List of Functions
37 * - ihevce_suppel_padding()
38 * - ihevce_pad_interp_recon_ctb()
39 *
40 *
41 ******************************************************************************
42 */
43
44 /*****************************************************************************/
45 /* File Includes */
46 /*****************************************************************************/
47 /* System include files */
48 #include <stdio.h>
49 #include <string.h>
50 #include <stdlib.h>
51 #include <assert.h>
52 #include <stdarg.h>
53 #include <math.h>
54
55 /* User include files */
56 #include "ihevc_typedefs.h"
57 #include "itt_video_api.h"
58 #include "ihevce_api.h"
59
60 #include "rc_cntrl_param.h"
61 #include "rc_frame_info_collector.h"
62 #include "rc_look_ahead_params.h"
63
64 #include "ihevc_defs.h"
65 #include "ihevc_debug.h"
66 #include "ihevc_macros.h"
67 #include "ihevc_structs.h"
68 #include "ihevc_platform_macros.h"
69 #include "ihevc_deblk.h"
70 #include "ihevc_itrans_recon.h"
71 #include "ihevc_chroma_itrans_recon.h"
72 #include "ihevc_chroma_intra_pred.h"
73 #include "ihevc_intra_pred.h"
74 #include "ihevc_inter_pred.h"
75 #include "ihevc_mem_fns.h"
76 #include "ihevc_padding.h"
77 #include "ihevc_weighted_pred.h"
78 #include "ihevc_sao.h"
79 #include "ihevc_resi_trans.h"
80 #include "ihevc_quant_iquant_ssd.h"
81 #include "ihevc_cabac_tables.h"
82 #include "ihevc_trans_tables.h"
83 #include "ihevc_trans_macros.h"
84
85 #include "ihevce_defs.h"
86 #include "ihevce_lap_enc_structs.h"
87 #include "ihevce_multi_thrd_structs.h"
88 #include "ihevce_multi_thrd_funcs.h"
89 #include "ihevce_me_common_defs.h"
90 #include "ihevce_had_satd.h"
91 #include "ihevce_error_codes.h"
92 #include "ihevce_bitstream.h"
93 #include "ihevce_cabac.h"
94 #include "ihevce_rdoq_macros.h"
95 #include "ihevce_function_selector.h"
96 #include "ihevce_enc_structs.h"
97 #include "ihevce_global_tables.h"
98 #include "ihevce_cmn_utils_instr_set_router.h"
99 #include "ihevce_entropy_structs.h"
100 #include "ihevce_enc_loop_structs.h"
101 #include "ihevce_enc_loop_utils.h"
102 #include "ihevce_inter_pred.h"
103 #include "ihevce_common_utils.h"
104
105 /*!
106 ******************************************************************************
107 * \if Function name : ihevce_suppel_padding \endif
108 *
109 * \brief
110 * Subpel Plane planes Padding Function
111 *
112 * \param[in] pu1_dst : pointer to subpel plane
113 * stride : subpel plane stride same as recon stride
114 * tot_wd : width of the block in subpel plane
115 * tot_ht : hieght of the block in subpel plane
116 * ctb_ctr : ctb horizontal position
117 * vert_ctr : ctb vertical position
118 * ps_frm_ctb_prms : CTB characteristics parameters
119 * \return
120 * None
121 *
122 *
123 * \author
124 * Ittiam
125 *
126 *****************************************************************************
127 */
ihevce_subpel_padding(UWORD8 * pu1_dst,WORD32 stride,WORD32 tot_wd,WORD32 tot_ht,WORD32 pad_subpel_x,WORD32 pad_subpel_y,WORD32 ctb_ctr,WORD32 vert_ctr,WORD32 i4_num_ctbs_horz,WORD32 i4_num_ctbs_vert,func_selector_t * ps_func_selector)128 void ihevce_subpel_padding(
129 UWORD8 *pu1_dst,
130 WORD32 stride,
131 WORD32 tot_wd,
132 WORD32 tot_ht,
133 WORD32 pad_subpel_x,
134 WORD32 pad_subpel_y,
135 WORD32 ctb_ctr,
136 WORD32 vert_ctr,
137 WORD32 i4_num_ctbs_horz,
138 WORD32 i4_num_ctbs_vert,
139 func_selector_t *ps_func_selector)
140 {
141 ihevc_pad_top_ft *pf_pad_top = ps_func_selector->ihevc_pad_top_fptr;
142 ihevc_pad_bottom_ft *pf_pad_bottom = ps_func_selector->ihevc_pad_bottom_fptr;
143 ihevc_pad_left_luma_ft *pf_pad_left_luma = ps_func_selector->ihevc_pad_left_luma_fptr;
144 ihevc_pad_right_luma_ft *pf_pad_right_luma = ps_func_selector->ihevc_pad_right_luma_fptr;
145
146 UWORD8 *pu1_dst_tmp = pu1_dst;
147 WORD32 cpy_ht = tot_ht;
148
149 /* Top padding*/
150 if(vert_ctr == 0)
151 {
152 PAD_BUF_VER(pu1_dst, stride, tot_wd, pad_subpel_x, pad_subpel_y, pf_pad_top);
153 /*if curr ctb is 1st ctb in ctb row, update dst pointer for Left padding*/
154 pu1_dst_tmp = pu1_dst - pad_subpel_y * stride;
155 cpy_ht += pad_subpel_y;
156 }
157 /*bottom padding*/
158 if(vert_ctr == (i4_num_ctbs_vert - 1))
159 {
160 PAD_BUF_VER(
161 (pu1_dst + (tot_ht * stride)),
162 stride,
163 tot_wd,
164 pad_subpel_x,
165 pad_subpel_y,
166 pf_pad_bottom);
167 /*if curr ctb is 1st ctb in ctb row, update dst pointer for right padding*/
168 cpy_ht += pad_subpel_y;
169 }
170
171 /*left padding*/
172 if(ctb_ctr == 0)
173 {
174 PAD_BUF_HOR(pu1_dst_tmp, stride, cpy_ht, pad_subpel_x, pad_subpel_y, pf_pad_left_luma);
175 }
176
177 /*right padding*/
178 if(ctb_ctr == (i4_num_ctbs_horz - 1))
179 {
180 PAD_BUF_HOR(
181 pu1_dst_tmp + tot_wd, stride, cpy_ht, pad_subpel_x, pad_subpel_y, pf_pad_right_luma);
182 }
183 }
184
185 /*!
186 ******************************************************************************
187 * \if Function name : ihevce_pad_interp_recon_ctb \endif
188 *
189 * \brief
190 * Ctb level Subpel Plane generation and padding function
191 *
192 * \param[in]
193 * s_cu_prms : coding unit params structures (recon buffers)
194 * ctb_ctr : ctb horizontal position
195 * vert_ctr : ctb vertical position
196 * ps_frm_ctb_prms : CTB characteristics parameters
197 * i4_dist_nbr_mask : nbr-mask for distributed mode. Should be 0 for standalone
198 * or distributed-single-client mode
199 *
200 * \return
201 * None
202 *
203 * \author
204 * Ittiam
205 *
206 *****************************************************************************
207 */
ihevce_pad_interp_recon_ctb(pad_interp_recon_frm_t * ps_pad_interp_recon,WORD32 ctb_ctr,WORD32 vert_ctr,WORD32 quality_preset,frm_ctb_ctxt_t * ps_frm_ctb_prms,WORD16 * pi2_hxhy_interm,WORD32 i4_bitrate_instance_id,func_selector_t * ps_func_selector)208 void ihevce_pad_interp_recon_ctb(
209 pad_interp_recon_frm_t *ps_pad_interp_recon,
210 WORD32 ctb_ctr,
211 WORD32 vert_ctr,
212 WORD32 quality_preset,
213 frm_ctb_ctxt_t *ps_frm_ctb_prms,
214 WORD16 *pi2_hxhy_interm,
215 WORD32 i4_bitrate_instance_id,
216 func_selector_t *ps_func_selector)
217 {
218 UWORD8 *pu1_src, *pu1_src_uv, *pu1_buf_y, *pu1_buf_uv;
219 WORD32 stride, stride_uv, wd, ht, wd_uv, ht_uv, pad_x, pad_y, pad_subpel_x, pad_subpel_y;
220 WORD32 tot_wd, tot_ht, offset, cpy_ht_y, cpy_ht_uv;
221 WORD32 i4_chroma_vert_pad_default;
222 WORD32 top_extra_pix = 0, left_extra_pix = 0;
223
224 WORD32 ctb_size = ps_frm_ctb_prms->i4_ctb_size;
225 UWORD8 *pu1_dst_hxfy = ps_pad_interp_recon->pu1_sbpel_hxfy +
226 (vert_ctr * ctb_size * ps_pad_interp_recon->i4_luma_recon_stride) +
227 (ctb_ctr * ctb_size);
228 UWORD8 *pu1_dst_fxhy = ps_pad_interp_recon->pu1_sbpel_fxhy +
229 (vert_ctr * ctb_size * ps_pad_interp_recon->i4_luma_recon_stride) +
230 (ctb_ctr * ctb_size);
231 UWORD8 *pu1_dst_hxhy = ps_pad_interp_recon->pu1_sbpel_hxhy +
232 (vert_ctr * ctb_size * ps_pad_interp_recon->i4_luma_recon_stride) +
233 (ctb_ctr * ctb_size);
234 UWORD8 u1_is_422 = (ps_pad_interp_recon->u1_chroma_array_type == 2);
235
236 ihevc_pad_top_ft *pf_pad_top = ps_func_selector->ihevc_pad_top_fptr;
237 ihevc_pad_bottom_ft *pf_pad_bottom = ps_func_selector->ihevc_pad_bottom_fptr;
238 ihevc_pad_left_luma_ft *pf_pad_left_luma = ps_func_selector->ihevc_pad_left_luma_fptr;
239 ihevc_pad_left_chroma_ft *pf_pad_left_chroma = ps_func_selector->ihevc_pad_left_chroma_fptr;
240 ihevc_pad_right_luma_ft *pf_pad_right_luma = ps_func_selector->ihevc_pad_right_luma_fptr;
241 ihevc_pad_right_chroma_ft *pf_pad_right_chroma = ps_func_selector->ihevc_pad_right_chroma_fptr;
242
243 ihevc_inter_pred_ft *pf_inter_pred_luma_horz =
244 ps_func_selector->ihevc_inter_pred_luma_horz_fptr;
245 ihevc_inter_pred_ft *pf_inter_pred_luma_vert =
246 ps_func_selector->ihevc_inter_pred_luma_vert_fptr;
247 ihevc_inter_pred_w16out_ft *pf_inter_pred_luma_horz_w16out =
248 ps_func_selector->ihevc_inter_pred_luma_horz_w16out_fptr;
249 ihevc_inter_pred_w16inp_ft *pf_inter_pred_luma_vert_w16inp =
250 ps_func_selector->ihevc_inter_pred_luma_vert_w16inp_fptr;
251 stride = ps_pad_interp_recon->i4_luma_recon_stride;
252 wd = ps_pad_interp_recon->i4_ctb_size;
253 ht = ps_pad_interp_recon->i4_ctb_size;
254
255 pu1_src = (UWORD8 *)ps_pad_interp_recon->pu1_luma_recon + (vert_ctr * ctb_size * stride) +
256 (ctb_ctr * ctb_size);
257
258 stride_uv = ps_pad_interp_recon->i4_chrm_recon_stride;
259 wd_uv = ps_pad_interp_recon->i4_ctb_size;
260 ht_uv = ps_pad_interp_recon->i4_ctb_size >> (0 == u1_is_422);
261
262 pu1_src_uv = (UWORD8 *)ps_pad_interp_recon->pu1_chrm_recon +
263 (vert_ctr * (ctb_size >> (0 == u1_is_422)) * stride_uv) + (ctb_ctr * ctb_size);
264
265 pad_x = ALIGN8(NTAPS_LUMA);
266 pad_y = ALIGN8(NTAPS_LUMA);
267 pad_subpel_x = PAD_HORZ - pad_x;
268 pad_subpel_y = PAD_VERT - pad_y;
269
270 offset = pad_x + (pad_y * stride);
271
272 tot_wd = wd + (pad_x << 1);
273 tot_ht = ht + (pad_y << 1);
274
275 i4_chroma_vert_pad_default = PAD_VERT >> (0 == u1_is_422);
276
277 if(ctb_ctr == (ps_frm_ctb_prms->i4_num_ctbs_horz - 1))
278 {
279 WORD32 last_ctb_x =
280 ps_frm_ctb_prms->i4_cu_aligned_pic_wd -
281 ((ps_frm_ctb_prms->i4_num_ctbs_horz - 1) * ps_pad_interp_recon->i4_ctb_size);
282 wd = last_ctb_x;
283 wd_uv = last_ctb_x;
284 }
285 if(vert_ctr == (ps_frm_ctb_prms->i4_num_ctbs_vert - 1))
286 {
287 WORD32 last_ctb_y =
288 ps_frm_ctb_prms->i4_cu_aligned_pic_ht -
289 ((ps_frm_ctb_prms->i4_num_ctbs_vert - 1) * ps_pad_interp_recon->i4_ctb_size);
290 ht = last_ctb_y;
291 ht_uv = last_ctb_y >> (0 == u1_is_422);
292 }
293 tot_ht = ht;
294 tot_wd = wd;
295 pu1_buf_y = pu1_src;
296 pu1_buf_uv = pu1_src_uv;
297 cpy_ht_y = ht;
298 cpy_ht_uv = ht_uv;
299 if(vert_ctr > 0)
300 {
301 top_extra_pix = 8;
302 }
303 if(ctb_ctr > 0)
304 {
305 left_extra_pix = 8;
306 }
307 /*top padding*/
308 if(vert_ctr == 0)
309 {
310 PAD_BUF_VER(
311 pu1_src - left_extra_pix, stride, wd + left_extra_pix, PAD_HORZ, PAD_VERT, pf_pad_top);
312 PAD_BUF_VER(
313 pu1_src_uv - left_extra_pix,
314 stride_uv,
315 wd_uv + left_extra_pix,
316 PAD_HORZ,
317 i4_chroma_vert_pad_default,
318 pf_pad_top);
319 tot_ht = pad_y + ht - 8;
320 /*if curr ctb is 1st ctb in ctb row, update dst pointer for Left padding*/
321 pu1_buf_y = pu1_src - PAD_VERT * stride;
322 pu1_buf_uv = pu1_src_uv - i4_chroma_vert_pad_default * stride_uv;
323 cpy_ht_y += PAD_VERT;
324 cpy_ht_uv += i4_chroma_vert_pad_default;
325 }
326 /*bottom padding*/
327 if(vert_ctr == (ps_frm_ctb_prms->i4_num_ctbs_vert - 1))
328 {
329 PAD_BUF_VER(
330 (pu1_src - left_extra_pix + (ht * stride)),
331 stride,
332 wd + left_extra_pix,
333 PAD_HORZ,
334 PAD_VERT,
335 pf_pad_bottom);
336 PAD_BUF_VER(
337 (pu1_src_uv - left_extra_pix + (ht_uv * stride_uv)),
338 stride_uv,
339 wd_uv + left_extra_pix,
340 PAD_HORZ,
341 i4_chroma_vert_pad_default,
342 pf_pad_bottom);
343 tot_ht = pad_y + ht + 8;
344 /*if curr ctb is 1st ctb in ctb row, update dst pointer for right padding*/
345 cpy_ht_y += PAD_VERT;
346 cpy_ht_uv += i4_chroma_vert_pad_default;
347 }
348
349 /*Left padding*/
350 if(ctb_ctr == 0)
351 {
352 PAD_BUF_HOR(
353 (pu1_buf_y - top_extra_pix * stride),
354 stride,
355 cpy_ht_y + top_extra_pix,
356 PAD_HORZ,
357 PAD_VERT,
358 pf_pad_left_luma);
359 PAD_BUF_HOR(
360 pu1_buf_uv - (top_extra_pix >> 1) * (u1_is_422 + 1) * stride_uv,
361 stride_uv,
362 cpy_ht_uv + (top_extra_pix >> 1) * (u1_is_422 + 1),
363 PAD_HORZ,
364 i4_chroma_vert_pad_default,
365 pf_pad_left_chroma);
366 tot_wd = pad_x + wd - 8;
367 }
368 /*right padding*/
369 if(ctb_ctr == (ps_frm_ctb_prms->i4_num_ctbs_horz - 1))
370 {
371 PAD_BUF_HOR(
372 (pu1_buf_y - (top_extra_pix * stride) + wd),
373 stride,
374 cpy_ht_y + top_extra_pix,
375 PAD_HORZ,
376 PAD_VERT,
377 pf_pad_right_luma);
378 PAD_BUF_HOR(
379 (pu1_buf_uv - ((top_extra_pix >> 1) * (u1_is_422 + 1) * stride_uv) + wd_uv),
380 stride_uv,
381 cpy_ht_uv + (top_extra_pix >> 1) * (u1_is_422 + 1),
382 PAD_HORZ,
383 i4_chroma_vert_pad_default,
384 pf_pad_right_chroma);
385 tot_wd = pad_x + wd + 8;
386 }
387
388 pu1_src -= offset;
389 pu1_dst_hxhy -= offset;
390 pu1_dst_hxfy -= offset;
391 pu1_dst_fxhy -= offset;
392
393 {
394 tot_wd = ALIGN16(tot_wd);
395 if(0 ==
396 i4_bitrate_instance_id) //do the following subpel calculations for reference bit-rate instance only
397 {
398 /* HxFY plane */
399 pf_inter_pred_luma_horz(
400 pu1_src,
401 pu1_dst_hxfy,
402 stride,
403 stride,
404 (WORD8 *)gai1_hevc_luma_filter_taps[2],
405 tot_ht,
406 tot_wd);
407
408 pf_inter_pred_luma_vert(
409 pu1_src,
410 pu1_dst_fxhy,
411 stride,
412 stride,
413 (WORD8 *)gai1_hevc_luma_filter_taps[2],
414 tot_ht,
415 tot_wd);
416
417 pf_inter_pred_luma_horz_w16out(
418 pu1_src - 3 * stride,
419 pi2_hxhy_interm,
420 stride,
421 tot_wd,
422 (WORD8 *)gai1_hevc_luma_filter_taps[2],
423 (tot_ht + 7),
424 tot_wd);
425
426 /* "Stride" of intermediate buffer in pixels,equals tot_wd */
427 pf_inter_pred_luma_vert_w16inp(
428 pi2_hxhy_interm + (3 * tot_wd),
429 pu1_dst_hxhy,
430 tot_wd,
431 stride,
432 (WORD8 *)gai1_hevc_luma_filter_taps[2],
433 tot_ht,
434 tot_wd);
435
436 ihevce_subpel_padding(
437 pu1_dst_fxhy,
438 stride,
439 tot_wd,
440 tot_ht,
441 pad_subpel_x,
442 pad_subpel_y,
443 ctb_ctr,
444 vert_ctr,
445 ps_frm_ctb_prms->i4_num_ctbs_horz,
446 ps_frm_ctb_prms->i4_num_ctbs_vert,
447 ps_func_selector);
448
449 ihevce_subpel_padding(
450 pu1_dst_hxfy,
451 stride,
452 tot_wd,
453 tot_ht,
454 pad_subpel_x,
455 pad_subpel_y,
456 ctb_ctr,
457 vert_ctr,
458 ps_frm_ctb_prms->i4_num_ctbs_horz,
459 ps_frm_ctb_prms->i4_num_ctbs_vert,
460 ps_func_selector);
461
462 ihevce_subpel_padding(
463 pu1_dst_hxhy,
464 stride,
465 tot_wd,
466 tot_ht,
467 pad_subpel_x,
468 pad_subpel_y,
469 ctb_ctr,
470 vert_ctr,
471 ps_frm_ctb_prms->i4_num_ctbs_horz,
472 ps_frm_ctb_prms->i4_num_ctbs_vert,
473 ps_func_selector);
474 }
475 }
476 }
477
ihevce_pad_interp_recon_src_ctb(pad_interp_recon_frm_t * ps_pad_interp_recon,WORD32 ctb_ctr,WORD32 vert_ctr,frm_ctb_ctxt_t * ps_frm_ctb_prms,WORD32 i4_bitrate_instance_id,func_selector_t * ps_func_selector,WORD32 is_chroma_needs_padding)478 void ihevce_pad_interp_recon_src_ctb(
479 pad_interp_recon_frm_t *ps_pad_interp_recon,
480 WORD32 ctb_ctr,
481 WORD32 vert_ctr,
482 frm_ctb_ctxt_t *ps_frm_ctb_prms,
483 WORD32 i4_bitrate_instance_id,
484 func_selector_t *ps_func_selector,
485 WORD32 is_chroma_needs_padding)
486 {
487 UWORD8 *pu1_src, *pu1_src_uv;
488 WORD32 stride, stride_uv, wd, ht, wd_uv, ht_uv, pad_x, pad_y;
489 WORD32 tot_wd, tot_ht;
490 WORD32 i4_chroma_vert_pad_default;
491
492 WORD32 ctb_size = ps_frm_ctb_prms->i4_ctb_size;
493 UWORD8 u1_is_422 = (ps_pad_interp_recon->u1_chroma_array_type == 2);
494
495 ihevc_pad_top_ft *pf_pad_top = ps_func_selector->ihevc_pad_top_fptr;
496 ihevc_pad_bottom_ft *pf_pad_bottom = ps_func_selector->ihevc_pad_bottom_fptr;
497 ihevc_pad_left_luma_ft *pf_pad_left_luma = ps_func_selector->ihevc_pad_left_luma_fptr;
498 ihevc_pad_left_chroma_ft *pf_pad_left_chroma = ps_func_selector->ihevc_pad_left_chroma_fptr;
499 ihevc_pad_right_luma_ft *pf_pad_right_luma = ps_func_selector->ihevc_pad_right_luma_fptr;
500 ihevc_pad_right_chroma_ft *pf_pad_right_chroma = ps_func_selector->ihevc_pad_right_chroma_fptr;
501
502 /* Luma padding */
503 pu1_src = (UWORD8 *)ps_pad_interp_recon->pu1_luma_recon_src +
504 (vert_ctr * ctb_size * ps_pad_interp_recon->i4_luma_recon_stride) +
505 (ctb_ctr * ctb_size);
506
507 stride = ps_pad_interp_recon->i4_luma_recon_stride;
508 wd = ps_pad_interp_recon->i4_ctb_size;
509 ht = ps_pad_interp_recon->i4_ctb_size;
510
511 pu1_src_uv =
512 (UWORD8 *)ps_pad_interp_recon->pu1_chrm_recon_src +
513 (vert_ctr * (ctb_size >> (0 == u1_is_422)) * ps_pad_interp_recon->i4_chrm_recon_stride) +
514 (ctb_ctr * ctb_size);
515
516 stride_uv = ps_pad_interp_recon->i4_chrm_recon_stride;
517 wd_uv = ps_pad_interp_recon->i4_ctb_size;
518 ht_uv = ps_pad_interp_recon->i4_ctb_size >> (0 == u1_is_422);
519
520 pad_x = ALIGN8(NTAPS_LUMA);
521 pad_y = ALIGN8(NTAPS_LUMA);
522
523 tot_wd = wd + (pad_x << 1);
524 tot_ht = ht + (pad_y << 1);
525
526 i4_chroma_vert_pad_default = PAD_VERT >> (0 == u1_is_422);
527
528 if(ctb_ctr == (ps_frm_ctb_prms->i4_num_ctbs_horz - 1))
529 {
530 WORD32 last_ctb_x =
531 ps_frm_ctb_prms->i4_cu_aligned_pic_wd -
532 ((ps_frm_ctb_prms->i4_num_ctbs_horz - 1) * ps_pad_interp_recon->i4_ctb_size);
533 wd = last_ctb_x;
534 wd_uv = last_ctb_x;
535 }
536 if(vert_ctr == (ps_frm_ctb_prms->i4_num_ctbs_vert - 1))
537 {
538 WORD32 last_ctb_y =
539 ps_frm_ctb_prms->i4_cu_aligned_pic_ht -
540 ((ps_frm_ctb_prms->i4_num_ctbs_vert - 1) * ps_pad_interp_recon->i4_ctb_size);
541 ht = last_ctb_y;
542 ht_uv = last_ctb_y >> (0 == u1_is_422);
543 }
544
545 if(ctb_ctr == 0)
546 {
547 if(vert_ctr == 0)
548 {
549 PAD_BUF_HOR(pu1_src, stride, ht, PAD_HORZ, PAD_VERT, pf_pad_left_luma);
550 PAD_BUF_VER(pu1_src - PAD_HORZ, stride, PAD_HORZ + wd, PAD_HORZ, PAD_VERT, pf_pad_top);
551 if(is_chroma_needs_padding)
552 {
553 PAD_BUF_HOR(
554 pu1_src_uv,
555 stride_uv,
556 ht_uv,
557 PAD_HORZ,
558 i4_chroma_vert_pad_default,
559 pf_pad_left_chroma);
560 PAD_BUF_VER(
561 pu1_src_uv - PAD_HORZ,
562 stride_uv,
563 PAD_HORZ + wd_uv,
564 PAD_HORZ,
565 i4_chroma_vert_pad_default,
566 pf_pad_top);
567 }
568 }
569 else if(vert_ctr == (ps_frm_ctb_prms->i4_num_ctbs_vert - 1))
570 {
571 PAD_BUF_HOR(pu1_src - 8 * stride, stride, ht + 8, PAD_HORZ, PAD_VERT, pf_pad_left_luma);
572 PAD_BUF_VER(
573 (pu1_src - PAD_HORZ + (ht * stride)),
574 stride,
575 PAD_HORZ + wd,
576 PAD_HORZ,
577 PAD_VERT,
578 pf_pad_bottom);
579 if(is_chroma_needs_padding)
580 {
581 PAD_BUF_HOR(
582 pu1_src_uv - 4 * (u1_is_422 + 1) * stride_uv,
583 stride_uv,
584 ht_uv + 4 * (u1_is_422 + 1),
585 PAD_HORZ,
586 i4_chroma_vert_pad_default,
587 pf_pad_left_chroma);
588 PAD_BUF_VER(
589 (pu1_src_uv - PAD_HORZ + (ht_uv * stride_uv)),
590 stride_uv,
591 PAD_HORZ + wd_uv,
592 PAD_HORZ,
593 i4_chroma_vert_pad_default,
594 pf_pad_bottom);
595 }
596 }
597 else
598 {
599 PAD_BUF_HOR(pu1_src - 8 * stride, stride, ht + 8, PAD_HORZ, PAD_VERT, pf_pad_left_luma);
600 if(is_chroma_needs_padding)
601 {
602 PAD_BUF_HOR(
603 pu1_src_uv - 4 * (u1_is_422 + 1) * stride_uv,
604 stride_uv,
605 ht_uv + 4 * (u1_is_422 + 1),
606 PAD_HORZ,
607 i4_chroma_vert_pad_default,
608 pf_pad_left_chroma);
609 }
610 }
611 }
612 else if(ctb_ctr == (ps_frm_ctb_prms->i4_num_ctbs_horz - 1))
613 {
614 if(vert_ctr == 0)
615 {
616 PAD_BUF_HOR(pu1_src + wd, stride, ht, PAD_HORZ, PAD_VERT, pf_pad_right_luma);
617 PAD_BUF_VER(pu1_src - 8, stride, PAD_HORZ + (wd + 8), PAD_HORZ, PAD_VERT, pf_pad_top);
618 if(is_chroma_needs_padding)
619 {
620 PAD_BUF_HOR(
621 pu1_src_uv + wd_uv,
622 stride_uv,
623 ht_uv,
624 PAD_HORZ,
625 i4_chroma_vert_pad_default,
626 pf_pad_right_chroma);
627 PAD_BUF_VER(
628 pu1_src_uv - 8,
629 stride_uv,
630 PAD_HORZ + (wd_uv + 8),
631 PAD_HORZ,
632 i4_chroma_vert_pad_default,
633 pf_pad_top);
634 }
635 }
636 else if(vert_ctr == (ps_frm_ctb_prms->i4_num_ctbs_vert - 1))
637 {
638 PAD_BUF_HOR(
639 (pu1_src - (8 * stride) + wd),
640 stride,
641 ht + 8,
642 PAD_HORZ,
643 PAD_VERT,
644 pf_pad_right_luma);
645 PAD_BUF_VER(
646 (pu1_src - 8 + (ht * stride)),
647 stride,
648 PAD_HORZ + (wd + 8),
649 PAD_HORZ,
650 PAD_VERT,
651 pf_pad_bottom);
652 if(is_chroma_needs_padding)
653 {
654 PAD_BUF_HOR(
655 (pu1_src_uv - (4 * (u1_is_422 + 1) * stride_uv) + wd_uv),
656 stride_uv,
657 ht_uv + 4 * (u1_is_422 + 1),
658 PAD_HORZ,
659 i4_chroma_vert_pad_default,
660 pf_pad_right_chroma);
661 PAD_BUF_VER(
662 (pu1_src_uv - 8 + (ht_uv * stride_uv)),
663 stride_uv,
664 PAD_HORZ + (wd_uv + 8),
665 PAD_HORZ,
666 i4_chroma_vert_pad_default,
667 pf_pad_bottom);
668 }
669 }
670 else
671 {
672 PAD_BUF_HOR(
673 (pu1_src - (8 * stride) + wd),
674 stride,
675 ht + 8,
676 PAD_HORZ,
677 PAD_VERT,
678 pf_pad_right_luma);
679 if(is_chroma_needs_padding)
680 {
681 PAD_BUF_HOR(
682 (pu1_src_uv - (4 * (u1_is_422 + 1) * stride_uv) + wd_uv),
683 stride_uv,
684 ht_uv + 4 * (u1_is_422 + 1),
685 PAD_HORZ,
686 i4_chroma_vert_pad_default,
687 pf_pad_right_chroma);
688 }
689 }
690 }
691 else if(vert_ctr == 0)
692 {
693 PAD_BUF_VER(pu1_src - 8, stride, (wd + 8), PAD_HORZ, PAD_VERT, pf_pad_top);
694 if(is_chroma_needs_padding)
695 {
696 PAD_BUF_VER(
697 pu1_src_uv - 8,
698 stride_uv,
699 (wd_uv + 8),
700 PAD_HORZ,
701 i4_chroma_vert_pad_default,
702 pf_pad_top);
703 }
704 }
705 else if(vert_ctr == (ps_frm_ctb_prms->i4_num_ctbs_vert - 1))
706 {
707 PAD_BUF_VER(
708 (pu1_src - 8 + (ht * stride)), stride, (wd + 8), PAD_HORZ, PAD_VERT, pf_pad_bottom);
709 if(is_chroma_needs_padding)
710 {
711 PAD_BUF_VER(
712 (pu1_src_uv - 8 + (ht_uv * stride_uv)),
713 stride_uv,
714 (wd_uv + 8),
715 PAD_HORZ,
716 i4_chroma_vert_pad_default,
717 pf_pad_bottom);
718 }
719 }
720 }
721