xref: /aosp_15_r20/external/libhevc/decoder/ihevcd_ilf_padding.c (revision c83a76b084498d55f252f48b2e3786804cdf24b7)
1*c83a76b0SSuyog Pawar /******************************************************************************
2*c83a76b0SSuyog Pawar *
3*c83a76b0SSuyog Pawar * Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
4*c83a76b0SSuyog Pawar *
5*c83a76b0SSuyog Pawar * Licensed under the Apache License, Version 2.0 (the "License");
6*c83a76b0SSuyog Pawar * you may not use this file except in compliance with the License.
7*c83a76b0SSuyog Pawar * You may obtain a copy of the License at:
8*c83a76b0SSuyog Pawar *
9*c83a76b0SSuyog Pawar * http://www.apache.org/licenses/LICENSE-2.0
10*c83a76b0SSuyog Pawar *
11*c83a76b0SSuyog Pawar * Unless required by applicable law or agreed to in writing, software
12*c83a76b0SSuyog Pawar * distributed under the License is distributed on an "AS IS" BASIS,
13*c83a76b0SSuyog Pawar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*c83a76b0SSuyog Pawar * See the License for the specific language governing permissions and
15*c83a76b0SSuyog Pawar * limitations under the License.
16*c83a76b0SSuyog Pawar *
17*c83a76b0SSuyog Pawar ******************************************************************************/
18*c83a76b0SSuyog Pawar /**
19*c83a76b0SSuyog Pawar *******************************************************************************
20*c83a76b0SSuyog Pawar * @file
21*c83a76b0SSuyog Pawar *  ihevc_ilf_padding_frame.c
22*c83a76b0SSuyog Pawar *
23*c83a76b0SSuyog Pawar * @brief
24*c83a76b0SSuyog Pawar *  Does frame level loop filtering (deblocking and SAO) and padding
25*c83a76b0SSuyog Pawar *
26*c83a76b0SSuyog Pawar * @author
27*c83a76b0SSuyog Pawar *  Srinivas T
28*c83a76b0SSuyog Pawar *
29*c83a76b0SSuyog Pawar * @par List of Functions:
30*c83a76b0SSuyog Pawar *   - ihevc_ilf_pad_frame()
31*c83a76b0SSuyog Pawar *
32*c83a76b0SSuyog Pawar * @remarks
33*c83a76b0SSuyog Pawar *  None
34*c83a76b0SSuyog Pawar *
35*c83a76b0SSuyog Pawar *******************************************************************************
36*c83a76b0SSuyog Pawar */
37*c83a76b0SSuyog Pawar 
38*c83a76b0SSuyog Pawar 
39*c83a76b0SSuyog Pawar #include <stdio.h>
40*c83a76b0SSuyog Pawar #include <stddef.h>
41*c83a76b0SSuyog Pawar #include <stdlib.h>
42*c83a76b0SSuyog Pawar #include <string.h>
43*c83a76b0SSuyog Pawar #include <assert.h>
44*c83a76b0SSuyog Pawar 
45*c83a76b0SSuyog Pawar #include "ihevc_typedefs.h"
46*c83a76b0SSuyog Pawar #include "iv.h"
47*c83a76b0SSuyog Pawar #include "ivd.h"
48*c83a76b0SSuyog Pawar #include "ihevcd_cxa.h"
49*c83a76b0SSuyog Pawar #include "ithread.h"
50*c83a76b0SSuyog Pawar 
51*c83a76b0SSuyog Pawar #include "ihevc_defs.h"
52*c83a76b0SSuyog Pawar #include "ihevc_debug.h"
53*c83a76b0SSuyog Pawar #include "ihevc_defs.h"
54*c83a76b0SSuyog Pawar #include "ihevc_structs.h"
55*c83a76b0SSuyog Pawar #include "ihevc_macros.h"
56*c83a76b0SSuyog Pawar #include "ihevc_platform_macros.h"
57*c83a76b0SSuyog Pawar #include "ihevc_cabac_tables.h"
58*c83a76b0SSuyog Pawar 
59*c83a76b0SSuyog Pawar #include "ihevc_error.h"
60*c83a76b0SSuyog Pawar #include "ihevc_common_tables.h"
61*c83a76b0SSuyog Pawar 
62*c83a76b0SSuyog Pawar #include "ihevcd_trace.h"
63*c83a76b0SSuyog Pawar #include "ihevcd_defs.h"
64*c83a76b0SSuyog Pawar #include "ihevcd_function_selector.h"
65*c83a76b0SSuyog Pawar #include "ihevcd_structs.h"
66*c83a76b0SSuyog Pawar #include "ihevcd_error.h"
67*c83a76b0SSuyog Pawar #include "ihevcd_nal.h"
68*c83a76b0SSuyog Pawar #include "ihevcd_bitstream.h"
69*c83a76b0SSuyog Pawar #include "ihevcd_job_queue.h"
70*c83a76b0SSuyog Pawar #include "ihevcd_utils.h"
71*c83a76b0SSuyog Pawar 
72*c83a76b0SSuyog Pawar #include "ihevc_deblk.h"
73*c83a76b0SSuyog Pawar #include "ihevc_deblk_tables.h"
74*c83a76b0SSuyog Pawar #include "ihevcd_profile.h"
75*c83a76b0SSuyog Pawar #include "ihevcd_deblk.h"
76*c83a76b0SSuyog Pawar #include "ihevcd_sao.h"
77*c83a76b0SSuyog Pawar #include "ihevc_padding.h"
78*c83a76b0SSuyog Pawar 
ihevcd_ilf_pad_frame(deblk_ctxt_t * ps_deblk_ctxt,sao_ctxt_t * ps_sao_ctxt)79*c83a76b0SSuyog Pawar void ihevcd_ilf_pad_frame(deblk_ctxt_t *ps_deblk_ctxt, sao_ctxt_t *ps_sao_ctxt)
80*c83a76b0SSuyog Pawar {
81*c83a76b0SSuyog Pawar     sps_t *ps_sps;
82*c83a76b0SSuyog Pawar     slice_header_t *ps_slice_hdr;
83*c83a76b0SSuyog Pawar     codec_t *ps_codec;
84*c83a76b0SSuyog Pawar     WORD32 i4_ctb_x, i4_ctb_y;
85*c83a76b0SSuyog Pawar     WORD32 ctb_size;
86*c83a76b0SSuyog Pawar 
87*c83a76b0SSuyog Pawar     ps_sps = ps_deblk_ctxt->ps_sps;
88*c83a76b0SSuyog Pawar     ps_slice_hdr = ps_deblk_ctxt->ps_slice_hdr;
89*c83a76b0SSuyog Pawar     ps_codec = ps_deblk_ctxt->ps_codec;
90*c83a76b0SSuyog Pawar     ctb_size = (1 << ps_sps->i1_log2_ctb_size);
91*c83a76b0SSuyog Pawar 
92*c83a76b0SSuyog Pawar     for(i4_ctb_y = 0; i4_ctb_y < ps_sps->i2_pic_ht_in_ctb; i4_ctb_y++)
93*c83a76b0SSuyog Pawar     {
94*c83a76b0SSuyog Pawar         for(i4_ctb_x = 0; i4_ctb_x < ps_sps->i2_pic_wd_in_ctb; i4_ctb_x++)
95*c83a76b0SSuyog Pawar         {
96*c83a76b0SSuyog Pawar             WORD32 i4_is_last_ctb_x = 0;
97*c83a76b0SSuyog Pawar             WORD32 i4_is_last_ctb_y = 0;
98*c83a76b0SSuyog Pawar 
99*c83a76b0SSuyog Pawar             /*TODO:
100*c83a76b0SSuyog Pawar              *  Slice header also has to be updated
101*c83a76b0SSuyog Pawar              *  */
102*c83a76b0SSuyog Pawar             ps_deblk_ctxt->i4_ctb_x = i4_ctb_x;
103*c83a76b0SSuyog Pawar             ps_deblk_ctxt->i4_ctb_y = i4_ctb_y;
104*c83a76b0SSuyog Pawar 
105*c83a76b0SSuyog Pawar             ps_sao_ctxt->i4_ctb_x = i4_ctb_x;
106*c83a76b0SSuyog Pawar             ps_sao_ctxt->i4_ctb_y = i4_ctb_y;
107*c83a76b0SSuyog Pawar 
108*c83a76b0SSuyog Pawar             if((0 == ps_slice_hdr->i1_slice_disable_deblocking_filter_flag) &&
109*c83a76b0SSuyog Pawar                (0 == ps_codec->i4_disable_deblk_pic))
110*c83a76b0SSuyog Pawar             {
111*c83a76b0SSuyog Pawar                 ihevcd_deblk_ctb(ps_deblk_ctxt, i4_is_last_ctb_x, i4_is_last_ctb_y);
112*c83a76b0SSuyog Pawar 
113*c83a76b0SSuyog Pawar                 /* If the last CTB in the row was a complete CTB then deblocking has to be called from remaining pixels, since deblocking
114*c83a76b0SSuyog Pawar                  * is applied on a shifted CTB structure
115*c83a76b0SSuyog Pawar                  */
116*c83a76b0SSuyog Pawar                 if(i4_ctb_x == ps_sps->i2_pic_wd_in_ctb - 1)
117*c83a76b0SSuyog Pawar                 {
118*c83a76b0SSuyog Pawar                     WORD32 last_x_pos;
119*c83a76b0SSuyog Pawar                     i4_is_last_ctb_x = 1;
120*c83a76b0SSuyog Pawar                     i4_is_last_ctb_y = 0;
121*c83a76b0SSuyog Pawar 
122*c83a76b0SSuyog Pawar 
123*c83a76b0SSuyog Pawar                     last_x_pos = (ps_sps->i2_pic_wd_in_ctb << ps_sps->i1_log2_ctb_size);
124*c83a76b0SSuyog Pawar                     if(last_x_pos  ==  ps_sps->i2_pic_width_in_luma_samples)
125*c83a76b0SSuyog Pawar                     {
126*c83a76b0SSuyog Pawar                         ihevcd_deblk_ctb(ps_deblk_ctxt, i4_is_last_ctb_x, i4_is_last_ctb_y);
127*c83a76b0SSuyog Pawar                     }
128*c83a76b0SSuyog Pawar                 }
129*c83a76b0SSuyog Pawar 
130*c83a76b0SSuyog Pawar 
131*c83a76b0SSuyog Pawar                 /* If the last CTB in the column was a complete CTB then deblocking has to be called from remaining pixels, since deblocking
132*c83a76b0SSuyog Pawar                  * is applied on a shifted CTB structure
133*c83a76b0SSuyog Pawar                  */
134*c83a76b0SSuyog Pawar                 if(i4_ctb_y == ps_sps->i2_pic_ht_in_ctb - 1)
135*c83a76b0SSuyog Pawar                 {
136*c83a76b0SSuyog Pawar                     WORD32 last_y_pos;
137*c83a76b0SSuyog Pawar                     i4_is_last_ctb_y = 1;
138*c83a76b0SSuyog Pawar                     i4_is_last_ctb_x = 0;
139*c83a76b0SSuyog Pawar 
140*c83a76b0SSuyog Pawar                     last_y_pos = (ps_sps->i2_pic_ht_in_ctb << ps_sps->i1_log2_ctb_size);
141*c83a76b0SSuyog Pawar                     if(last_y_pos == ps_sps->i2_pic_height_in_luma_samples)
142*c83a76b0SSuyog Pawar                     {
143*c83a76b0SSuyog Pawar                         ihevcd_deblk_ctb(ps_deblk_ctxt, i4_is_last_ctb_x, i4_is_last_ctb_y);
144*c83a76b0SSuyog Pawar                     }
145*c83a76b0SSuyog Pawar                 }
146*c83a76b0SSuyog Pawar             }
147*c83a76b0SSuyog Pawar 
148*c83a76b0SSuyog Pawar             if(ps_slice_hdr->i1_slice_sao_luma_flag || ps_slice_hdr->i1_slice_sao_chroma_flag)
149*c83a76b0SSuyog Pawar             {
150*c83a76b0SSuyog Pawar                 ihevcd_sao_ctb(ps_sao_ctxt);
151*c83a76b0SSuyog Pawar             }
152*c83a76b0SSuyog Pawar 
153*c83a76b0SSuyog Pawar             /* Call padding if required */
154*c83a76b0SSuyog Pawar             {
155*c83a76b0SSuyog Pawar                 UWORD8 *pu1_cur_ctb_luma = ps_deblk_ctxt->pu1_cur_pic_luma
156*c83a76b0SSuyog Pawar                                 + (i4_ctb_x * ctb_size
157*c83a76b0SSuyog Pawar                                                 + i4_ctb_y * ctb_size
158*c83a76b0SSuyog Pawar                                                                 * ps_codec->i4_strd);
159*c83a76b0SSuyog Pawar                 UWORD8 *pu1_cur_ctb_chroma = ps_deblk_ctxt->pu1_cur_pic_chroma
160*c83a76b0SSuyog Pawar                                 + i4_ctb_x * ctb_size
161*c83a76b0SSuyog Pawar                                 + (i4_ctb_y * ctb_size * ps_codec->i4_strd / 2);
162*c83a76b0SSuyog Pawar 
163*c83a76b0SSuyog Pawar                 if(0 == i4_ctb_x)
164*c83a76b0SSuyog Pawar                 {
165*c83a76b0SSuyog Pawar                     WORD32 pad_ht_luma;
166*c83a76b0SSuyog Pawar                     WORD32 pad_ht_chroma;
167*c83a76b0SSuyog Pawar 
168*c83a76b0SSuyog Pawar                     pad_ht_luma = ctb_size;
169*c83a76b0SSuyog Pawar                     pad_ht_luma += (ps_sps->i2_pic_ht_in_ctb - 1) == i4_ctb_y ? 8 : 0;
170*c83a76b0SSuyog Pawar                     pad_ht_chroma = ctb_size / 2;
171*c83a76b0SSuyog Pawar                     pad_ht_chroma += (ps_sps->i2_pic_ht_in_ctb - 1) == i4_ctb_y ? 8 : 0;
172*c83a76b0SSuyog Pawar                     /* Pad left after 1st CTB is processed */
173*c83a76b0SSuyog Pawar                     ps_codec->s_func_selector.ihevc_pad_left_luma_fptr(pu1_cur_ctb_luma - 8 * ps_codec->i4_strd, ps_codec->i4_strd, pad_ht_luma, PAD_LEFT);
174*c83a76b0SSuyog Pawar                     ps_codec->s_func_selector.ihevc_pad_left_chroma_fptr(pu1_cur_ctb_chroma - 8 * ps_codec->i4_strd, ps_codec->i4_strd, pad_ht_chroma, PAD_LEFT);
175*c83a76b0SSuyog Pawar                 }
176*c83a76b0SSuyog Pawar                 else if((ps_sps->i2_pic_wd_in_ctb - 1) == i4_ctb_x)
177*c83a76b0SSuyog Pawar                 {
178*c83a76b0SSuyog Pawar                     WORD32 pad_ht_luma;
179*c83a76b0SSuyog Pawar                     WORD32 pad_ht_chroma;
180*c83a76b0SSuyog Pawar                     WORD32 cols_remaining = ps_sps->i2_pic_width_in_luma_samples - (i4_ctb_x << ps_sps->i1_log2_ctb_size);
181*c83a76b0SSuyog Pawar 
182*c83a76b0SSuyog Pawar                     pad_ht_luma = ctb_size;
183*c83a76b0SSuyog Pawar                     pad_ht_luma += (ps_sps->i2_pic_ht_in_ctb - 1) == i4_ctb_y ? 8 : 0;
184*c83a76b0SSuyog Pawar                     pad_ht_chroma = ctb_size / 2;
185*c83a76b0SSuyog Pawar                     pad_ht_chroma += (ps_sps->i2_pic_ht_in_ctb - 1) == i4_ctb_y ? 8 : 0;
186*c83a76b0SSuyog Pawar                     /* Pad right after last CTB in the current row is processed */
187*c83a76b0SSuyog Pawar                     ps_codec->s_func_selector.ihevc_pad_right_luma_fptr(pu1_cur_ctb_luma + cols_remaining - 8 * ps_codec->i4_strd, ps_codec->i4_strd, pad_ht_luma, PAD_RIGHT);
188*c83a76b0SSuyog Pawar                     ps_codec->s_func_selector.ihevc_pad_right_chroma_fptr(pu1_cur_ctb_chroma + cols_remaining - 8 * ps_codec->i4_strd, ps_codec->i4_strd, pad_ht_chroma, PAD_RIGHT);
189*c83a76b0SSuyog Pawar 
190*c83a76b0SSuyog Pawar 
191*c83a76b0SSuyog Pawar                     if((ps_sps->i2_pic_ht_in_ctb - 1) == i4_ctb_y)
192*c83a76b0SSuyog Pawar                     {
193*c83a76b0SSuyog Pawar                         UWORD8 *pu1_buf;
194*c83a76b0SSuyog Pawar                         /* Since SAO is shifted by 8x8, chroma padding can not be done till second row is processed */
195*c83a76b0SSuyog Pawar                         /* Hence moving top padding to to end of frame, Moving it to second row also results in problems when there is only one row */
196*c83a76b0SSuyog Pawar                         /* Pad top after padding left and right for current rows after processing 1st CTB row */
197*c83a76b0SSuyog Pawar                         ihevc_pad_top(ps_deblk_ctxt->pu1_cur_pic_luma - PAD_LEFT, ps_codec->i4_strd, ps_sps->i2_pic_width_in_luma_samples + PAD_WD, PAD_TOP);
198*c83a76b0SSuyog Pawar                         ihevc_pad_top(ps_deblk_ctxt->pu1_cur_pic_chroma - PAD_LEFT, ps_codec->i4_strd, ps_sps->i2_pic_width_in_luma_samples + PAD_WD, PAD_TOP / 2);
199*c83a76b0SSuyog Pawar 
200*c83a76b0SSuyog Pawar                         pu1_buf = ps_deblk_ctxt->pu1_cur_pic_luma + ps_codec->i4_strd * ps_sps->i2_pic_height_in_luma_samples - PAD_LEFT;
201*c83a76b0SSuyog Pawar                         /* Pad top after padding left and right for current rows after processing 1st CTB row */
202*c83a76b0SSuyog Pawar                         ihevc_pad_bottom(pu1_buf, ps_codec->i4_strd, ps_sps->i2_pic_width_in_luma_samples + PAD_WD, PAD_BOT);
203*c83a76b0SSuyog Pawar 
204*c83a76b0SSuyog Pawar                         pu1_buf = ps_deblk_ctxt->pu1_cur_pic_chroma + ps_codec->i4_strd * (ps_sps->i2_pic_height_in_luma_samples / 2) - PAD_LEFT;
205*c83a76b0SSuyog Pawar                         ihevc_pad_bottom(pu1_buf, ps_codec->i4_strd, ps_sps->i2_pic_width_in_luma_samples + PAD_WD, PAD_BOT / 2);
206*c83a76b0SSuyog Pawar                     }
207*c83a76b0SSuyog Pawar                 }
208*c83a76b0SSuyog Pawar             }
209*c83a76b0SSuyog Pawar 
210*c83a76b0SSuyog Pawar 
211*c83a76b0SSuyog Pawar         }
212*c83a76b0SSuyog Pawar     }
213*c83a76b0SSuyog Pawar 
214*c83a76b0SSuyog Pawar }
215