⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 deblock_ref.c

📁 deblocking 在SPI DSP上的优化代码,超级强
💻 C
📖 第 1 页 / 共 2 页
字号:
// -------------------------------------------------------------------// ?2005 Stream Processors, Inc.  All rights reserved.// This Software is the property of Stream Processors, Inc. (SPI) and// is Proprietary and Confidential.  It has been provided under// license for solely use in evaluating and/or developing code for a// stream processor device.  Any use of the Software to develop code// for a semiconductor device not manufactured by or for SPI is// prohibited.  Unauthorized use of this Software is strictly// prohibited.//// THIS SOFTWARE IS PROVIDED "AS IS".  NO WARRANTIES ARE GIVEN,// WHETHER EXPRESS, IMPLIED OR STATUTORY, INCLUDING WARRANTIES OR// MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE,// NONINFRINGEMENT AND TITLE.  RECIPIENT SHALL HAVE THE SOLE// RESPONSIBILITY FOR THE ADEQUATE PROTECTION AND BACK-UP OF ITS DATA// USED IN CONNECTION WITH THIS SOFTWARE. IN NO EVENT WILL SPI BE// LIABLE FOR ANY CONSEQUENTIAL DAMAGES WHATSOEVER, INCLUDING LOSS OF// DATA OR USE, LOST PROFITS OR ANY INCIDENTAL OR SPECIAL DAMAGES,// ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS// SOFTWARE, WHETHER IN ACTION OF CONTRACT OR TORT, INCLUDING// NEGLIGENCE.  SPI FURTHER DISCLAIMS ANY LIABILITY WHATSOEVER FOR// INFRINGEMENT OF ANY INTELLECTUAL PROPERTY RIGHTS OF ANY THIRD// PARTY.// -------------------------------------------------------------------//--------------------------------------------------------------------//  $File: //depot/main/software/demo/deblock/src/deblock_ref.c $//  $Revision: #1 $//  $DateTime: 2007/12/10 16:59:57 $////  Description://     Simplified implementation for loop filter (as compared to//     previous VSofts data structures).// //  Current version fully supports Baseline profile, but lacks support//  for the following Main Profile features: B-frames and Interlaced//  frames.//--------------------------------------------------------------------#include <stdio.h>#include <stdlib.h>#include <string.h>#include <assert.h>#include "spi_common.h"#include "encoder_tables.h"#include "mb_info.h"#include "encoder_context.h"//-------------------------------------------------------------------// Local defines, macros, and constants//-------------------------------------------------------------------#define CLIP0_255(x) (IClip(0, 255, (x)))#define  IClip(Min, Max, Val) (((Val)<(Min)) ? (Min) : (((Val)>(Max)) ? (Max) : (Val)))// Indexed with [direction][edge][4x4 block]//   direction: 0 - vertical, 1 - horizontal//   edge: 0-3, from left to right (dir = 0) or top to bottom (dir = 1)//   block: 0-3: which block within a particular edge, from top to//               bottom for dir=0, and left to right for dir=1.typedef unsigned char S_BOUNDARY_STRENGTH_REF[2][4][4];//#define DEBUG_OUTPUT#ifdef DEBUG_OUTPUTofstream dbgfile;#define DEBUG_FILENAME "new_lf.txt"#endif//-------------------------------------------------------------------// Local protocols//-------------------------------------------------------------------void CalcBoundaryStrength(S_BLK_MB_INFO *MBInfo,                          S_BLK_MB_INFO *MBInfoLeft,                          S_BLK_MB_INFO *MBInfoTop,                          S_BOUNDARY_STRENGTH_REF *BSRef,                          int disable_deblocking_filter_idc);void DeblockMB(S_BOUNDARY_STRENGTH_REF *BSRef,               int QPyCurr, int QPyLeft, int QPyTop,               int alpha_c0_offset,               int beta_offset,               yuv_frame_t *frame,               int MBx, int MBy,               int DontFilterVertEdges, int DontFilterHorzEdges);void EdgeLoopLuma(unsigned char* SrcPtr,                  unsigned char Strength[4],                  int QP,                  int AlphaC0Offset, int BetaOffset,                  int PtrInc, int inc);void EdgeLoopChroma(unsigned char* SrcPtr,                    unsigned char Strength[4],                    int QP,                    int AlphaC0Offset, int BetaOffset,                    int PtrInc, int inc);static void pad_deblock_out_frame(yuv_frame_t *in_out, int PadAmount);// Make BSRef a global var, useful for debuggingS_BOUNDARY_STRENGTH_REF *BSRef = NULL;#ifdef DEBUGunsigned char *qp_av_ref = NULL;#endif//====================================================================//   The main MB-filtering function.  The basic strategy is to//   translate all the information in the VSofts data structure that//   are passed to the function into a new simplified data structure.//--------------------------------------------------------------------void deblock_frame_ref(                       encoder_context_t *p_enc                       ){    // Read necessary information from encoder context struct (p_enc)    S_BLK_MB_INFO *pBlkMBInfo          = p_enc->pBlkMBInfo;    int disable_deblocking_filter_idc  = p_enc->loopfilter_params.disable_flag;    int slice_alpha_c0_offset          = p_enc->loopfilter_params.alpha_c0_offset;    int slice_beta_offset              = p_enc->loopfilter_params.beta_offset;    yuv_frame_t *frame                 = p_enc->pRecFrame; // Input & Output        // Do not access p_enc directly below this line    int MBNumX = frame->image_width>>4;    int MBNumY = frame->image_height>>4;    int MBcurr, MBcurrLeft, MBcurrTop;    int s, x, y, m, CurrStripSize;        // [UJK} Make a temporary assumption on strip size.  I expect it    // to be more like 100 for SP-16, but am setting it to a lower    // value here to increase testing of strip-mining code in the    // meantime.    int StripSize = 24;   // = getStripSize();    // The StripSize variable doesn't account for the extra boundary    // macroblock that needs to be processed in order to stitch    // together the filtering of two adjacent strips (See comments    // below on the "Main stream loop").  So we have to add +1 when we    // use this value in many places.    int NumStrips = (MBNumX / StripSize) + ((MBNumX % StripSize) ? 1 : 0);      BSRef = (S_BOUNDARY_STRENGTH_REF *)spi_malloc(MBNumX * MBNumY * sizeof(*BSRef));    if (!BSRef) {        spi_printf("Error allocating memory for loop filter boundary strength indices!!  Exiting...");        spi_exit(-1);    }#ifdef DEBUG    qp_av_ref = (unsigned char *)spi_malloc(MBNumX * MBNumY * 8);    if (!qp_av_ref) {        spi_printf("Error allocating memory for loop filter average qp indices!!  Exiting...");        spi_exit(-1);    }#endif            //  The computation is strip-mined such that a strip is a    //  consecutive group of macroblocks all on the same row.  The    //  StreamC code is written to process strips in vertical order,    //  rather than in row-major order.  That is, the loop processes    //  the strips contain the macroblocks at macroblock coordinates    //  (0,0) to (N,0), then (0,1) to (N,1), etc.  At this point, it    //  goes back to the top and process MB strips (N,0) to (2N-1,0),    //  then (2N,1) to (2N-1,1), and so on.  (Notice the overlap of    //  the Nth macroblock on each row in each pair of strips).    //    //  This overlap is needed because of the nature of the deblocking    //  algorithm described in the H.264 standard.  In order to    //  conform to the standard, if the last macroblock (call it    //  LastStripMB) is on the right edge of the image, no special    //  boundary conditions need to be handled.  If LastStripMB is in    //  the interior of the image, than only the vertical edges are    //  filtered for that macroblock.  In this case, when the strip    //  next to the current one is processed (i.e., the strip that    //  contains the macroblocks from LastStripMB to    //  LastStripMB+StripSize), only the horizontal edges will be    //  filtered for LastStripMB.  But notice that LastStripMB must be    //  processed by the kernel twice.  This is slightly inefficient,    //  but if the strips are large enough (say > 25    //  macroblocks/strip) this has a neglible impact on performance.    // Loop over row segments (each row segment is StripSize    // wide, though the last segment may be < StripSize wide)    for (s = 0; s < NumStrips; s++) {        // Calculate x macroblock coordinate for this strip        x = s * (StripSize);        // The last strip might be smaller than the rest        CurrStripSize = ((x + StripSize + 1) <= MBNumX) ? (StripSize+1) : (MBNumX-x);        for (y = 0 ; y < MBNumY ; y++ ) {            for (m = 0; m < CurrStripSize; m++) {                MBcurr = y*MBNumX + x + m;                MBcurrLeft = (m == 0) ? (MBcurr) : (MBcurr - 1);                MBcurrTop = (y == 0) ? (MBcurr) : (MBcurr - MBNumX);                                // Calculate boundary strengths for the macroblock                CalcBoundaryStrength(&pBlkMBInfo[MBcurr*BLOCKS_PER_MB],                                     &pBlkMBInfo[MBcurrLeft*BLOCKS_PER_MB],                                     &pBlkMBInfo[MBcurrTop*BLOCKS_PER_MB],                                     &BSRef[MBcurr],                                     disable_deblocking_filter_idc                                     );                                // Deblock the macroblock                DeblockMB(&BSRef[MBcurr],                          pBlkMBInfo[MBcurr*BLOCKS_PER_MB].QP,                          pBlkMBInfo[MBcurrLeft*BLOCKS_PER_MB].QP,                          pBlkMBInfo[MBcurrTop*BLOCKS_PER_MB].QP,                          slice_alpha_c0_offset,                          slice_beta_offset,                          frame,                          x + m, y,                          (s > 0) && (m == 0),                          (s < (NumStrips - 1)) && (m == (CurrStripSize - 1)));            }        }    }        pad_deblock_out_frame(p_enc->pRecFrame, REFERENCE_FRAME_PAD_AMT); // dec    spi_free(BSRef);#ifdef DEBUG    spi_free(qp_av_ref);#endif}//====================================================================void CalcBoundaryStrength//====================================================================//   Calculate the boundary strengths for all the edges for one//   Macroblock//--------------------------------------------------------------------( // Inputs S_BLK_MB_INFO *MBInfo, S_BLK_MB_INFO *MBInfoLeft, S_BLK_MB_INFO *MBInfoTop, // Output S_BOUNDARY_STRENGTH_REF *BSRef, // Inputs int disable_deblocking_filter_idc )//--------------------------------------------------------------------{    int d, i, j;    // Do edges in both directions (d=0: vertical; d=1: horizontal)    for (d = 0; d < 2; d++) {        S_BLK_MB_INFO *NeighborBlk = ((d == 0) ? MBInfoLeft : MBInfoTop);        int BlkIsIntra = ((MBInfo->Type == INTRA_LARGE_BLOCKS_MB_TYPE)                          || (MBInfo->Type == INTRA_SMALL_BLOCKS_MB_TYPE));        int NeighborIsIntra = ((NeighborBlk->Type == INTRA_LARGE_BLOCKS_MB_TYPE)                               || (NeighborBlk->Type == INTRA_SMALL_BLOCKS_MB_TYPE));        // Loop over four edges in a MB        for (i = 0; i < 4; i++) {                // loop over four 4x4 block positions along each edge in order            // to determine strength of filtering for each group of 4 pixel            // boundaries (all 4 pixel boundaries within a single 4x4 block            // position all use the same strength)            for (j = 0; j < 4; j++) {                // indices into MV[y][x] and CBP[y][x] arrays                int pXidx = ((d == 0) ? i-1 : j  );                int pYidx = ((d == 0) ? j   : i-1);                int qXidx = ((d == 0) ? i   : j  );                int qYidx = ((d == 0) ? j   : i  );                // If this is 4x4 block is on the macroblock edge,                // calculate the appropriate index into the                // neighboring macroblock's 2-D array of 4x4 blocks.                int NeighborX = (d == 0) ? 3 : j;                int NeighborY = (d == 1) ? 3 : j;                // Get p_Blk and q_Blk                S_BLK_MB_INFO p_Blk = ((i == 0)                                       ? NeighborBlk[NeighborY*4 + NeighborX]                                       : MBInfo[pYidx*4 + pXidx]);                S_BLK_MB_INFO q_Blk = MBInfo[qYidx*4 + qXidx];                // Get MVs for each 4x4 block to the left and above                S_MV pMV = p_Blk.MV;                S_MV qMV = q_Blk.MV;                // Get Reference frames for each 4x4 block to the left and above                int pRef = p_Blk.RefFrameIdx;                int qRef = q_Blk.RefFrameIdx;                // Check for coded coefficients in each 4x4 block to the left and above                int pCodedCoeffs = (p_Blk.TotalCoeffLuma != 0);                int qCodedCoeffs = (q_Blk.TotalCoeffLuma != 0);                // Calculate boundary strength (bS)                if ((i == 0) && (NeighborIsIntra || BlkIsIntra))                {                    (*BSRef)[d][i][j] = 4;                }                else if (BlkIsIntra)                {                    (*BSRef)[d][i][j] = 3;                }                else if (pCodedCoeffs || qCodedCoeffs)                {                    (*BSRef)[d][i][j] = 2;                }                else if ((pRef != qRef)                         || ((abs(pMV.x - qMV.x) >= 4)                             || (abs(pMV.y - qMV.y) >= 4)))                {                    (*BSRef)[d][i][j] = 1;                }                else                {                    (*BSRef)[d][i][j] = 0;                }                // check boundary conditions                if (                    // Check for left picture edge                    ((d == 0) && (i == 0) && (MBInfo->Loc & LOC_MB_LEFT_PICTURE_EDGE))                    // Check for top picture edge                    || ((d == 1) && (i == 0) && (MBInfo->Loc & LOC_MB_TOP_PICTURE_EDGE))                    // Check for disable_deblocking_filter_idc                    || (disable_deblocking_filter_idc == 1)                     // Check for slice edge                    || ((disable_deblocking_filter_idc == 2)                        && (((d == 0) && (i == 0) && (MBInfo->Loc & LOC_MB_LEFT_SLICE_EDGE))                            || ((d == 1) && (i == 0) && (MBInfo->Loc & LOC_MB_TOP_SLICE_EDGE))))                    )                {                    (*BSRef)[d][i][j] = 0;                }            }  // for (j...        }  // for (i...    }  // for (d...}//====================================================================void DeblockMB//====================================================================//   Filter (deblock) a single macroblock//--------------------------------------------------------------------( S_BOUNDARY_STRENGTH_REF *BSRef, int QPyCurr, int QPyLeft, int QPyTop, int alpha_c0_offset, int beta_offset, yuv_frame_t *frame, int MBx, int MBy, int DontFilterVertEdges, int DontFilterHorzEdges )//--------------------------------------------------------------------{    int d, i;    int img_width, img_height;    int buf_width, buf_height;    unsigned char *y,*u, *v;    buf_width  = frame->width;    buf_height = frame->height;    img_width  = frame->image_width;    img_height = frame->image_height;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -