Encode_Status VaapiEncoderH264::encodePicture(const PicturePtr& picture) { Encode_Status ret = ENCODE_FAIL; SurfacePtr reconstruct = createSurface(); if (!reconstruct) return ret; { AutoLock locker(m_paramLock); #ifdef __BUILD_GET_MV__ uint32_t size; void *buffer = NULL; getMVBufferSize(&size); if (!picture->editMVBuffer(buffer, &size)) return ret; #endif if (!ensureSequence (picture)) return ret; if (!ensureMiscParams (picture.get())) return ret; if (!ensurePicture(picture, reconstruct)) return ret; if (!ensureSlices (picture)) return ret; } if (!picture->encode()) return ret; if (!referenceListUpdate (picture, reconstruct)) return ret; return ENCODE_SUCCESS; }
static void setH264PictureReference(VaapiDecPictureH264* picture, uint32_t referenceFlags, bool otherField) { VAAPI_PICTURE_FLAG_UNSET(picture, VAAPI_PICTURE_FLAGS_REFERENCE); VAAPI_PICTURE_FLAG_SET(picture, referenceFlags); PicturePtr strong; if (!otherField || !(strong = picture->m_otherField.lock())) return ; VaapiDecPictureH264* other = strong.get(); VAAPI_PICTURE_FLAG_UNSET(other, VAAPI_PICTURE_FLAGS_REFERENCE); VAAPI_PICTURE_FLAG_SET(other, referenceFlags); }
bool VaapiDPBManager::execDummyPictureMarking(const PicturePtr& dummyPic, const SliceHeaderPtr& sliceHdr, int32_t frameNum) { initPictureRefLists(dummyPic); initPictureRefsPicNum(dummyPic, sliceHdr, frameNum); if (!execRefPicMarkingSlidingWindow(dummyPic)) return false; removeShortReference(dummyPic); /* add to short reference */ DPBLayer->shortRef[DPBLayer->shortRefCount++] = dummyPic.get(); return true; }
bool VaapiDPBManager::execRefPicMarkingSlidingWindow(const PicturePtr& picture) { H264PPS *const pps = picture->m_pps; H264SPS *const sps = pps->sequence; VaapiDecPictureH264 *refPicture; uint32_t i, m, maxNumRefFrames; if (!VAAPI_PICTURE_IS_FIRST_FIELD(picture)) return true; maxNumRefFrames = sps->num_ref_frames; if (maxNumRefFrames == 0) maxNumRefFrames = 1; if (!VAAPI_PICTURE_IS_FRAME(picture)) maxNumRefFrames <<= 1; if (DPBLayer->shortRefCount + DPBLayer->longRefCount < maxNumRefFrames) return true; if (DPBLayer->shortRefCount < 1) return false; for (m = 0, i = 1; i < DPBLayer->shortRefCount; i++) { VaapiDecPictureH264 *const pic = DPBLayer->shortRef[i]; if (pic->m_frameNumWrap < DPBLayer->shortRef[m]->m_frameNumWrap) m = i; } refPicture = DPBLayer->shortRef[m]; setH264PictureReference(refPicture, 0, true); ARRAY_REMOVE_INDEX(DPBLayer->shortRef, m); /* Both fields need to be marked as "unused for reference", so remove the other field from the shortRef[] list as well */ if (!VAAPI_PICTURE_IS_FRAME(picture)) { PicturePtr strong = refPicture->m_otherField.lock(); VaapiDecPictureH264* other = strong.get(); if (other) { for (i = 0; i < DPBLayer->shortRefCount; i++) { if (DPBLayer->shortRef[i] == other) { ARRAY_REMOVE_INDEX(DPBLayer->shortRef, i); break; } } } } return true; }
void VaapiDPBManager::removeShortReference(const PicturePtr& picture) { VaapiDecPictureH264 *refPicture; uint32_t i; uint32_t frameNum = picture->m_frameNum; PicturePtr strong = picture->m_otherField.lock(); VaapiDecPictureH264* other = strong.get(); for (i = 0; i < DPBLayer->shortRefCount; ++i) { if (DPBLayer->shortRef[i]->m_frameNum == frameNum) { refPicture = DPBLayer->shortRef[i]; if (refPicture != other) { setH264PictureReference(refPicture, 0, false); ARRAY_REMOVE_INDEX(DPBLayer->shortRef, i); } return; } } }
bool VaapiDPBManager::outputDPB(const VaapiFrameStore::Ptr &frameStore, const PicturePtr& picture) { picture->m_outputNeeded = false; PicturePtr frame; if (frameStore) { if (--frameStore->m_outputNeeded > 0) return true; frame = frameStore->m_buffers[0]; } DEBUG("DPB: output picture(Addr:%p, Poc:%d)", picture.get(), picture->m_POC); //FIXME: #if 0 if (!frameStore) picture->m_surfBuf->status &= ~SURFACE_DECODING; #endif return m_decoder->outputPicture(frame) == DECODE_SUCCESS; }
bool VaapiDPBManager::execRefPicMarkingAdaptive1(const PicturePtr& picture, H264RefPicMarking *refPicMarking, uint32_t MMCO) { uint32_t picNumX, i; int32_t longTermFrameIdx; VaapiDecPictureH264 *refPicture; int32_t foundIdx = 0; switch (MMCO) { case 1: { picNumX = getPicNumX(picture, refPicMarking); foundIdx = findShortRermReference(picNumX); if (foundIdx < 0) return false; i = (uint32_t) foundIdx; setH264PictureReference(DPBLayer->shortRef[i], 0, VAAPI_PICTURE_IS_FRAME(picture)); ARRAY_REMOVE_INDEX(DPBLayer->shortRef, i); } break; case 2: { foundIdx = findLongTermReference(refPicMarking->long_term_pic_num); if (foundIdx < 0) return false; i = (uint32_t) foundIdx; setH264PictureReference(DPBLayer->longRef[i], 0, VAAPI_PICTURE_IS_FRAME(picture)); ARRAY_REMOVE_INDEX(DPBLayer->longRef, i); } break; case 3: { for (i = 0; i < DPBLayer->longRefCount; i++) { if ((int32_t) DPBLayer->longRef[i]->m_longTermFrameIdx == refPicMarking->long_term_frame_idx) break; } if (i != DPBLayer->longRefCount) { setH264PictureReference(DPBLayer->longRef[i], 0, true); ARRAY_REMOVE_INDEX(DPBLayer->longRef, i); } picNumX = getPicNumX(picture, refPicMarking); foundIdx = findShortRermReference(picNumX); if (foundIdx < 0) return false; i = (uint32_t) foundIdx; refPicture = DPBLayer->shortRef[i]; ARRAY_REMOVE_INDEX(DPBLayer->shortRef, i); DPBLayer->longRef[DPBLayer->longRefCount++] = refPicture; refPicture->m_longTermFrameIdx = refPicMarking->long_term_frame_idx; setH264PictureReference(refPicture, VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE, VAAPI_PICTURE_IS_FRAME(picture)); } break; case 4: { longTermFrameIdx = refPicMarking->max_long_term_frame_idx_plus1 - 1; for (i = 0; i < DPBLayer->longRefCount; i++) { if (DPBLayer->longRef[i]->m_longTermFrameIdx <= longTermFrameIdx) continue; setH264PictureReference(DPBLayer->longRef[i], 0, false); ARRAY_REMOVE_INDEX(DPBLayer->longRef, i); i--; } } break; case 5: { flushDPB(); /* The picture shall be inferred to have had frame_num equal to 0 (7.4.3) */ picture->m_frameNum = 0; /* Update TopFieldOrderCnt and BottomFieldOrderCnt (8.2.1) */ if (picture->m_structure != VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD) picture->m_fieldPoc[TOP_FIELD] -= picture->m_POC; if (picture->m_structure != VAAPI_PICTURE_STRUCTURE_TOP_FIELD) picture->m_fieldPoc[BOTTOM_FIELD] -= picture->m_POC; picture->m_POC = 0; if (VAAPI_H264_PICTURE_IS_SHORT_TERM_REFERENCE(picture)) removeShortReference(picture); } break; case 6: { picture->m_longTermFrameIdx = refPicMarking->long_term_frame_idx; setH264PictureReference(picture.get(), VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE, false); } break; default: ERROR("unsupported MMCO type %d", MMCO); break; } return true; }