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;
}