📄 slice.c
字号:
} else if (reordering_of_pic_nums_idc == 2) { /* longTermPicNum be in the range of 0 to num_ref_frames, inclusive. */ if ((retCode = ue_v(bitbuf, &slice->reorderCmdList[i].long_term_pic_num, numRefFrames)) < 0) return retCode; } i++; } while (reordering_of_pic_nums_idc != 3 && i < MAX_NUM_OF_REORDER_CMDS); } } return SLICE_OK;}/* * getDecRefPicMarkingCmds: * * Parameters: * slice Slice object * bitbuf Bitbuffer object * numRefFrames Number of reference frames in used * * Function: * Parse and store the MMCO commands * * Return: * The number of bits being parsed */static int getDecRefPicMarkingCmds(slice_s *slice, unsigned int numRefFrames, bitbuffer_s *bitbuf){ int i; unsigned int mmco; int retCode; /* MMCO commands can exist only in slice header of a reference picture */ if (slice->nalRefIdc != 0) { if (slice->isIDR) { if ((retCode = u_n(bitbuf, 1, &slice->no_output_of_prior_pics_flag)) < 0) return retCode; if ((retCode = u_n(bitbuf, 1, &slice->long_term_reference_flag)) < 0) return retCode; } else { if ((retCode = u_n(bitbuf, 1, &slice->adaptive_ref_pic_marking_mode_flag)) < 0) return retCode; if (slice->adaptive_ref_pic_marking_mode_flag) { i = 0; do { /* Get MMCO command */ if ((retCode = ue_v(bitbuf, &mmco, 6)) < 0) return retCode; slice->mmcoCmdList[i].memory_management_control_operation = mmco; /* Get command parameter (if any) */ if (mmco == 1 || mmco == 3) { if ((retCode = ue_v(bitbuf, &slice->mmcoCmdList[i].difference_of_pic_nums_minus1, 65535)) < 0) return retCode; } if (mmco == 2) { if ((retCode = ue_v(bitbuf, &slice->mmcoCmdList[i].long_term_pic_num, numRefFrames)) < 0) return retCode; } if (mmco == 3 || mmco == 6) { if ((retCode = ue_v(bitbuf, &slice->mmcoCmdList[i].long_term_frame_idx, numRefFrames)) < 0) return retCode; } if (mmco == 4) { if ((retCode = ue_v(bitbuf, &slice->mmcoCmdList[i].max_long_term_frame_idx_plus1, numRefFrames)) < 0) return retCode; } if (mmco == 5) { slice->picHasMMCO5 = 1; } i++; } while (mmco != 0 && i < MAX_NUM_OF_MMCO_OPS); } } } else slice->adaptive_ref_pic_marking_mode_flag = 0; return NCC_OK;}/* * sliceInitRefPicList: * * Parameters: * dpb DPB buffer * refPicList Reference picture list (output) * numRefPicActive Number of active reference frames * * Fucntion: * Initialize reference picture list. * * Return: * SLICE_OK for no error and negative value for error. */int sliceInitRefPicList(dpb_s *dpb, frmBuf_s *refPicList[], int numRefPicActive){ int numRef, numShort; frmBuf_s *refTmp; int i, j; /* * Select the reference pictures from the DPB */ j = 0; /* Put short term pictures first in the list */ for (i = 0; i < dpb->fullness; i++) { if (dpb->buffers[i]->refType == FRM_SHORT_TERM_PIC) refPicList[j++] = dpb->buffers[i]; } numShort = j; /* Put long term pictures after the short term pictures */ for (i = 0; i < dpb->fullness; i++) { if (dpb->buffers[i]->refType == FRM_LONG_TERM_PIC) refPicList[j++] = dpb->buffers[i]; } numRef = j; /* numLong = numRef - numShort; */ if (numRef < numRefPicActive) return SLICE_ERR_ILLEGAL_VALUE; /* * Initialisation process for reference picture lists */ /* Sort short term pictures in the order of descending picNum */ for (i = 0; i < numShort; i++) { for (j = i+1; j < numShort; j++) { if (refPicList[i]->picNum < refPicList[j]->picNum) { /* exchange refPicList[i] and refPicList[j] */ refTmp = refPicList[i]; refPicList[i] = refPicList[j]; refPicList[j] = refTmp; } } } /* Sort long term pictures in the order of ascending longTermPicNum */ for (i = numShort; i < numRef; i++) { for (j = i+1; j < numRef; j++) { if (refPicList[i]->longTermPicNum > refPicList[j]->longTermPicNum) { /* exchange refPicList[i] and refPicList[j] */ refTmp = refPicList[i]; refPicList[i] = refPicList[j]; refPicList[j] = refTmp; } } } return SLICE_OK;}/* * refPicListReordering: * * Parameters: * slice Current slice object * dpb DPB buffer * refPicList Reference picture list (modified by this function) * numRefPicActive Number of active reference frames * reorderCmdList Reordering command list * * Fucntion: * Reorder the reference picture list for current slice * * Return: * SLICE_OK for no error and negative value for error */static int refPicListReordering(slice_s *slice, dpb_s *dpb, frmBuf_s *refPicList[], int numRefPicActive, sliceRefPicListReorderCmd_s reorderCmdList[]){ int i; int reordering_of_pic_nums_idc, longTermPicNum; int32 absDiffPicNum; int refIdx; int32 currPicNum, picNumPred, picNumNoWrap; int32 maxPicNum, picNum; int cmdNum; int cIdx, nIdx; /* * 3. Reordering process for reference picture list */ maxPicNum = slice->maxFrameNum; /* for frame coding only */ currPicNum = slice->frame_num; picNumPred = currPicNum; refIdx = 0; cmdNum = 0; do { reordering_of_pic_nums_idc = reorderCmdList[cmdNum].reordering_of_pic_nums_idc; if (reordering_of_pic_nums_idc == 0 || reordering_of_pic_nums_idc == 1) { /* * reorder short-term ref pic -subclause 8.2.4.3.1 */ absDiffPicNum = reorderCmdList[cmdNum].abs_diff_pic_num_minus1 + 1; /* Derive picNumNoWrap */ if (reordering_of_pic_nums_idc == 0) { if (picNumPred - absDiffPicNum < 0) picNumNoWrap = picNumPred - absDiffPicNum + maxPicNum; else picNumNoWrap = picNumPred - absDiffPicNum; } else { /* reordering_of_pic_nums_idc == 1 */ if (picNumPred + absDiffPicNum >= maxPicNum) picNumNoWrap = picNumPred + absDiffPicNum - maxPicNum; else picNumNoWrap = picNumPred + absDiffPicNum; } /* Derive picNum */ if (picNumNoWrap > currPicNum) picNum = picNumNoWrap - maxPicNum; else picNum = picNumNoWrap; /* Find short term picture with picture number picNum */ for (i = 0; i < dpb->fullness; i++) { if (!dpb->buffers[i]->nonExisting && dpb->buffers[i]->refType == FRM_SHORT_TERM_PIC && dpb->buffers[i]->picNum == picNum) break; } /* If picNum was not found */ if (i == dpb->fullness) { deb1f(stderr, "The short term ref pic(%d) is not found!\n", picNum); return SLICE_ERR_ILLEGAL_VALUE; } /* Shift remaining pictures later in the list */ for (cIdx = numRefPicActive; cIdx > refIdx; cIdx--) refPicList[cIdx] = refPicList[cIdx - 1]; /* Place picture with number picNum into the index position refIdx */ refPicList[refIdx++] = dpb->buffers[i]; /* Remove duplicate of the inserted picture */ nIdx = refIdx; for (cIdx = refIdx; cIdx <= numRefPicActive; cIdx++) if (refPicList[cIdx]->refType == FRM_LONG_TERM_PIC || refPicList[cIdx]->picNum != picNum) refPicList[nIdx++] = refPicList[cIdx]; picNumPred = picNumNoWrap; } else if (reordering_of_pic_nums_idc == 2) { /* * reorder long-term ref pic -subclause 8.2.4.3.2 */ /* Get long-term picture number */ longTermPicNum = reorderCmdList[cmdNum].long_term_pic_num; /* Find long-term picture with picture number longTermPicNum */ for (i = 0; i < dpb->fullness; i++) if (dpb->buffers[i]->refType == FRM_LONG_TERM_PIC && dpb->buffers[i]->longTermPicNum == longTermPicNum) break; if (i == dpb->fullness) { // something wrong ! deb1f(stderr, "The long term ref pic(%d) is not found!\n", longTermPicNum); return SLICE_ERR_ILLEGAL_VALUE; } /* Shift remaining pictures later in the list */ for (cIdx = numRefPicActive; cIdx > refIdx; cIdx--) refPicList[cIdx] = refPicList[cIdx - 1]; /* Place picture with number longTermPicNum into the index position refIdx */ refPicList[refIdx++] = dpb->buffers[i]; /* Remove duplicate of the inserted picture */ nIdx = refIdx; for (cIdx = refIdx; cIdx <= numRefPicActive; cIdx++) if (refPicList[cIdx]->refType == FRM_SHORT_TERM_PIC || refPicList[cIdx]->longTermPicNum != longTermPicNum) { refPicList[nIdx++] = refPicList[cIdx]; } } cmdNum++; } while (reordering_of_pic_nums_idc != 3 && cmdNum < MAX_NUM_OF_REORDER_CMDS); refPicList[numRefPicActive] = 0; return SLICE_OK;}/* * * sliceDecodeMacroblocks: * * Parameters: * slice Slice object * recoBuf Current frame buffer * dpb Decoded picture buffer * pEc Error concealment * pps Picture PS * mdData Macroblock buffer * sliceID Slice ID (=sliceNum*16+sliceGroupNum) * bitbuf Bitbuffer object * * Function: * Decode one slice * * Returns: * SLICE_OK: Success * <0: Fail */int sliceDecodeMacroblocks(slice_s *slice, frmBuf_s *recoBuf, dpb_s *dpb,#ifdef ERROR_CONCEALMENT errorConcealment_s *pEc,#endif pic_parameter_set_s *pps, mbAttributes_s *mbData, int sliceID, bitbuffer_s *bitbuf){ frmBuf_s *refPicList0[DPB_MAX_SIZE+1]; macroblock_s mb; int numRefFrames; int mbIdxY; int mbIdxX; int mbksPerLine; int mbksPerCol; int picSizeInMbs; int currMbAddr; int sliceGroupNum; void *stream; int retCode; /* Choose number of reference frames and build reference picture list */ numRefFrames = 0; if (!IS_SLICE_I(slice->slice_type)) { if (slice->num_ref_idx_active_override_flag) numRefFrames = slice->num_ref_idx_l0_active_minus1 + 1; else numRefFrames = pps->num_ref_idx_l0_active_minus1 + 1; retCode = sliceInitRefPicList(dpb, refPicList0, numRefFrames); if (retCode < 0) return retCode; if (slice->ref_pic_list_reordering_flag0) { retCode = refPicListReordering(slice, dpb, refPicList0, numRefFrames, slice->reorderCmdList); if (retCode < 0) return retCode; } } mbksPerLine = recoBuf->width/MBK_SIZE; mbksPerCol = recoBuf->height/MBK_SIZE; picSizeInMbs = mbksPerLine*mbksPerCol; currMbAddr = slice->first_mb_in_slice; sliceGroupNum = sliceID & 0xF; mbIdxY = currMbAddr / mbksPerLine; mbIdxX = currMbAddr - mbIdxY*mbksPerLine; mbkSetInitialQP(&mb, slice->qp, pps->chroma_qp_index_offset); stream = bitbuf; /* Loop until all macroblocks in current slice have been decoded */ do { /* Store slice ID for current macroblock */ mbData->sliceMap[currMbAddr] = sliceID; /* Store loopfilter mode */ mbData->filterModeTab[currMbAddr] = (int8) slice->disable_deblocking_filter_idc; mbData->alphaOffset[currMbAddr] = (int8) (slice->slice_alpha_c0_offset_div2*2); mbData->betaOffset[currMbAddr] = (int8) (slice->slice_beta_offset_div2*2); retCode = mbkDecode(&mb, recoBuf, refPicList0, numRefFrames, mbData, recoBuf->width, recoBuf->height, slice->slice_type, pps->constrained_intra_pred_flag, pps->chroma_qp_index_offset, mbIdxX, mbIdxY, stream); if (retCode < 0) return SLICE_ERROR;#ifdef ERROR_CONCEALMENT ercDecodeMb(pEc, mbIdxX, mbIdxY);#endif /* If end of slice data has been reached and there are no */ /* skipped macroblocks left, stop decoding slice. */ if (!bibMoreRbspData(bitbuf) && mb.numSkipped <= 0) break; /* Find next mb address in the current slice group */ do { /* Next mb address */ currMbAddr++; /* If end of frame was reached, stop search */ if (currMbAddr == picSizeInMbs) break; /* Update mb location */ mbIdxX++; if (mbIdxX == mbksPerLine) { mbIdxX = 0; mbIdxY++; } } while ((mbData->sliceMap[currMbAddr] & 0xF) != sliceGroupNum); /* If end of frame was reached, stop decoding slice */ } while (currMbAddr < picSizeInMbs); return SLICE_OK;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -