Home | History | Annotate | Download | only in decoder
      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 
     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