Decode_Status VaapiDecoderH264::start(VideoConfigBuffer * buffer)
{
    DEBUG("H264: start()");
    Decode_Status status;
    bool gotConfig = false;

    if (buffer->data == NULL || buffer->size == 0) {
        gotConfig = false;
        if ((buffer->flag & HAS_SURFACE_NUMBER)
            && (buffer->flag & HAS_VA_PROFILE)) {
            gotConfig = true;
        }
    } else {
        if (decodeCodecData((uint8_t *) buffer->data, buffer->size)) {
            H264SPS *sps = &(m_parser.sps[0]);
            uint32_t maxSize = getMaxDecFrameBuffering(sps, 1);
            buffer->profile = VAProfileH264Baseline;
            buffer->surfaceNumber = maxSize + H264_EXTRA_SURFACE_NUMBER;
            gotConfig = true;
        } else {
            ERROR("codec data has some error");
            return DECODE_FAIL;
        }
    }

    if (gotConfig) {
        status = VaapiDecoderBase::start(buffer);
        if (status != DECODE_SUCCESS)
            return status;

        m_hasContext = true;
    }

    return DECODE_SUCCESS;
}
Exemple #2
0
ErrVal VUI::BitstreamRestriction::write( HeaderSymbolWriteIf* pcWriteIf ) const
{
  RNOK( pcWriteIf->writeFlag( m_bBitstreamRestrictionFlag,              "VUI: bitstream_restriction_flag"));
  ROFRS( m_bBitstreamRestrictionFlag, Err::m_nOK );

  RNOK( pcWriteIf->writeFlag( getMotionVectorsOverPicBoundariesFlag(),  "VUI: motion_vectors_over_pic_boundaries_flag"));
  RNOK( pcWriteIf->writeUvlc( getMaxBytesPerPicDenom(),                 "VUI: max_bytes_per_pic_denom"));
  RNOK( pcWriteIf->writeUvlc( getMaxBitsPerMbDenom(),                   "VUI: max_bits_per_mb_denom"));
  RNOK( pcWriteIf->writeUvlc( getLog2MaxMvLengthHorizontal(),           "VUI: log2_max_mv_length_horizontal"));
  RNOK( pcWriteIf->writeUvlc( getLog2MaxMvLengthVertical(),             "VUI: log2_max_mv_length_vertical"));
  RNOK( pcWriteIf->writeUvlc( getMaxDecFrameReordering(),               "VUI: max_dec_frame_reordering"));
  RNOK( pcWriteIf->writeUvlc( getMaxDecFrameBuffering(),                "VUI: max_dec_frame_buffering"));
  return Err::m_nOK;
}
void VaapiDPBManager::resetDPB(H264SPS * sps)
{
    m_prevFrameStore.reset();
    uint32_t size = getMaxDecFrameBuffering(sps, 1);
    DPBLayer.reset(new VaapiDecPicBufLayer(size));
}
Decode_Status VaapiDecoderH264::ensureContext(H264PPS * pps)
{
    H264SPS *const sps = pps->sequence;
    VAProfile parsedProfile;
    VaapiChromaType parsedChroma;
    uint32_t mbWidth, mbHeight;
    bool resetContext = false;
    uint32_t DPBSize = 0;
    Decode_Status status;

    m_progressiveSequence = sps->frame_mbs_only_flag;

    if (!m_DPBManager) {
        DPBSize = getMaxDecFrameBuffering(sps, 1);
        m_DPBManager = new VaapiDPBManager(DPBSize);
    }

    VideoConfigBuffer *config = &m_configBuffer;
    parsedProfile = getH264VAProfile(pps);
    if (parsedProfile != m_configBuffer.profile) {
        DEBUG("H264: profile changed: old = %d, new = %d, \n",
              m_configBuffer.profile, parsedProfile);
        m_configBuffer.profile = parsedProfile;
        m_configBuffer.flag |= HAS_VA_PROFILE;
        resetContext = true;
    }

    /*
       parsedChroma = getH264ChromaType(sps);
       if (parsedChroma != m_chromaType) {
       WARNING("ensure context: chroma changed !\n");
       m_chromaType = parsedChroma;
       resetContext = true;
       }
     */

    mbWidth = sps->pic_width_in_mbs_minus1 + 1;
    mbHeight = (sps->pic_height_in_map_units_minus1 + 1) <<
        !sps->frame_mbs_only_flag;

    if (mbWidth != m_mbWidth || mbHeight != m_mbHeight) {
        DEBUG("H264: resolution changed: Orig w=%d, h=%d; New w=%d, h=%d",
              m_mbWidth * 16, m_mbHeight * 16, mbWidth * 16,
              mbHeight * 16);

        m_mbWidth = mbWidth;
        m_mbHeight = mbHeight;
        m_configBuffer.width = mbWidth * 16;
        m_configBuffer.height = mbHeight * 16;
        resetContext = true;
    }

    if (!resetContext && m_hasContext)
        return DECODE_SUCCESS;

    if (!m_hasContext) {
        DPBSize = getMaxDecFrameBuffering(sps, 1);
        m_configBuffer.surfaceNumber = DPBSize + H264_EXTRA_SURFACE_NUMBER;
        m_configBuffer.flag |= HAS_SURFACE_NUMBER;
        status = VaapiDecoderBase::start(&m_configBuffer);
        if (status != DECODE_SUCCESS)
            return status;

        DEBUG("First time to Start VA context");
        m_resetContext = true;
    } else if (resetContext) {
        m_hasContext = false;
        status = VaapiDecoderBase::reset(&m_configBuffer);
        if (status != DECODE_SUCCESS)
            return status;

        if (m_DPBManager)
            m_DPBManager->resetDPB(sps);

        DEBUG("Re-start VA context");
        m_resetContext = true;
    }

    m_hasContext = true;

    if (resetContext)
        return DECODE_FORMAT_CHANGE;

    return DECODE_SUCCESS;
}