void VaapiDPBManager::initPictureRefLists(const PicturePtr& pic) { uint32_t i, j, shortRefCount, longRefCount; VaapiFrameStore::Ptr frameStore; VaapiDecPictureH264 *picture; shortRefCount = 0; longRefCount = 0; if (pic->m_structure == VAAPI_PICTURE_STRUCTURE_FRAME) { for (i = 0; i < DPBLayer->DPBCount; i++) { frameStore = DPBLayer->DPB[i]; if (!frameStore->hasFrame()) continue; picture = frameStore->m_buffers[0].get(); if (VAAPI_H264_PICTURE_IS_SHORT_TERM_REFERENCE(picture)) DPBLayer->shortRef[shortRefCount++] = picture; else if (VAAPI_H264_PICTURE_IS_LONG_TERM_REFERENCE(picture)) DPBLayer->longRef[longRefCount++] = picture; picture->m_structure = VAAPI_PICTURE_STRUCTURE_FRAME; picture->m_otherField = frameStore->m_buffers[1]; } } else { for (i = 0; i < DPBLayer->DPBCount; i++) { frameStore = DPBLayer->DPB[i]; for (j = 0; j < frameStore->m_numBuffers; j++) { picture = frameStore->m_buffers[j].get(); if (VAAPI_H264_PICTURE_IS_SHORT_TERM_REFERENCE(picture)) DPBLayer->shortRef[shortRefCount++] = picture; else if (VAAPI_H264_PICTURE_IS_LONG_TERM_REFERENCE (picture)) DPBLayer->longRef[longRefCount++] = picture; picture->m_structure = picture->m_picStructure; picture->m_otherField = frameStore->m_buffers[j ^ 1]; } } } for (i = shortRefCount; i < DPBLayer->shortRefCount; i++) DPBLayer->shortRef[i] = NULL; DPBLayer->shortRefCount = shortRefCount; for (i = longRefCount; i < DPBLayer->longRefCount; i++) DPBLayer->longRef[i] = NULL; DPBLayer->longRefCount = longRefCount; }
void VaapiDecoderH264::vaapiFillPicture(VAPictureH264 * pic, VaapiPictureH264 * picture, uint32_t pictureStructure) { pic->picture_id = picture->m_surfaceID; pic->flags = 0; if (VAAPI_H264_PICTURE_IS_LONG_TERM_REFERENCE(picture)) { pic->flags |= VA_PICTURE_H264_LONG_TERM_REFERENCE; pic->frame_idx = picture->m_longTermFrameIdx; } else { if (VAAPI_H264_PICTURE_IS_SHORT_TERM_REFERENCE(picture)) pic->flags |= VA_PICTURE_H264_SHORT_TERM_REFERENCE; pic->frame_idx = picture->m_frameNum; } if (!pictureStructure) pictureStructure = picture->m_structure; switch (pictureStructure) { case VAAPI_PICTURE_STRUCTURE_FRAME: pic->TopFieldOrderCnt = picture->m_fieldPoc[TOP_FIELD]; pic->BottomFieldOrderCnt = picture->m_fieldPoc[BOTTOM_FIELD]; break; case VAAPI_PICTURE_STRUCTURE_TOP_FIELD: pic->flags |= VA_PICTURE_H264_TOP_FIELD; pic->TopFieldOrderCnt = picture->m_fieldPoc[TOP_FIELD]; pic->BottomFieldOrderCnt = 0; break; case VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD: pic->flags |= VA_PICTURE_H264_BOTTOM_FIELD; pic->BottomFieldOrderCnt = picture->m_fieldPoc[BOTTOM_FIELD]; pic->TopFieldOrderCnt = 0; break; } }
void VaapiDPBManager::execPictureRefsModification1(const PicturePtr& picture, const SliceHeaderPtr&sliceHdr, uint32_t list) { H264PPS *const pps = sliceHdr->pps; H264SPS *const sps = pps->sequence; H264RefPicListModification *refPicListModification; uint32_t numRefPicListModifications; VaapiDecPictureH264 **refList; uint32_t *refListCountPtr, refListCount, refListIdx = 0; uint32_t i, j, n, numRefs; int32_t foundRefIdx; int32_t maxPicNum, currPicNum, picNumPred; if (list == 0) { refPicListModification = sliceHdr->ref_pic_list_modification_l0; numRefPicListModifications = sliceHdr->n_ref_pic_list_modification_l0; refList = DPBLayer->refPicList0; refListCountPtr = &DPBLayer->refPicList0Count; numRefs = sliceHdr->num_ref_idx_l0_active_minus1 + 1; } else { refPicListModification = sliceHdr->ref_pic_list_modification_l1; numRefPicListModifications = sliceHdr->n_ref_pic_list_modification_l1; refList = DPBLayer->refPicList1; refListCountPtr = &DPBLayer->refPicList1Count; numRefs = sliceHdr->num_ref_idx_l1_active_minus1 + 1; } refListCount = *refListCountPtr; //FIXME: without this we will crash in MR3_TANDBERG_B.264 //shold review this after we fix it for (int j = refListCount; j < numRefs; j++) refList[j] = NULL; //end if (picture->m_structure != VAAPI_PICTURE_STRUCTURE_FRAME) { maxPicNum = 1 << (sps->log2_max_frame_num_minus4 + 5); // 2 * maxFrameNum currPicNum = 2 * sliceHdr->frame_num + 1; // 2 * frame_num + 1 } else { maxPicNum = 1 << (sps->log2_max_frame_num_minus4 + 4); // maxFrameNum currPicNum = sliceHdr->frame_num; // frame_num } picNumPred = currPicNum; for (i = 0; i < numRefPicListModifications; i++) { H264RefPicListModification *const l = &refPicListModification[i]; if (l->modification_of_pic_nums_idc == 3) break; /* 8.2.4.3.1 - Short-term reference pictures */ if (l->modification_of_pic_nums_idc == 0 || l->modification_of_pic_nums_idc == 1) { int32_t absDiffPicNum = l->value.abs_diff_pic_num_minus1 + 1; int32_t picNum, picNumNoWrap; // (8-34) if (l->modification_of_pic_nums_idc == 0) { picNumNoWrap = picNumPred - absDiffPicNum; if (picNumNoWrap < 0) picNumNoWrap += maxPicNum; } // (8-35) else { picNumNoWrap = picNumPred + absDiffPicNum; if (picNumNoWrap >= maxPicNum) picNumNoWrap -= maxPicNum; } picNumPred = picNumNoWrap; // (8-36) picNum = picNumNoWrap; if (picNum > currPicNum) picNum -= maxPicNum; // (8-37) for (j = numRefs; j > refListIdx; j--) refList[j] = refList[j - 1]; foundRefIdx = findShortRermReference(picNum); refList[refListIdx++] = foundRefIdx >= 0 ? DPBLayer->shortRef[foundRefIdx] : NULL; n = refListIdx; for (j = refListIdx; j <= numRefs; j++) { int32_t picNumF; if (!refList[j]) continue; picNumF = VAAPI_H264_PICTURE_IS_SHORT_TERM_REFERENCE(refList[j]) ? refList[j]->m_picNum : maxPicNum; if (picNumF != picNum) refList[n++] = refList[j]; } } /* 8.2.4.3.2 - Long-term reference pictures */ else if (l->modification_of_pic_nums_idc == 2) { for (j = numRefs; j > refListIdx; j--) refList[j] = refList[j - 1]; foundRefIdx = findLongTermReference(l->value.long_term_pic_num); refList[refListIdx++] = foundRefIdx >= 0 ? DPBLayer->longRef[foundRefIdx] : NULL; n = refListIdx; for (j = refListIdx; j <= numRefs; j++) { uint32_t longTermPicNumF; if (!refList[j]) continue; longTermPicNumF = VAAPI_H264_PICTURE_IS_LONG_TERM_REFERENCE(refList[j]) ? refList[j]->m_longTermPicNum : std::numeric_limits<int32_t>::max(); if (longTermPicNumF != l->value.long_term_pic_num) refList[n++] = refList[j]; } } } for (i = numRefs; i > 0 && !refList[i - 1]; i--); *refListCountPtr = i; }