1 /*! 2 * \copy 3 * Copyright (c) 2009-2013, Cisco Systems 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 21 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 22 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 23 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 24 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 26 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 28 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 * 31 * 32 * \file slice_segment.h 33 * 34 * \brief SSlice segment routine (Single slice/multiple slice/fmo arrangement exclusive) 35 * 36 * \date 2/4/2009 Created 37 * 38 ************************************************************************************* 39 */ 40 #ifndef WELS_SLICE_SEGMENT_H__ 41 #define WELS_SLICE_SEGMENT_H__ 42 43 #include "typedefs.h" 44 #include "macros.h" 45 #include "as264_common.h" 46 #include "memory_align.h" 47 48 #include "codec_app_def.h" 49 #include "set_mb_syn_cabac.h" 50 51 using namespace WelsCommon; 52 53 namespace WelsEnc { 54 55 56 // NOTE: 57 // if PREFIX_NALs are used in base layer(iDid=0, qid=0), MAX_SLICES_NUM will be half of MAX_NAL_UNITS_IN_LAYER in case ST or MT without PACKING_ONE_SLICE_PER_LAYER 58 // in case MT and PACKING_ONE_SLICE_PER_LAYER, MAX_SLICES_NUM should not be exceeding MAX_LAYER_NUM_OF_FRAME 59 // for AVC cases, maximal resolution we can support up to (?x1024) for SM_ROWMB_SLICE slice mode 60 // fine solution for MAX_SLICES_NUM, need us use the variable instead of MACRO for any resolution combining any multiple-slice mode adaptive 61 #define SAVED_NALUNIT_NUM ( (MAX_SPATIAL_LAYER_NUM*MAX_QUALITY_LAYER_NUM) + 1 + MAX_SPATIAL_LAYER_NUM ) // SPS/PPS + SEI/SSEI + PADDING_NAL 62 #define MAX_SLICES_NUM ( ( MAX_NAL_UNITS_IN_LAYER - SAVED_NALUNIT_NUM ) / 3 ) // Also MAX_SLICES_NUM need constrained by implementation: uiSliceIdc allocated in SSliceCtx.pOverallMbMap need a byte range as expected 63 #define AVERSLICENUM_CONSTRAINT (MAX_SLICES_NUM) // used in sNalList initialization, 64 65 #define MIN_NUM_MB_PER_SLICE 48 // (128/16 * 96/16), addressing the lowest resolution for multiple slicing is 128x96 above 66 67 #define DEFAULT_MAXPACKETSIZE_CONSTRAINT (1200) //in bytes 68 //#define MINPACKETSIZE_CONSTRAINT (1200) 69 70 #define AVER_MARGIN_BYTES ( 100 ) //in bytes 71 #define JUMPPACKETSIZE_CONSTRAINT(max_byte) ( max_byte - AVER_MARGIN_BYTES ) //in bytes 72 #define JUMPPACKETSIZE_JUDGE(len,mb_idx,max_byte) ( (len) > JUMPPACKETSIZE_CONSTRAINT(max_byte) ) //( (mb_idx+1)%40/*16slice for compare*/ == 0 ) // 73 //cur_mb_idx is for early tests, can be omit in optimization 74 typedef struct TagSlice SSlice; 75 typedef struct TagDqLayer SDqLayer; 76 typedef struct TagWelsEncCtx sWelsEncCtx; 77 /*! 78 * \brief SSlice context 79 */ 80 /* Single/multiple slices */ 81 typedef struct SlicepEncCtx_s { 82 SliceModeEnum uiSliceMode; /* 0: single slice in frame; 1: multiple slices in frame; */ 83 int16_t iMbWidth; /* width of picture size in mb */ 84 int16_t iMbHeight; /* height of picture size in mb */ 85 int32_t iSliceNumInFrame; /* count number of slices in frame; */ 86 int32_t iMbNumInFrame; /* count number of MBs in frame */ 87 uint16_t* pOverallMbMap; /* overall MB map in frame, store virtual slice idc; */ 88 uint32_t uiSliceSizeConstraint; /* in byte */ 89 int32_t iMaxSliceNumConstraint; /* maximal number of slices constraint */ 90 91 } SSliceCtx; 92 93 94 typedef struct TagDynamicSlicingStack { 95 int32_t iStartPos; 96 int32_t iCurrentPos; 97 98 uint8_t* pBsStackBufPtr; // current writing position 99 uint32_t uiBsStackCurBits; 100 int32_t iBsStackLeftBits; 101 102 SCabacCtx sStoredCabac; 103 int32_t iMbSkipRunStack; 104 uint8_t uiLastMbQp; 105 uint8_t* pRestoreBuffer; 106 } SDynamicSlicingStack; 107 108 /*! 109 * \brief Initialize Wels SSlice context (Single/multiple slices and FMO) 110 * 111 * \param pCurDq current layer which its SSlice context will be initialized 112 * \param bFmoUseFlag flag of using fmo 113 * \param iMbWidth MB width 114 * \param iMbHeight MB height 115 * \param uiSliceMode slice mode 116 * \param mul_slice_arg argument for multiple slice if it is applicable 117 * \param pPpsArg argument for pPps parameter 118 * 119 * \return 0 - successful; none 0 - failed; 120 */ 121 int32_t InitSlicePEncCtx (SDqLayer* pCurDq, 122 CMemoryAlign* pMa, 123 bool bFmoUseFlag, 124 int32_t iMbWidth, 125 int32_t iMbHeight, 126 SSliceArgument* pSliceArgument, 127 void* pPpsArg); 128 129 130 /*! 131 * \brief Uninitialize Wels SSlice context (Single/multiple slices and FMO) 132 * 133 * \param pCurDq curent layer which its SSlice context will be initialized 134 * 135 * \return NONE; 136 */ 137 void UninitSlicePEncCtx (SDqLayer* pCurDq, CMemoryAlign* pMa); 138 139 /*! 140 * \brief Get slice idc for given iMbXY (apply in Single/multiple slices and FMO) 141 * 142 * \param pCurDq current layer info 143 * \param kiMbXY MB xy index 144 * 145 * \return uiSliceIdc - successful; (uint8_t)(-1) - failed; 146 */ 147 uint16_t WelsMbToSliceIdc (SDqLayer* pCurDq, const int32_t kiMbXY); 148 149 /*! 150 * \brief Get first mb in slice/slice_group: uiSliceIdc (apply in Single/multiple slices and FMO) 151 * 152 * \param pCurLayer current layer 153 * \param kiSliceIdc slice idc 154 * 155 * \return first_mb - successful; -1 - failed; 156 */ 157 int32_t WelsGetFirstMbOfSlice (SDqLayer* pCurLayer, const int32_t kiSliceIdc); 158 159 /*! 160 * \brief Get successive mb to be processed in slice/slice_group: uiSliceIdc (apply in Single/multiple slices and FMO) 161 * 162 * \param pCurDq current layer info 163 * \param kiMbXY MB xy index 164 * 165 * \return next_mb - successful; -1 - failed; 166 */ 167 int32_t WelsGetNextMbOfSlice (SDqLayer* pCurDq, const int32_t kiMbXY); 168 169 /*! 170 * \brief Get previous mb to be processed in slice/slice_group: uiSliceIdc (apply in Single/multiple slices and FMO) 171 * 172 * \param pCurDq current layer info 173 * \param kiMbXY MB xy index 174 * 175 * \return prev_mb - successful; -1 - failed; 176 */ 177 int32_t WelsGetPrevMbOfSlice (SDqLayer* pCurDq, const int32_t kiMbXY); 178 179 /*! 180 * \brief Get number of mb in slice/slice_group: uiSliceIdc (apply in Single/multiple slices and FMO) 181 * 182 * \param pCurDq current layer info 183 * \param pSlice slice which request slice num 184 * \param kiSliceIdc slice/slice_group idc 185 * 186 * \return count_num_of_mb - successful; -1 - failed; 187 */ 188 int32_t WelsGetNumMbInSlice (SDqLayer* pCurDq, SSlice* pSlice, const int32_t kuiSliceIdc); 189 190 /*! 191 * Get slice count for multiple slice segment 192 * 193 */ 194 int32_t GetInitialSliceNum (SSliceArgument* pSliceArgument); 195 int32_t GetCurrentSliceNum (const SDqLayer* pCurDq); 196 SSlice* GetSliceByIndex(sWelsEncCtx* pCtx, const int32_t kiSliceIdc); 197 198 //checking valid para 199 int32_t DynamicMaxSliceNumConstraint (uint32_t uiMaximumNum, int32_t uiConsumedNum, uint32_t uiDulplicateTimes); 200 201 bool CheckFixedSliceNumMultiSliceSetting (const int32_t kiMbNumInFrame, SSliceArgument* pSliceArg); 202 bool CheckRasterMultiSliceSetting (const int32_t kiMbNumInFrame, SSliceArgument* pSliceArg); 203 bool CheckRowMbMultiSliceSetting (const int32_t kiMbWidth, SSliceArgument* pSliceArg); 204 205 bool GomValidCheckSliceNum (const int32_t kiMbWidth, const int32_t kiMbHeight, uint32_t* pSliceNum); 206 bool GomValidCheckSliceMbNum (const int32_t kiMbWidth, const int32_t kiMbHeight, SSliceArgument* pSliceArg); 207 //end of checking valid para 208 209 int32_t DynamicAdjustSlicePEncCtxAll (SDqLayer* pCurDq, 210 int32_t* pRunLength); 211 } 212 #endif//WELS_SLICE_SEGMENT_H__ 213