Пример #1
0
bool VaapiDecoderH265::decodeCodecData(uint8_t * buf, uint32_t bufSize)
{
    Decode_Status status;
    H265NalUnit nalu;
    H265ParserResult result;
    int32_t i, j;
    uint8_t * nalBuf, numNalu;
    DEBUG("H265: codec data detected");
    if (!buf || bufSize == 0)
        return false;
    if (buf[0] != 1) {
        VideoDecodeBuffer buffer;
        memset(&buffer, 0, sizeof(buffer));
        buffer.data = buf;
        buffer.size = bufSize;
        status = decode(&buffer);
        return status == DECODE_SUCCESS;
    }
    if (bufSize < 24)
        return false;
    nalBuf = &buf[21];
    m_nalLengthSize = (*nalBuf & 0x03) + 1;
    nalBuf++;
    numNalu = *nalBuf & 0x1f;
    nalBuf++;
    for (i = 0; i < numNalu; i++) {
        nalBuf++;
        int cnt = *(nalBuf+1) & 0xf;
        nalBuf += 2;
        for (j = 0; j < cnt; j++) {
            int nalsize = *(nalBuf + 1) + 2;
            if (buf + bufSize - nalBuf < nalsize)
               return false;
            result = h265_parser_identify_nalu_hevc(m_parser,
                                                   nalBuf, 0, nalsize, 2,
                                                   &nalu);
            if (result != H265_PARSER_OK)
                return false;
            status = decodeNalu(&nalu);
            if (status != DECODE_SUCCESS)
                return false;
            nalBuf += nalu.offset + nalu.size;
        }
    }
    m_isnalff = true;
    return true;
}
Пример #2
0
Decode_Status VaapiDecoderH265::decode(VideoDecodeBuffer *buffer)
{
    if (!buffer || !buffer->data) {
        decodeCurrent();
        m_dpb.flush();
        m_prevPicOrderCntMsb = 0;
        m_prevPicOrderCntLsb = 0;
        m_newStream = true;
        m_endOfSequence = false;
        return DECODE_SUCCESS;
    }
    m_currentPTS = buffer->timeStamp;

    Decode_Status status = DECODE_SUCCESS;
    H265ParserResult result;
    H265NalUnit nalu; 
    uint8_t *buf;
    uint32_t bufSize = 0;
    uint32_t i, naluSize, size;
    int32_t ofs = 0;
    uint32_t startCode;

    m_currentPTS = buffer->timeStamp;
    buf = buffer->data;
    size = buffer->size;
    DEBUG("H265: Decode(bufsize =%d, timestamp=%ld)", size, m_currentPTS);
    if (buf == NULL || size == 0) { // got EOS
        INFO("flush-debug got EOS, set all frames output-able");
        return DECODE_SUCCESS;
    }
    do {
        if (m_isnalff || buffer->flag & IS_AVCC) {
            if (size < m_nalLengthSize)
                break;
            naluSize = 0;
            for (i = 0; i < m_nalLengthSize; i++)
                naluSize = (naluSize << 8) | buf[i];
            bufSize = m_nalLengthSize + naluSize;
            if (size < bufSize)
                break;
            result = h265_parser_identify_nalu_hevc(m_parser,
                                                   buf, 0, bufSize,
                                                   m_nalLengthSize, &nalu);
            size -= bufSize;
            buf += bufSize;
        } else {
            if (size < 4)
                break;
            if (buffer->flag & IS_NAL_UNIT) {
                bufSize = buffer->size;
                size = 0;
            } else {
                /* skip the un-used bit before start code */
                ofs = scanForStartCode(buf, 0, size, &startCode);
                if (ofs < 0)
                    break;
                buf += ofs;
                size -= ofs;

                /* find the length of the nal */
                ofs =
                    (size < 7) ? -1 : scanForStartCode(buf, 3, size - 3, NULL);
                if (ofs < 0) {
                    ofs = size - 3;
                }
                bufSize = ofs + 3;
                size -= (ofs + 3);
            }
            result = h265_parser_identify_nalu_unchecked(m_parser,
                                                         buf, 0, bufSize,
                                                         &nalu);
            buf += bufSize;
        }

        //status = getStatus(result);
        if (result == H265_PARSER_OK) {
            status = decodeNalu(&nalu);
        } else {
            ERROR("parser nalu uncheck failed code =%d", status);
        }

    } while (status == DECODE_SUCCESS);


    if (status == DECODE_FORMAT_CHANGE && m_resetContext) {
        WARNING("H265 decoder format change happens");
        m_resetContext = false;
    }

    return status;
}
Decode_Status VaapiDecoderH264::decode(VideoDecodeBuffer * buffer)
{
    Decode_Status status = DECODE_SUCCESS;
    H264ParserResult result;
    H264NalUnit nalu;

    uint8_t *buf;
    uint32_t bufSize = 0;
    uint32_t i, naluSize, size;
    int32_t ofs = 0;
    uint32_t startCode;
    bool isEOS = false;

    m_currentPTS = buffer->timeStamp;
    buf = buffer->data;
    size = buffer->size;

    DEBUG("H264: Decode(bufsize =%d, timestamp=%ld)", size, m_currentPTS);

    do {
        if (m_isAVC) {
            if (size < m_nalLengthSize)
                break;

            naluSize = 0;
            for (i = 0; i < m_nalLengthSize; i++)
                naluSize = (naluSize << 8) | buf[i];

            bufSize = m_nalLengthSize + naluSize;
            if (size < bufSize)
                break;

            result = h264_parser_identify_nalu_avc(&m_parser,
                                                   buf, 0, bufSize,
                                                   m_nalLengthSize, &nalu);

            size -= bufSize;
            buf += bufSize;

        } else {
            if (size < 4)
                break;

            /* skip the un-used bit before start code */
            ofs = scanForStartCode(buf, 0, size, &startCode);
            if (ofs < 0)
                break;

            buf += ofs;
            size -= ofs;

            /* find the length of the nal */
            ofs =
                (size < 7) ? -1 : scanForStartCode(buf, 3, size - 3, NULL);
            if (ofs < 0) {
                ofs = size - 3;
            }

            bufSize = ofs + 3;
            size -= (ofs + 3);

            result = h264_parser_identify_nalu_unchecked(&m_parser,
                                                         buf, 0, bufSize,
                                                         &nalu);

            buf += bufSize;
        }

        status = getStatus(result);
        if (status == DECODE_SUCCESS) {
            status = decodeNalu(&nalu);
        } else {
            ERROR("parser nalu uncheck failed code =%ld", status);
        }

    } while (status == DECODE_SUCCESS);

    if (isEOS && status == DECODE_SUCCESS)
        status = decodeSequenceEnd();

    if (status == DECODE_FORMAT_CHANGE && m_resetContext) {
        WARNING("H264 decoder format change happens");
        m_resetContext = false;
    }

    return status;
}