Showing the changes to codec/encoder/core/src/au_set.cpp (1 of 308 files). Show all
Unified · Split
| @@ -0,0 +1,514 @@ | ||
| 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 au_set.c | |
| 33 | + * | |
| 34 | + * \brief Interfaces introduced in Access Unit level based writer | |
| 35 | + * | |
| 36 | + * \date 05/18/2009 Created | |
| 37 | + * | |
| 38 | + ************************************************************************************* | |
| 39 | + */ | |
| 40 | + | |
| 41 | +#include <string.h> | |
| 42 | +#include <assert.h> | |
| 43 | +#include "au_set.h" | |
| 44 | +#include "svc_enc_golomb.h" | |
| 45 | +namespace WelsSVCEnc { | |
| 46 | +static const uint32_t g_kuiMaxDPBx2AtLevel[52] = // *2 on the basic of Annex A, Table A-1, for int32_t type | |
| 47 | +{ | |
| 48 | + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, //0~9 | |
| 49 | + 297, 675, 1782, 1782, 0, 0, 0, 0, 0, 0, //10, 11, 12, 13 | |
| 50 | + 1782, 3564, 6075, 0, 0, 0, 0, 0, 0, 0, //20, 21, 22 | |
| 51 | + 6075, 13500, 15360, 0, 0, 0, 0, 0, 0, 0, //30, 31, 32 | |
| 52 | + 24576, 24576, 26112, 0, 0, 0, 0, 0, 0, 0, //40, 41, 42 | |
| 53 | + 82800, 138240 //50, 51 | |
| 54 | +}; | |
| 55 | + | |
| 56 | + | |
| 57 | +#define LEVEL_NUMBER 16 | |
| 58 | + | |
| 59 | +typedef struct TagLevelLimit | |
| 60 | +{ | |
| 61 | + uint8_t iLevelIdc; | |
| 62 | + uint32_t uiMaxMbPS; // Max MBs processing speed | |
| 63 | + uint32_t uiMaxFS; // Max Frame size | |
| 64 | + uint32_t uiMaxDPBMB; //Max DPB MB Size | |
| 65 | + uint32_t uiMaxBR; //Max Bitrate | |
| 66 | +} SLevelLimit; | |
| 67 | + | |
| 68 | +const SLevelLimit g_ksLevelLimit[LEVEL_NUMBER] = | |
| 69 | +{ | |
| 70 | + { 10, 1485, 99, 396, 64 }, //10 | |
| 71 | + { 9, 1485, 99, 396, 128 }, //9 (1b) | |
| 72 | + { 11, 3000, 396, 900, 192 }, //11 | |
| 73 | + { 12, 6000, 396, 2376, 384 }, //12 | |
| 74 | + { 13, 11880, 396, 2376, 768 }, //13 | |
| 75 | + | |
| 76 | + { 20, 11880, 396, 2376, 2000 }, //20 | |
| 77 | + { 21, 19800, 792, 4752, 4000 }, //21 | |
| 78 | + { 22, 20250, 1620, 8100, 4000 }, //22 | |
| 79 | + | |
| 80 | + { 30, 40500, 1620, 8100, 10000 }, //30 | |
| 81 | + { 31, 108000, 3600, 18000, 14000 }, //31 | |
| 82 | + { 32, 216000, 5120, 20480, 20000 }, //32 | |
| 83 | + | |
| 84 | + { 40, 245760, 8192, 32768, 20000 }, //40 | |
| 85 | + { 41, 245760, 8192, 32768, 50000 }, //41 | |
| 86 | + { 42, 491520, 8192, 34816, 50000 }, //42 | |
| 87 | + | |
| 88 | + { 50, 589824, 22080, 110400, 135000 }, //50 | |
| 89 | + { 51, 983040, 36864, 184320, 240000 } //51 | |
| 90 | +}; | |
| 91 | + | |
| 92 | +static inline int32_t WelsCheckLevelLimitation( const SWelsSPS* kpSps, const SLevelLimit *kpLevelLimit, float fFrameRate, int32_t iTargetBitRate ) | |
| 93 | +{ | |
| 94 | + uint32_t uiPicWidthInMBs = kpSps->iMbWidth; | |
| 95 | + uint32_t uiPicHeightInMBs = kpSps->iMbHeight; | |
| 96 | + uint32_t uiPicInMBs = uiPicWidthInMBs * uiPicHeightInMBs; | |
| 97 | + uint32_t uiNumRefFrames = kpSps->iNumRefFrames; | |
| 98 | + | |
| 99 | + if( kpLevelLimit->uiMaxMbPS < ( uint32_t ) ( uiPicInMBs * fFrameRate ) ) | |
| 100 | + return 0; | |
| 101 | + if( kpLevelLimit->uiMaxFS < uiPicInMBs ) | |
| 102 | + return 0; | |
| 103 | + if( ( kpLevelLimit->uiMaxFS << 3 ) < ( uiPicWidthInMBs * uiPicWidthInMBs ) ) | |
| 104 | + return 0; | |
| 105 | + if( ( kpLevelLimit->uiMaxFS << 3 ) < ( uiPicHeightInMBs * uiPicHeightInMBs ) ) | |
| 106 | + return 0; | |
| 107 | + if( kpLevelLimit->uiMaxDPBMB < uiNumRefFrames * uiPicInMBs ) | |
| 108 | + return 0; | |
| 109 | + if( iTargetBitRate && ( (int32_t) kpLevelLimit->uiMaxBR * 1200 ) < iTargetBitRate ) //RC enabled, considering bitrate constraint | |
| 110 | + return 0; | |
| 111 | + //add more checks here if needed in future | |
| 112 | + | |
| 113 | + return 1; | |
| 114 | + | |
| 115 | +} | |
| 116 | + | |
| 117 | +static inline int32_t WelsGetLevelIdc( const SWelsSPS* kpSps, float fFrameRate, int32_t iTargetBitRate ) | |
| 118 | +{ | |
| 119 | + int32_t iOrder; | |
| 120 | + for( iOrder = 0; iOrder < LEVEL_NUMBER; iOrder++ ) | |
| 121 | + { | |
| 122 | + if( WelsCheckLevelLimitation(kpSps, &(g_ksLevelLimit[iOrder]), fFrameRate, iTargetBitRate) ) | |
| 123 | + { | |
| 124 | + return (int32_t) ( g_ksLevelLimit[iOrder].iLevelIdc ); | |
| 125 | + } | |
| 126 | + } | |
| 127 | + return 51; //final decision: select the biggest level | |
| 128 | +} | |
| 129 | + | |
| 130 | + | |
| 131 | +/*! | |
| 132 | + ************************************************************************************* | |
| 133 | + * \brief to set Sequence Parameter Set (SPS) | |
| 134 | + * | |
| 135 | + * \param pSps SWelsSPS to be wrote, update iSpsId dependency | |
| 136 | + * \param pBitStringAux bitstream writer auxiliary | |
| 137 | + * | |
| 138 | + * \return 0 - successed | |
| 139 | + * 1 - failed | |
| 140 | + * | |
| 141 | + * \note Call it in case EWelsNalUnitType is SPS. | |
| 142 | + ************************************************************************************* | |
| 143 | + */ | |
| 144 | +int32_t WelsWriteSpsSyntax( SWelsSPS *pSps, SBitStringAux *pBitStringAux, int32_t* pSpsIdDelta ) | |
| 145 | +{ | |
| 146 | + SBitStringAux *pLocalBitStringAux = pBitStringAux; | |
| 147 | + | |
| 148 | + assert( pSps != NULL && pBitStringAux != NULL ); | |
| 149 | + | |
| 150 | + BsWriteBits( pLocalBitStringAux, 8, pSps->uiProfileIdc ); | |
| 151 | + | |
| 152 | + BsWriteOneBit( pLocalBitStringAux, pSps->bConstraintSet0Flag ); // bConstraintSet0Flag | |
| 153 | + BsWriteOneBit( pLocalBitStringAux, pSps->bConstraintSet1Flag ); // bConstraintSet1Flag | |
| 154 | + BsWriteOneBit( pLocalBitStringAux, pSps->bConstraintSet2Flag ); // bConstraintSet2Flag | |
| 155 | + BsWriteOneBit( pLocalBitStringAux, 0/*pSps->bConstraintSet3Flag*/ ); // bConstraintSet3Flag | |
| 156 | + BsWriteBits( pLocalBitStringAux, 4, 0 ); // reserved_zero_4bits, equal to 0 | |
| 157 | + BsWriteBits( pLocalBitStringAux, 8, pSps->iLevelIdc ); // iLevelIdc | |
| 158 | + BsWriteUE( pLocalBitStringAux, pSps->uiSpsId + pSpsIdDelta[pSps->uiSpsId] ); // seq_parameter_set_id | |
| 159 | + | |
| 160 | + if ( PRO_SCALABLE_BASELINE == pSps->uiProfileIdc || PRO_SCALABLE_HIGH == pSps->uiProfileIdc || | |
| 161 | + PRO_HIGH == pSps->uiProfileIdc || PRO_HIGH10 == pSps->uiProfileIdc || | |
| 162 | + PRO_HIGH422 == pSps->uiProfileIdc || PRO_HIGH444 == pSps->uiProfileIdc || | |
| 163 | + PRO_CAVLC444 == pSps->uiProfileIdc || 44 == pSps->uiProfileIdc ) | |
| 164 | + { | |
| 165 | + BsWriteUE( pLocalBitStringAux, 1 ); //uiChromaFormatIdc, now should be 1 | |
| 166 | + BsWriteUE( pLocalBitStringAux, 0); //uiBitDepthLuma | |
| 167 | + BsWriteUE( pLocalBitStringAux, 0); //uiBitDepthChroma | |
| 168 | + BsWriteOneBit( pLocalBitStringAux, 0); //qpprime_y_zero_transform_bypass_flag | |
| 169 | + BsWriteOneBit( pLocalBitStringAux, 0); //seq_scaling_matrix_present_flag | |
| 170 | + } | |
| 171 | + | |
| 172 | + BsWriteUE( pLocalBitStringAux, pSps->uiLog2MaxFrameNum - 4 ); // log2_max_frame_num_minus4 | |
| 173 | + BsWriteUE( pLocalBitStringAux, 0/*pSps->uiPocType*/ ); // pic_order_cnt_type | |
| 174 | + BsWriteUE( pLocalBitStringAux, pSps->iLog2MaxPocLsb - 4 ); // log2_max_pic_order_cnt_lsb_minus4 | |
| 175 | + | |
| 176 | + BsWriteUE( pLocalBitStringAux, pSps->iNumRefFrames ); // max_num_ref_frames | |
| 177 | + BsWriteOneBit( pLocalBitStringAux, true/*pSps->bGapsInFrameNumValueAllowedFlag*/ ); // bGapsInFrameNumValueAllowedFlag | |
| 178 | + BsWriteUE( pLocalBitStringAux, pSps->iMbWidth - 1 ); // pic_width_in_mbs_minus1 | |
| 179 | + BsWriteUE( pLocalBitStringAux, pSps->iMbHeight - 1 ); // pic_height_in_map_units_minus1 | |
| 180 | + BsWriteOneBit( pLocalBitStringAux, true/*pSps->bFrameMbsOnlyFlag*/ ); // bFrameMbsOnlyFlag | |
| 181 | + | |
| 182 | + BsWriteOneBit( pLocalBitStringAux, 0/*pSps->bDirect8x8InferenceFlag*/ ); // direct_8x8_inference_flag | |
| 183 | + BsWriteOneBit( pLocalBitStringAux, pSps->bFrameCroppingFlag ); // bFrameCroppingFlag | |
| 184 | + if ( pSps->bFrameCroppingFlag ) | |
| 185 | + { | |
| 186 | + BsWriteUE( pLocalBitStringAux, pSps->sFrameCrop.iCropLeft ); // frame_crop_left_offset | |
| 187 | + BsWriteUE( pLocalBitStringAux, pSps->sFrameCrop.iCropRight ); // frame_crop_right_offset | |
| 188 | + BsWriteUE( pLocalBitStringAux, pSps->sFrameCrop.iCropTop ); // frame_crop_top_offset | |
| 189 | + BsWriteUE( pLocalBitStringAux, pSps->sFrameCrop.iCropBottom ); // frame_crop_bottom_offset | |
| 190 | + } | |
| 191 | + | |
| 192 | + BsWriteOneBit( pLocalBitStringAux, 0/*pSps->bVuiParamPresentFlag*/ ); // vui_parameters_present_flag | |
| 193 | + | |
| 194 | + return 0; | |
| 195 | +} | |
| 196 | + | |
| 197 | + | |
| 198 | +int32_t WelsWriteSpsNal( SWelsSPS *pSps, SBitStringAux *pBitStringAux, int32_t* pSpsIdDelta) | |
| 199 | +{ | |
| 200 | + WelsWriteSpsSyntax( pSps, pBitStringAux, pSpsIdDelta ); | |
| 201 | + | |
| 202 | + BsRbspTrailingBits( pBitStringAux ); | |
| 203 | + | |
| 204 | + BsFlush( pBitStringAux ); | |
| 205 | + | |
| 206 | + return 0; | |
| 207 | +} | |
| 208 | + | |
| 209 | +/*! | |
| 210 | + ************************************************************************************* | |
| 211 | + * \brief to write SubSet Sequence Parameter Set | |
| 212 | + * | |
| 213 | + * \param sub_sps subset pSps parsed | |
| 214 | + * \param pBitStringAux bitstream writer auxiliary | |
| 215 | + * | |
| 216 | + * \return 0 - successed | |
| 217 | + * 1 - failed | |
| 218 | + * | |
| 219 | + * \note Call it in case EWelsNalUnitType is SubSet SPS. | |
| 220 | + ************************************************************************************* | |
| 221 | + */ | |
| 222 | + | |
| 223 | +int32_t WelsWriteSubsetSpsSyntax( SSubsetSps *pSubsetSps, SBitStringAux *pBitStringAux , int32_t* pSpsIdDelta ) | |
| 224 | +{ | |
| 225 | + SWelsSPS *pSps = &pSubsetSps->pSps; | |
| 226 | + | |
| 227 | + WelsWriteSpsSyntax( pSps, pBitStringAux, pSpsIdDelta ); | |
| 228 | + | |
| 229 | + if ( pSps->uiProfileIdc == PRO_SCALABLE_BASELINE || pSps->uiProfileIdc == PRO_SCALABLE_HIGH ){ | |
| 230 | + SSpsSvcExt *pSubsetSpsExt = &pSubsetSps->sSpsSvcExt; | |
| 231 | + | |
| 232 | + BsWriteOneBit( pBitStringAux, true/*pSubsetSpsExt->bInterLayerDeblockingFilterCtrlPresentFlag*/ ); | |
| 233 | + BsWriteBits( pBitStringAux, 2, pSubsetSpsExt->iExtendedSpatialScalability ); | |
| 234 | + BsWriteOneBit( pBitStringAux, 0/*pSubsetSpsExt->uiChromaPhaseXPlus1Flag*/ ); | |
| 235 | + BsWriteBits( pBitStringAux, 2, 1/*pSubsetSpsExt->uiChromaPhaseYPlus1*/ ); | |
| 236 | + if ( pSubsetSpsExt->iExtendedSpatialScalability == 1 ){ | |
| 237 | + BsWriteOneBit( pBitStringAux, 0/*pSubsetSpsExt->uiSeqRefLayerChromaPhaseXPlus1Flag*/ ); | |
| 238 | + BsWriteBits( pBitStringAux, 2, 1/*pSubsetSpsExt->uiSeqRefLayerChromaPhaseYPlus1*/ ); | |
| 239 | + BsWriteSE( pBitStringAux, 0/*pSubsetSpsExt->sSeqScaledRefLayer.left_offset*/ ); | |
| 240 | + BsWriteSE( pBitStringAux, 0/*pSubsetSpsExt->sSeqScaledRefLayer.top_offset*/ ); | |
| 241 | + BsWriteSE( pBitStringAux, 0/*pSubsetSpsExt->sSeqScaledRefLayer.right_offset*/ ); | |
| 242 | + BsWriteSE( pBitStringAux, 0/*pSubsetSpsExt->sSeqScaledRefLayer.bottom_offset*/ ); | |
| 243 | + } | |
| 244 | + BsWriteOneBit( pBitStringAux, pSubsetSpsExt->bSeqTcoeffLevelPredFlag ); | |
| 245 | + if ( pSubsetSpsExt->bSeqTcoeffLevelPredFlag ){ | |
| 246 | + BsWriteOneBit( pBitStringAux, pSubsetSpsExt->bAdaptiveTcoeffLevelPredFlag ); | |
| 247 | + } | |
| 248 | + BsWriteOneBit( pBitStringAux, pSubsetSpsExt->bSliceHeaderRestrictionFlag ); | |
| 249 | + | |
| 250 | + BsWriteOneBit( pBitStringAux, false/*pSubsetSps->bSvcVuiParamPresentFlag*/ ); | |
| 251 | + } | |
| 252 | + BsWriteOneBit( pBitStringAux, false/*pSubsetSps->bAdditionalExtension2Flag*/ ); | |
| 253 | + | |
| 254 | + BsRbspTrailingBits( pBitStringAux ); | |
| 255 | + | |
| 256 | + BsFlush( pBitStringAux ); | |
| 257 | + | |
| 258 | + return 0; | |
| 259 | +} | |
| 260 | + | |
| 261 | +/*! | |
| 262 | + ************************************************************************************* | |
| 263 | + * \brief to write Picture Parameter Set (PPS) | |
| 264 | + * | |
| 265 | + * \param pPps pPps | |
| 266 | + * \param pBitStringAux bitstream writer auxiliary | |
| 267 | + * | |
| 268 | + * \return 0 - successed | |
| 269 | + * 1 - failed | |
| 270 | + * | |
| 271 | + * \note Call it in case EWelsNalUnitType is PPS. | |
| 272 | + ************************************************************************************* | |
| 273 | + */ | |
| 274 | +int32_t WelsWritePpsSyntax( SWelsPPS *pPps, SBitStringAux *pBitStringAux, SParaSetOffset* sPSOVector ) | |
| 275 | +{ | |
| 276 | + SBitStringAux * pLocalBitStringAux = pBitStringAux; | |
| 277 | + | |
| 278 | + bool_t bUsedSubset = sPSOVector->bPpsIdMappingIntoSubsetsps[pPps->iPpsId]; | |
| 279 | + int32_t iParameterSetType = ( bUsedSubset ? PARA_SET_TYPE_SUBSETSPS : PARA_SET_TYPE_AVCSPS ); | |
| 280 | + | |
| 281 | + BsWriteUE( pLocalBitStringAux, pPps->iPpsId + sPSOVector->sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[pPps->iPpsId] ); | |
| 282 | + BsWriteUE( pLocalBitStringAux, pPps->iSpsId + sPSOVector->sParaSetOffsetVariable[iParameterSetType].iParaSetIdDelta[pPps->iSpsId] ); | |
| 283 | + | |
| 284 | +#if _DEBUG | |
| 285 | + //SParaSetOffset use, 110421 | |
| 286 | + if ( sPSOVector->bEnableSpsPpsIdAddition ) | |
| 287 | + { | |
| 288 | + const int32_t kiTmpSpsIdInBs = pPps->iSpsId + sPSOVector->sParaSetOffsetVariable[iParameterSetType].iParaSetIdDelta[pPps->iSpsId]; | |
| 289 | + const int32_t tmp_pps_id_in_bs = pPps->iPpsId + sPSOVector->sParaSetOffsetVariable[PARA_SET_TYPE_PPS].iParaSetIdDelta[pPps->iPpsId]; | |
| 290 | + assert ( MAX_SPS_COUNT > kiTmpSpsIdInBs ); | |
| 291 | + assert ( MAX_PPS_COUNT > tmp_pps_id_in_bs ); | |
| 292 | + assert( sPSOVector->sParaSetOffsetVariable[iParameterSetType].bUsedParaSetIdInBs[kiTmpSpsIdInBs] ); | |
| 293 | + } | |
| 294 | +#endif | |
| 295 | + | |
| 296 | + BsWriteOneBit( pLocalBitStringAux, false/*pPps->entropy_coding_mode_flag*/ ); | |
| 297 | + BsWriteOneBit( pLocalBitStringAux, false/*pPps->bPicOrderPresentFlag*/ ); | |
| 298 | + | |
| 299 | +#ifdef DISABLE_FMO_FEATURE | |
| 300 | + BsWriteUE( pLocalBitStringAux, 0/*pPps->uiNumSliceGroups - 1*/ ); | |
| 301 | +#else | |
| 302 | + BsWriteUE( pLocalBitStringAux, pPps->uiNumSliceGroups - 1 ); | |
| 303 | + if ( pPps->uiNumSliceGroups > 1 ) | |
| 304 | + { | |
| 305 | + uint32_t i, uiNumBits; | |
| 306 | + | |
| 307 | + BsWriteUE( pLocalBitStringAux, pPps->uiSliceGroupMapType ); | |
| 308 | + | |
| 309 | + switch ( pPps->uiSliceGroupMapType ) | |
| 310 | + { | |
| 311 | + case 0: | |
| 312 | + for ( i = 0; i < pPps->uiNumSliceGroups; i ++ ) | |
| 313 | + { | |
| 314 | + BsWriteUE( pLocalBitStringAux, pPps->uiRunLength[i] - 1 ); | |
| 315 | + } | |
| 316 | + break; | |
| 317 | + case 2: | |
| 318 | + for ( i = 0; i < pPps->uiNumSliceGroups; i ++ ) | |
| 319 | + { | |
| 320 | + BsWriteUE( pLocalBitStringAux, pPps->uiTopLeft[i] ); | |
| 321 | + BsWriteUE( pLocalBitStringAux, pPps->uiBottomRight[i] ); | |
| 322 | + } | |
| 323 | + break; | |
| 324 | + case 3: | |
| 325 | + case 4: | |
| 326 | + case 5: | |
| 327 | + BsWriteOneBit( pLocalBitStringAux, pPps->bSliceGroupChangeDirectionFlag ); | |
| 328 | + BsWriteUE( pLocalBitStringAux, pPps->uiSliceGroupChangeRate - 1 ); | |
| 329 | + break; | |
| 330 | + case 6: | |
| 331 | + BsWriteUE( pLocalBitStringAux, pPps->uiPicSizeInMapUnits - 1 ); | |
| 332 | + uiNumBits = 0;///////////////////WELS_CEILLOG2(pPps->uiPicSizeInMapUnits); | |
| 333 | + for ( i = 0; i < pPps->uiPicSizeInMapUnits; i ++ ) | |
| 334 | + { | |
| 335 | + BsWriteBits( pLocalBitStringAux, uiNumBits, pPps->uiSliceGroupId[i] ); | |
| 336 | + } | |
| 337 | + break; | |
| 338 | + default: | |
| 339 | + break; | |
| 340 | + } | |
| 341 | + } | |
| 342 | +#endif//!DISABLE_FMO_FEATURE | |
| 343 | + | |
| 344 | + BsWriteUE( pLocalBitStringAux, 0/*pPps->uiNumRefIdxL0Active - 1*/ ); | |
| 345 | + BsWriteUE( pLocalBitStringAux, 0/*pPps->uiNumRefIdxL1Active - 1*/ ); | |
| 346 | + | |
| 347 | + | |
| 348 | + BsWriteOneBit( pLocalBitStringAux, false/*pPps->bWeightedPredFlag*/ ); | |
| 349 | + BsWriteBits (pLocalBitStringAux, 2, 0/*pPps->uiWeightedBiPredIdc*/ ); | |
| 350 | + | |
| 351 | + BsWriteSE( pLocalBitStringAux, pPps->iPicInitQp - 26 ); | |
| 352 | + BsWriteSE( pLocalBitStringAux, pPps->iPicInitQs - 26 ); | |
| 353 | + | |
| 354 | + BsWriteSE( pLocalBitStringAux, pPps->uiChromaQpIndexOffset ); | |
| 355 | + BsWriteOneBit( pLocalBitStringAux, pPps->bDeblockingFilterControlPresentFlag ); | |
| 356 | + BsWriteOneBit( pLocalBitStringAux, false/*pPps->bConstainedIntraPredFlag*/ ); | |
| 357 | + BsWriteOneBit( pLocalBitStringAux, false/*pPps->bRedundantPicCntPresentFlag*/ ); | |
| 358 | + | |
| 359 | + BsRbspTrailingBits( pLocalBitStringAux ); | |
| 360 | + | |
| 361 | + BsFlush( pLocalBitStringAux ); | |
| 362 | + | |
| 363 | + return 0; | |
| 364 | +} | |
| 365 | + | |
| 366 | +static inline bool_t WelsGetPaddingOffset(int32_t iActualWidth, int32_t iActualHeight, int32_t iWidth, int32_t iHeight, SCropOffset &pOffset) | |
| 367 | +{ | |
| 368 | + if( (iWidth < iActualWidth) || (iHeight < iActualHeight) ) | |
| 369 | + return false; | |
| 370 | + | |
| 371 | + // make actual size even | |
| 372 | + iActualWidth -= (iActualWidth & 1); | |
| 373 | + iActualHeight -= (iActualHeight & 1); | |
| 374 | + | |
| 375 | + pOffset.iCropLeft = 0; | |
| 376 | + pOffset.iCropRight = (iWidth - iActualWidth)/2; | |
| 377 | + pOffset.iCropTop = 0; | |
| 378 | + pOffset.iCropBottom = (iHeight - iActualHeight)/2; | |
| 379 | + | |
| 380 | + return (iWidth>iActualWidth) || (iHeight>iActualHeight); | |
| 381 | +} | |
| 382 | + | |
| 383 | +int32_t WelsInitSps( SWelsSPS *pSps, SDLayerParam *pLayerParam, const uint32_t kuiIntraPeriod, const int32_t kiNumRefFrame, | |
| 384 | + const uint32_t kuiSpsId, const bool_t kbEnableFrameCropping, bool_t bEnableRc ) | |
| 385 | +{ | |
| 386 | + memset(pSps, 0, sizeof(SWelsSPS)); | |
| 387 | + | |
| 388 | + pSps->uiSpsId = kuiSpsId; | |
| 389 | + pSps->iMbWidth = (pLayerParam->iFrameWidth+15) >> 4; | |
| 390 | + pSps->iMbHeight = (pLayerParam->iFrameHeight+15) >> 4; | |
| 391 | + | |
| 392 | + if ( 0 == kuiIntraPeriod ) | |
| 393 | + { | |
| 394 | + //max value of both iFrameNum and POC are 2^16-1, in our encoder, iPOC=2*iFrameNum, so max of iFrameNum should be 2^15-1.-- | |
| 395 | + pSps->uiLog2MaxFrameNum = 15;//16; | |
| 396 | + } | |
| 397 | + else | |
| 398 | + { | |
| 399 | + pSps->uiLog2MaxFrameNum = 4; | |
| 400 | + while ( (uint32_t)(1 << pSps->uiLog2MaxFrameNum) <= kuiIntraPeriod ) { | |
| 401 | + ++ pSps->uiLog2MaxFrameNum; | |
| 402 | + } | |
| 403 | + } | |
| 404 | + pSps->iLog2MaxPocLsb = 1 + pSps->uiLog2MaxFrameNum; | |
| 405 | + | |
| 406 | + pSps->iNumRefFrames = kiNumRefFrame; /* min pRef size when fifo pRef operation*/ | |
| 407 | + | |
| 408 | + if ( kbEnableFrameCropping ) | |
| 409 | + { | |
| 410 | + // TODO: get frame_crop_left_offset, frame_crop_right_offset, frame_crop_top_offset, frame_crop_bottom_offset | |
| 411 | + pSps->bFrameCroppingFlag = WelsGetPaddingOffset( pLayerParam->iActualWidth, pLayerParam->iActualHeight, pLayerParam->iFrameWidth, pLayerParam->iFrameHeight, pSps->sFrameCrop ); | |
| 412 | + } | |
| 413 | + else | |
| 414 | + { | |
| 415 | + pSps->bFrameCroppingFlag = false; | |
| 416 | + } | |
| 417 | + | |
| 418 | + pSps->uiProfileIdc = pLayerParam->uiProfileIdc ? pLayerParam->uiProfileIdc : PRO_BASELINE; | |
| 419 | + | |
| 420 | + if( bEnableRc ) //fixed QP condition | |
| 421 | + pSps->iLevelIdc = WelsGetLevelIdc(pSps, pLayerParam->fOutputFrameRate, pLayerParam->iSpatialBitrate); | |
| 422 | + else | |
| 423 | + pSps->iLevelIdc = WelsGetLevelIdc(pSps, pLayerParam->fOutputFrameRate, 0); // Set tar_br = 0 to remove the bitrate constraint; a better way is to set actual tar_br as 0 | |
| 424 | + | |
| 425 | + return 0; | |
| 426 | +} | |
| 427 | + | |
| 428 | + | |
| 429 | +int32_t WelsInitSubsetSps( SSubsetSps *pSubsetSps, SDLayerParam *pLayerParam, const uint32_t kuiIntraPeriod, const int32_t kiNumRefFrame, | |
| 430 | + const uint32_t kuiSpsId, const bool_t kbEnableFrameCropping, bool_t bEnableRc ) | |
| 431 | +{ | |
| 432 | + SWelsSPS *pSps = &pSubsetSps->pSps; | |
| 433 | + | |
| 434 | + memset(pSubsetSps, 0, sizeof(SSubsetSps)); | |
| 435 | + | |
| 436 | + WelsInitSps( pSps, pLayerParam, kuiIntraPeriod, kiNumRefFrame, kuiSpsId, kbEnableFrameCropping, bEnableRc ); | |
| 437 | + | |
| 438 | + pSps->uiProfileIdc = (pLayerParam->uiProfileIdc >= PRO_SCALABLE_BASELINE) ? pLayerParam->uiProfileIdc : PRO_SCALABLE_BASELINE; | |
| 439 | + | |
| 440 | + pSubsetSps->sSpsSvcExt.iExtendedSpatialScalability = 0; /* ESS is 0 in default */ | |
| 441 | + pSubsetSps->sSpsSvcExt.bAdaptiveTcoeffLevelPredFlag = false; | |
| 442 | + pSubsetSps->sSpsSvcExt.bSeqTcoeffLevelPredFlag = false; | |
| 443 | + pSubsetSps->sSpsSvcExt.bSliceHeaderRestrictionFlag = true; | |
| 444 | + | |
| 445 | + return 0; | |
| 446 | +} | |
| 447 | + | |
| 448 | +int32_t WelsInitPps( SWelsPPS *pPps, | |
| 449 | + SWelsSPS *pSps, | |
| 450 | + SSubsetSps *pSubsetSps, | |
| 451 | + const uint32_t kuiPpsId, | |
| 452 | + const bool_t kbDeblockingFilterPresentFlag, | |
| 453 | + const bool_t kbUsingSubsetSps ) | |
| 454 | +{ | |
| 455 | + SWelsSPS *pUsedSps = NULL; | |
| 456 | + if ( pPps == NULL || (pSps == NULL && pSubsetSps == NULL) ) | |
| 457 | + return 1; | |
| 458 | + if ( !kbUsingSubsetSps ){ | |
| 459 | + assert( pSps != NULL ); | |
| 460 | + if ( NULL == pSps ) | |
| 461 | + return 1; | |
| 462 | + pUsedSps = pSps; | |
| 463 | + } | |
| 464 | + else{ | |
| 465 | + assert(pSubsetSps != NULL); | |
| 466 | + if ( NULL == pSubsetSps ) | |
| 467 | + return 1; | |
| 468 | + pUsedSps = &pSubsetSps->pSps; | |
| 469 | + } | |
| 470 | + | |
| 471 | + /* fill picture parameter set syntax */ | |
| 472 | + pPps->iPpsId = kuiPpsId; | |
| 473 | + pPps->iSpsId = pUsedSps->uiSpsId; | |
| 474 | +#if !defined(DISABLE_FMO_FEATURE) | |
| 475 | + pPps->uiNumSliceGroups = 1; //param->qos_param.sliceGroupCount; | |
| 476 | + if( pPps->uiNumSliceGroups > 1 ) | |
| 477 | + { | |
| 478 | + pPps->uiSliceGroupMapType = 0; //param->qos_param.sliceGroupType; | |
| 479 | + if( pPps->uiSliceGroupMapType == 0 ) | |
| 480 | + { | |
| 481 | + uint32_t uiGroup = 0; | |
| 482 | + while (uiGroup < pPps->uiNumSliceGroups) { | |
| 483 | + pPps->uiRunLength[uiGroup] = 25; | |
| 484 | + ++ uiGroup; | |
| 485 | + } | |
| 486 | + } | |
| 487 | + else if( pPps->uiSliceGroupMapType == 2 ) | |
| 488 | + { | |
| 489 | + memset(&pPps->uiTopLeft[0], 0, MAX_SLICEGROUP_IDS*sizeof(pPps->uiTopLeft[0])); | |
| 490 | + memset(&pPps->uiBottomRight[0], 0, MAX_SLICEGROUP_IDS*sizeof(pPps->uiBottomRight[0])); | |
| 491 | + } | |
| 492 | + else if( pPps->uiSliceGroupMapType >= 3 && | |
| 493 | + pPps->uiSliceGroupMapType <= 5 ) | |
| 494 | + { | |
| 495 | + pPps->bSliceGroupChangeDirectionFlag = false; | |
| 496 | + pPps->uiSliceGroupChangeRate = 0; | |
| 497 | + } | |
| 498 | + else if( pPps->uiSliceGroupMapType == 6 ) | |
| 499 | + { | |
| 500 | + pPps->uiPicSizeInMapUnits = 1; | |
| 501 | + memset(&pPps->uiSliceGroupId[0], 0, MAX_SLICEGROUP_IDS*sizeof(pPps->uiSliceGroupId[0])); | |
| 502 | + } | |
| 503 | + } | |
| 504 | +#endif//!DISABLE_FMO_FEATURE | |
| 505 | + | |
| 506 | + pPps->iPicInitQp = 26; | |
| 507 | + pPps->iPicInitQs = 26; | |
| 508 | + | |
| 509 | + pPps->uiChromaQpIndexOffset = 0; | |
| 510 | + pPps->bDeblockingFilterControlPresentFlag = kbDeblockingFilterPresentFlag; | |
| 511 | + | |
| 512 | + return 0; | |
| 513 | +} | |
| 514 | +} // namespace WelsSVCEnc | |