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