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

📄 slice.c

📁 Nokia H.264/AVC Encoder/Decoder Usage Manual
💻 C
📖 第 1 页 / 共 2 页
字号:
    mapUnitsInSliceGroup0 = slice->sliceGroupChangeCycle *       (pps->slice_group_change_rate_minus1 + 1);    mapUnitsInSliceGroup0 =  min(mapUnitsInSliceGroup0, picSizeInMapUnits);    switch (pps->slice_group_map_type) {      /* type 0, 1 can be moved to the function activating parameter set. */    case SLICE_MAP_INTERLEAVED:      // the parameters should not violate the frame constraints      i = 0;      do {        for (iGroup = 0; iGroup <= (int)pps->num_slice_groups_minus1 && i < picSizeInMapUnits;          i += pps->run_length_minus1[iGroup++] + 1)        {          for (j = 0; j <= (int)pps->run_length_minus1[iGroup] && i+j < picSizeInMapUnits; j++)            pMbStateArr[i+j].sliceMap |= iGroup;   /* Only the group number */        }      } while (i < picSizeInMapUnits);      break;    case SLICE_MAP_DISPERSED:      {        int numGroups, offset;        numGroups = pps->num_slice_groups_minus1 + 1;        for (i = 0; i < picSizeInMapUnits; i ++)        {          // offset makes an even row start with group 0,           // an odd row start with group "numGroups/2"          offset = ((i/picWidthInMbs) * numGroups)/2;          pMbStateArr[i].sliceMap =             (int16) (((i % picWidthInMbs) + offset) % numGroups);        }      }      break;    case SLICE_MAP_FOREGROUND:      // background, with the largest ground ID      for (i = 0; i < picSizeInMapUnits; i++)        pMbStateArr[i].sliceMap = (int16) pps->num_slice_groups_minus1;      // foreground, rectangles can overlap      // overlapping area will be in the group with the smallest ID      for (iGroup = pps->num_slice_groups_minus1 - 1; iGroup >= 0; iGroup--) {        int xTopLeft, yTopLeft, xBottomRight, yBottomRight;        yTopLeft = pps->top_left[iGroup] / picWidthInMbs;        xTopLeft = pps->top_left[iGroup] % picWidthInMbs;        yBottomRight = pps->bottom_right[iGroup] / picWidthInMbs;        xBottomRight = pps->bottom_right[iGroup] % picWidthInMbs;        for (y = yTopLeft; y <= yBottomRight; y++)          for (x = xTopLeft; x <= xBottomRight; x++)            pMbStateArr[y * picWidthInMbs + x].sliceMap = (int16) iGroup;      }      break;    case SLICE_MAP_BOX_OUT:      {        int leftBound, topBound, rightBound, bottomBound;        int xDir, yDir;        int mapUnitVacant;        for (i = 0; i < picSizeInMapUnits; i++)          pMbStateArr[i].sliceMap = 1;        x = (picWidthInMbs - pps->slice_group_change_direction_flag)/2;        y = (picHeightInMapUnits - pps->slice_group_change_direction_flag)/2;        leftBound = x;         topBound = y;        rightBound = x;         bottomBound = y;        xDir = pps->slice_group_change_direction_flag - 1;        yDir = pps->slice_group_change_direction_flag;        for (i = 0; i < mapUnitsInSliceGroup0; i += mapUnitVacant) {          mapUnitVacant = (pMbStateArr[y * picWidthInMbs + x].sliceMap == 1);          if (mapUnitVacant)            pMbStateArr[y * picWidthInMbs + x].sliceMap = 0;          if (xDir == -1 && x == leftBound) {            // reach left bound, shift one step left, then move vertically            leftBound = max(leftBound - 1, 0);            x = leftBound;            xDir = 0;            // move up if direction_flag is 0, otherwise move down            yDir = 2 * pps->slice_group_change_direction_flag - 1;          }           else if (xDir == 1 && x == rightBound) {            // reach right bound, shift one step right, then move vertically            rightBound = min(rightBound + 1, picWidthInMbs - 1);            x = rightBound;            xDir = 0;            // move down if direction_flag is 0, otherwise move up            yDir = 1 - 2 * pps->slice_group_change_direction_flag;          }          else if (yDir == -1 && y == topBound) {            // reach top bound, shift one step up, then move horizontally            topBound = max(topBound - 1, 0);            y = topBound;            // move to right if direction_flag is 0, otherwise move to left            xDir = 1 - 2 * pps->slice_group_change_direction_flag;            yDir = 0;          }           else if (yDir == 1 && y == bottomBound) {            // reach bottom bound, shift one step down, then move horizontally            bottomBound = min(bottomBound + 1, picHeightInMapUnits - 1);            y = bottomBound;            // move to left if direction_flag is 0, otherwise move to right            xDir = 2 * pps->slice_group_change_direction_flag - 1;            yDir = 0;          }           else {            // just move according to pre-determined direction            x = x + xDir;            y = y + yDir;          }        }      }      break;    case SLICE_MAP_RASTER:    case SLICE_MAP_WIPE:      sizeOfUpperLeftGroup = pps->slice_group_change_direction_flag ?         (picSizeInMapUnits - mapUnitsInSliceGroup0) : mapUnitsInSliceGroup0;      iGroup = pps->slice_group_change_direction_flag;      if (pps->slice_group_map_type == SLICE_MAP_RASTER)      {        for (i = 0; i < picSizeInMapUnits; i ++)        {          if (i >= sizeOfUpperLeftGroup)            // change to another slice group            iGroup = 1 - pps->slice_group_change_direction_flag;          pMbStateArr[i].sliceMap = (int16) iGroup;        }      }      else      {        k = 0;        for (j = 0; j < picWidthInMbs; j ++)          for (i = 0; i < picHeightInMapUnits; i ++)          {            if( k ++ >= sizeOfUpperLeftGroup )              // change to another slice group              iGroup = 1 - pps->slice_group_change_direction_flag;            pMbStateArr[i * picWidthInMbs + j].sliceMap = (int16) iGroup;          }      }      break;    case SLICE_MAP_BITMAP:      for (i = 0; i < picSizeInMapUnits; i++)        pMbStateArr[i].sliceMap = pps->slice_group_id[i];      break;    default:      break;    }  }}/* * sliceEncode * * Parameters: *      slice                 SLice object *      sliceIdxInGroup       Index of this slice within a slice group        *      sps                   Sequence parameter set *      pps                   Picture parameter set *      pBrc                  pointer to bit rate control engine, * * Function: *      Encode one slice * * Returns: *      0   This is not the last slice in the current frame *      1   This is the last slice in the current slice group of the current frame */int sliceEncode(slice_s             *slice,                 int                 sliceIdxInGroup,                 dpbBuf_s            *dpbBuf,                encParams_s         *encPar,                int                 tuneFactor,                int                 *mapRIR,                seq_parameter_set_s *sps,                 pic_parameter_set_s *pps,                int                 forcedIRNo,                int                 *forcedIR,                rateCtrl_s          *pbRC){  int numBits;  int sliceDataStartBits;  int sliceStartBits, maxSliceSize;  int maxMbsPerSlice;  int mbNum, numIntraMbs;  macroblock_s *mb;  meProfile_s  *pMeProf;  refFrmBuf_s  **refFrmBufs;    /* Interface for MB layer. */  mbState_s    *mbStateArr;  void         *stream;  int numRefFrms;  int nextSliceAddr;  int temp_header= 0;  int temp_texture = 0;  mbStateArr = slice->mbStateArr;  mb         = & slice->mb;  pMeProf    = & slice->meProfile;  sliceStartBits = bibGetNumBits(slice->bitbuf);  sliceDataStartBits = sliceStartBits;    // just to avoid compiler complaint  dpbRefListNormalOrder(dpbBuf);  // Reference picture list (Interface for MB layer)  refFrmBufs = dpbBuf->refPicList0;  // setup the motion estimation profile  if (IS_SLICE_P(slice->sliceType))    mesPrepareProfile(pMeProf, refFrmBufs[0], encPar, dpbBuf->numRefFrms);  // if nBytesPerSlice is 0, no fixed length slices, set the size to max  maxSliceSize = (encPar->nBytesPerSlice == 0) ? INT_MAX : 8 *     (encPar->nBytesPerSlice - 4);  // If nMbsPerSlice is 0, set number of mbs per slice to max  maxMbsPerSlice = (encPar->nMbsPerSlice == 0) ? INT_MAX : encPar->nMbsPerSlice;  // Initialize macroblock before the slice is encoded  mbkBeforeSlice(mb, slice->qp);  stream = slice->bitbuf;  // in the first run, the best frame order will be found  numIntraMbs = 0;  // perform the reordering of the reference frame pointers  numRefFrms = dpbBuf->numRefFrms;  slice->frmStat->bitsHdr += startSlice(slice, encPar, slice->firstMbAddr,     dpbBuf, sps, pps, & slice->frmStat->bitsNAL);  sliceDataStartBits = bibGetNumBits(slice->bitbuf);   // Scan through all macroblocks in slice  nextSliceAddr = slice->firstMbAddr;  mbNum = 0;  do {    mbState_s *pMbState;        // setup the address of the current macroblock    mb->mbAddr = nextSliceAddr;    mb->idxX   = nextSliceAddr % slice->mbksPerLine;    mb->idxY   = nextSliceAddr / slice->mbksPerLine;    // look for the next MB in the same slice group    do {      nextSliceAddr ++;    } while (nextSliceAddr < slice->picSizeInMbs &&       (mbStateArr[nextSliceAddr].sliceMap & 0xF) != slice->groupId);    // if next MB is available, nextSliceAddr should be within the frame    mb->isLastMb = (nextSliceAddr == slice->picSizeInMbs) || (mbNum+1 == maxMbsPerSlice);    // Perform bit-rate control    numBits = bibGetNumBits(slice->bitbuf);    if(pbRC->bit_rate != 0)    {        temp_header =             slice->frmStat->bitsNAL +          slice->frmStat->bitsHdr +          slice->frmStat->bitsSkipLen +          slice->frmStat->bitsMBtype +          slice->frmStat->bitsPred +          slice->frmStat->bitsVec +          slice->frmStat->bitsCBP;        temp_texture =           slice->frmStat->bitsCoefLumaDC +          slice->frmStat->bitsCoefLuma +          slice->frmStat->bitsCoefChromaDC +          slice->frmStat->bitsCoefChroma +          slice->frmStat->bitsArithmeticStream ;            }        // this is to collect the statistics    mbkStartEnc(mb, slice->mbStateArr, slice->origBuf, slice->recoBuf,       encPar, slice->qp, tuneFactor);    // mbAddr is calculated in mbkStartEnc    pMbState = & mbStateArr[mb->mbAddr];    // differentiate slices within the same slice group    pMbState->sliceMap |= sliceIdxInGroup << 4;    // Put loopfilter mode    pMbState->filterMode  = (char) encPar->filterMode;    pMbState->alphaOffset = (char) encPar->alphaOffset;    pMbState->betaOffset  = (char) encPar->betaOffset;       mbkModeSelection(pbRC,mb, pMeProf, refFrmBufs, numRefFrms,    slice->sliceType, encPar, mapRIR, slice->recoBuf->channelDistortion, forcedIRNo, forcedIR, mb->idxY*encPar->picWidth/MBK_SIZE+mb->idxX);   slice->qp = (short) mb->qp;        //printf("%d ",slice->qp);    // otherwise (temporary), intra-4x4 was fully processed, using nominal qp   mbkProcessData(mb, slice->sliceType, encPar);    // VLC coding of macroblock   mbkSend(stream, mb, numRefFrms, slice->sliceType, slice->frmStat);    numBits = bibGetNumBits(slice->bitbuf);    if ((numBits - sliceStartBits) >= maxSliceSize)      mb->isLastMb = 1;    // some bookkeeping at the end of encoding    mbkFinishEnc(mb, slice->frmStat);    if (mb->type == MBK_INTRA)      numIntraMbs ++;  if (mb->type == MBK_INTRA)    pbRC->numIntraMBs++;    if(pbRC->bit_rate != 0)  {    temp_header =         slice->frmStat->bitsNAL +      slice->frmStat->bitsHdr +      slice->frmStat->bitsSkipLen +      slice->frmStat->bitsMBtype +      slice->frmStat->bitsPred +      slice->frmStat->bitsVec +      slice->frmStat->bitsCBP - temp_header;    temp_texture =       slice->frmStat->bitsCoefLumaDC +      slice->frmStat->bitsCoefLuma +      slice->frmStat->bitsCoefChromaDC +      slice->frmStat->bitsCoefChroma +      slice->frmStat->bitsArithmeticStream - temp_texture;              rc_updateMB(pbRC,temp_texture,temp_header,mb,mb->idxY*encPar->picWidth / MBK_SIZE+mb->idxX);  }    mbNum++;  } while (!mb->isLastMb);  // Check if skip flag needs to be sent at the end of slice  if (encPar->entropyEncoder == ENTROPY_CAVLC && IS_SLICE_P(slice->sliceType) && mb->numSkipped > 0)    streamSendMbSkipFlag(stream, mb, 0);  // end the slice by sending the trailing bits  slice->frmStat->bitsHdr += bibTrailingBits(slice->bitbuf);  return numIntraMbs;}

⌨️ 快捷键说明

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