1 /******************************************************************************
2 *
3 * Copyright (C) 2012 Ittiam Systems Pvt Ltd, Bangalore
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 /**
19 *******************************************************************************
20 * @file
21 *  ihevc_ilf_padding_frame.c
22 *
23 * @brief
24 *  Does frame level loop filtering (deblocking and SAO) and padding
25 *
26 * @author
27 *  Srinivas T
28 *
29 * @par List of Functions:
30 *   - ihevc_ilf_pad_frame()
31 *
32 * @remarks
33 *  None
34 *
35 *******************************************************************************
36 */
37 
38 
39 #include <stdio.h>
40 #include <stddef.h>
41 #include <stdlib.h>
42 #include <string.h>
43 #include <assert.h>
44 
45 #include "ihevc_typedefs.h"
46 #include "iv.h"
47 #include "ivd.h"
48 #include "ihevcd_cxa.h"
49 #include "ithread.h"
50 
51 #include "ihevc_defs.h"
52 #include "ihevc_debug.h"
53 #include "ihevc_defs.h"
54 #include "ihevc_structs.h"
55 #include "ihevc_macros.h"
56 #include "ihevc_platform_macros.h"
57 #include "ihevc_cabac_tables.h"
58 
59 #include "ihevc_error.h"
60 #include "ihevc_common_tables.h"
61 
62 #include "ihevcd_trace.h"
63 #include "ihevcd_defs.h"
64 #include "ihevcd_function_selector.h"
65 #include "ihevcd_structs.h"
66 #include "ihevcd_error.h"
67 #include "ihevcd_nal.h"
68 #include "ihevcd_bitstream.h"
69 #include "ihevcd_job_queue.h"
70 #include "ihevcd_utils.h"
71 
72 #include "ihevc_deblk.h"
73 #include "ihevc_deblk_tables.h"
74 #include "ihevcd_profile.h"
75 #include "ihevcd_deblk.h"
76 #include "ihevcd_sao.h"
77 #include "ihevc_padding.h"
78 
ihevcd_ilf_pad_frame(deblk_ctxt_t * ps_deblk_ctxt,sao_ctxt_t * ps_sao_ctxt)79 void ihevcd_ilf_pad_frame(deblk_ctxt_t *ps_deblk_ctxt, sao_ctxt_t *ps_sao_ctxt)
80 {
81     sps_t *ps_sps;
82     slice_header_t *ps_slice_hdr;
83     codec_t *ps_codec;
84     WORD32 i4_ctb_x, i4_ctb_y;
85     WORD32 ctb_size;
86 
87     ps_sps = ps_deblk_ctxt->ps_sps;
88     ps_slice_hdr = ps_deblk_ctxt->ps_slice_hdr;
89     ps_codec = ps_deblk_ctxt->ps_codec;
90     ctb_size = (1 << ps_sps->i1_log2_ctb_size);
91 
92     for(i4_ctb_y = 0; i4_ctb_y < ps_sps->i2_pic_ht_in_ctb; i4_ctb_y++)
93     {
94         for(i4_ctb_x = 0; i4_ctb_x < ps_sps->i2_pic_wd_in_ctb; i4_ctb_x++)
95         {
96             WORD32 i4_is_last_ctb_x = 0;
97             WORD32 i4_is_last_ctb_y = 0;
98 
99             /*TODO:
100              *  Slice header also has to be updated
101              *  */
102             ps_deblk_ctxt->i4_ctb_x = i4_ctb_x;
103             ps_deblk_ctxt->i4_ctb_y = i4_ctb_y;
104 
105             ps_sao_ctxt->i4_ctb_x = i4_ctb_x;
106             ps_sao_ctxt->i4_ctb_y = i4_ctb_y;
107 
108             if((0 == ps_slice_hdr->i1_slice_disable_deblocking_filter_flag) &&
109                (0 == ps_codec->i4_disable_deblk_pic))
110             {
111                 ihevcd_deblk_ctb(ps_deblk_ctxt, i4_is_last_ctb_x, i4_is_last_ctb_y);
112 
113                 /* If the last CTB in the row was a complete CTB then deblocking has to be called from remaining pixels, since deblocking
114                  * is applied on a shifted CTB structure
115                  */
116                 if(i4_ctb_x == ps_sps->i2_pic_wd_in_ctb - 1)
117                 {
118                     WORD32 last_x_pos;
119                     i4_is_last_ctb_x = 1;
120                     i4_is_last_ctb_y = 0;
121 
122 
123                     last_x_pos = (ps_sps->i2_pic_wd_in_ctb << ps_sps->i1_log2_ctb_size);
124                     if(last_x_pos  ==  ps_sps->i2_pic_width_in_luma_samples)
125                     {
126                         ihevcd_deblk_ctb(ps_deblk_ctxt, i4_is_last_ctb_x, i4_is_last_ctb_y);
127                     }
128                 }
129 
130 
131                 /* If the last CTB in the column was a complete CTB then deblocking has to be called from remaining pixels, since deblocking
132                  * is applied on a shifted CTB structure
133                  */
134                 if(i4_ctb_y == ps_sps->i2_pic_ht_in_ctb - 1)
135                 {
136                     WORD32 last_y_pos;
137                     i4_is_last_ctb_y = 1;
138                     i4_is_last_ctb_x = 0;
139 
140                     last_y_pos = (ps_sps->i2_pic_ht_in_ctb << ps_sps->i1_log2_ctb_size);
141                     if(last_y_pos == ps_sps->i2_pic_height_in_luma_samples)
142                     {
143                         ihevcd_deblk_ctb(ps_deblk_ctxt, i4_is_last_ctb_x, i4_is_last_ctb_y);
144                     }
145                 }
146             }
147 
148             if(ps_slice_hdr->i1_slice_sao_luma_flag || ps_slice_hdr->i1_slice_sao_chroma_flag)
149             {
150                 ihevcd_sao_ctb(ps_sao_ctxt);
151             }
152 
153             /* Call padding if required */
154             {
155                 UWORD8 *pu1_cur_ctb_luma = ps_deblk_ctxt->pu1_cur_pic_luma
156                                 + (i4_ctb_x * ctb_size
157                                                 + i4_ctb_y * ctb_size
158                                                                 * ps_codec->i4_strd);
159                 UWORD8 *pu1_cur_ctb_chroma = ps_deblk_ctxt->pu1_cur_pic_chroma
160                                 + i4_ctb_x * ctb_size
161                                 + (i4_ctb_y * ctb_size * ps_codec->i4_strd / 2);
162 
163                 if(0 == i4_ctb_x)
164                 {
165                     WORD32 pad_ht_luma;
166                     WORD32 pad_ht_chroma;
167 
168                     pad_ht_luma = ctb_size;
169                     pad_ht_luma += (ps_sps->i2_pic_ht_in_ctb - 1) == i4_ctb_y ? 8 : 0;
170                     pad_ht_chroma = ctb_size / 2;
171                     pad_ht_chroma += (ps_sps->i2_pic_ht_in_ctb - 1) == i4_ctb_y ? 8 : 0;
172                     /* Pad left after 1st CTB is processed */
173                     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                     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                 }
176                 else if((ps_sps->i2_pic_wd_in_ctb - 1) == i4_ctb_x)
177                 {
178                     WORD32 pad_ht_luma;
179                     WORD32 pad_ht_chroma;
180                     WORD32 cols_remaining = ps_sps->i2_pic_width_in_luma_samples - (i4_ctb_x << ps_sps->i1_log2_ctb_size);
181 
182                     pad_ht_luma = ctb_size;
183                     pad_ht_luma += (ps_sps->i2_pic_ht_in_ctb - 1) == i4_ctb_y ? 8 : 0;
184                     pad_ht_chroma = ctb_size / 2;
185                     pad_ht_chroma += (ps_sps->i2_pic_ht_in_ctb - 1) == i4_ctb_y ? 8 : 0;
186                     /* Pad right after last CTB in the current row is processed */
187                     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                     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 
190 
191                     if((ps_sps->i2_pic_ht_in_ctb - 1) == i4_ctb_y)
192                     {
193                         UWORD8 *pu1_buf;
194                         /* Since SAO is shifted by 8x8, chroma padding can not be done till second row is processed */
195                         /* 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                         /* Pad top after padding left and right for current rows after processing 1st CTB row */
197                         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                         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 
200                         pu1_buf = ps_deblk_ctxt->pu1_cur_pic_luma + ps_codec->i4_strd * ps_sps->i2_pic_height_in_luma_samples - PAD_LEFT;
201                         /* Pad top after padding left and right for current rows after processing 1st CTB row */
202                         ihevc_pad_bottom(pu1_buf, ps_codec->i4_strd, ps_sps->i2_pic_width_in_luma_samples + PAD_WD, PAD_BOT);
203 
204                         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                         ihevc_pad_bottom(pu1_buf, ps_codec->i4_strd, ps_sps->i2_pic_width_in_luma_samples + PAD_WD, PAD_BOT / 2);
206                     }
207                 }
208             }
209 
210 
211         }
212     }
213 
214 }
215