コード例 #1
0
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;

}
コード例 #2
0
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;
    }
}
コード例 #3
0
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;
}