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); }
Decode_Status VaapiDecoderH264::decodePicture(H264NalUnit * nalu, H264SliceHdr * sliceHdr) { VaapiPictureH264 *picture; Decode_Status status; H264PPS *const pps = sliceHdr->pps; H264SPS *const sps = pps->sequence; status = decodeCurrentPicture(); if (status != DECODE_SUCCESS) return status; if (m_currentPicture) { /* Re-use current picture where the first field was decoded */ picture = m_currentPicture->newField(); if (!picture) { ERROR("failed to allocate field picture"); m_currentPicture = NULL; return DECODE_FAIL; } } else { /*accquire one surface from m_bufPool in base decoder */ picture = new VaapiPictureH264(m_VADisplay, m_VAContext, m_bufPool, VAAPI_PICTURE_STRUCTURE_FRAME); VAAPI_PICTURE_FLAG_SET(picture, VAAPI_PICTURE_FLAG_FF); /* hack code here */ } m_currentPicture = picture; picture->m_pps = pps; status = ensureQuantMatrix(picture); if (status != DECODE_SUCCESS) { ERROR("failed to reset quantizer matrix"); return status; } if (!initPicture(picture, sliceHdr, nalu)) return DECODE_FAIL; if (!fillPicture(picture, sliceHdr, nalu)) return DECODE_FAIL; return DECODE_SUCCESS; }
bool VaapiDecoderVP8::allocNewPicture() { int i; /* Create new picture */ /*accquire one surface from m_bufPool in base decoder */ VaapiPictureVP8 *picture; picture = new VaapiPictureVP8(m_VADisplay, m_VAContext, m_bufPool, VAAPI_PICTURE_STRUCTURE_FRAME); VAAPI_PICTURE_FLAG_SET(picture, VAAPI_PICTURE_FLAG_FF); for (i = 0; i < VP8_MAX_PICTURE_COUNT; i++) { DEBUG("m_pictures[%d] = %p, surfaceID: %x", i, m_pictures[i], m_pictures[i] ? m_pictures[i]->m_surfaceID : VA_INVALID_SURFACE); if (m_pictures[i] && (m_pictures[i] == m_goldenRefPicture || m_pictures[i] == m_altRefPicture || m_pictures[i] == m_lastPicture || m_pictures[i] == m_currentPicture)) continue; if (m_pictures[i]) { delete m_pictures[i]; } m_pictures[i] = picture; break; } if (i == VP8_MAX_PICTURE_COUNT) { delete picture; return false; } replacePicture(m_currentPicture, picture); DEBUG ("i: %d, alloc new picture: %p with surface ID: %x, iq matrix buffer id: %x", i, m_currentPicture, m_currentPicture->m_surfaceID, m_currentPicture->m_iqMatrix->getID()); return true; }
PicturePtr VaapiDPBManager::addDummyPicture(const PicturePtr& pic, int32_t frameNum) { PicturePtr dummyPic(new VaapiDecPictureH264(pic->m_context, pic->m_surface, 0)); if (!dummyPic) return dummyPic; VAAPI_PICTURE_FLAG_SET(dummyPic, (VAAPI_PICTURE_FLAG_SKIPPED | VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE | VAAPI_PICTURE_FLAG_FF)); //FIXME : how do we handle poc if B frame exists. dummyPic->m_POC = INVALID_POC; dummyPic->m_frameNum = frameNum; dummyPic->m_frameNumWrap = frameNum; dummyPic->m_pps = pic->m_pps; dummyPic->m_outputNeeded = false; dummyPic->m_picStructure = VAAPI_PICTURE_STRUCTURE_FRAME; dummyPic->m_structure = dummyPic->m_picStructure; return dummyPic; }
bool VaapiDecoderH264::initPicture(VaapiPictureH264 * picture, H264SliceHdr * sliceHdr, H264NalUnit * nalu) { H264SPS *const sps = sliceHdr->pps->sequence; m_prevFrameNum = m_frameNum; m_frameNum = sliceHdr->frame_num; picture->m_frameNum = m_frameNum; picture->m_frameNumWrap = m_frameNum; picture->m_outputFlag = true; /* XXX: conformant to Annex A only */ picture->m_timeStamp = m_currentPTS; /* Reset decoder state for IDR pictures */ if (nalu->idr_pic_flag) { DEBUG("H264: IDR frame detected"); VAAPI_PICTURE_FLAG_SET(picture, VAAPI_PICTURE_FLAG_IDR); m_DPBManager->flushDPB(); m_prevFrame = NULL; } /* Initialize slice type */ switch (sliceHdr->type % 5) { case H264_P_SLICE: picture->m_type = VAAPI_PICTURE_TYPE_P; break; case H264_B_SLICE: picture->m_type = VAAPI_PICTURE_TYPE_B; break; case H264_I_SLICE: picture->m_type = VAAPI_PICTURE_TYPE_I; break; case H264_SP_SLICE: picture->m_type = VAAPI_PICTURE_TYPE_SP; break; case H264_SI_SLICE: picture->m_type = VAAPI_PICTURE_TYPE_SI; break; } /* Initialize picture structure */ if (!sliceHdr->field_pic_flag) picture->m_picStructure = VAAPI_PICTURE_STRUCTURE_FRAME; else { VAAPI_PICTURE_FLAG_SET(picture, VAAPI_PICTURE_FLAG_INTERLACED); if (!sliceHdr->bottom_field_flag) picture->m_picStructure = VAAPI_PICTURE_STRUCTURE_TOP_FIELD; else picture->m_picStructure = VAAPI_PICTURE_STRUCTURE_BOTTOM_FIELD; } picture->m_structure = picture->m_picStructure; /* Initialize reference flags */ if (nalu->ref_idc) { H264DecRefPicMarking *const decRefPicMarking = &sliceHdr->dec_ref_pic_marking; if (VAAPI_H264_PICTURE_IS_IDR(picture) && decRefPicMarking->long_term_reference_flag) { VAAPI_PICTURE_FLAG_SET(picture, VAAPI_PICTURE_FLAG_LONG_TERM_REFERENCE); } else { VAAPI_PICTURE_FLAG_SET(picture, VAAPI_PICTURE_FLAG_SHORT_TERM_REFERENCE); } } initPicturePOC(picture, sliceHdr); m_DPBManager->initPictureRefs(picture, sliceHdr, m_frameNum); return true; }