End of stream flush (#86)
* * rocDecode/HEVC: Added picture output operation in DPB and display callback function.
- To avoid serialization of decode submissions and/or display callback in certain cases, increased DPB buffer size by 1 and tweaked picture bumping procedure.
* * rocDecode/HEVC: Added flushing of the remaining pictures from DPB at the end of decode session.
* * rocDecode/HEVC: Changed output_pic_num to num_output_pics to void some confusion. Set top_field_first to 1.
* * rocDecode/HEVC: Added a few return error checks.
[ROCm/rocdecode commit: 624c3c0f09]
Este cometimento está contido em:
cometido por
GitHub
ascendente
049100d761
cometimento
7035965722
@@ -79,39 +79,52 @@ rocDecStatus HEVCVideoParser::UnInitialize() {
|
||||
|
||||
|
||||
rocDecStatus HEVCVideoParser::ParseVideoData(RocdecSourceDataPacket *p_data) {
|
||||
// Clear DPB output/display buffer number
|
||||
dpb_buffer_.output_pic_num = 0;
|
||||
if (p_data->payload && p_data->payload_size) {
|
||||
// Clear DPB output/display buffer number
|
||||
dpb_buffer_.num_output_pics = 0;
|
||||
|
||||
bool status = ParseFrameData(p_data->payload, p_data->payload_size);
|
||||
if (!status) {
|
||||
ERR(STR("Parser failed!"));
|
||||
return ROCDEC_RUNTIME_ERROR;
|
||||
bool status = ParseFrameData(p_data->payload, p_data->payload_size);
|
||||
if (!status) {
|
||||
ERR(STR("Parser failed!"));
|
||||
return ROCDEC_RUNTIME_ERROR;
|
||||
}
|
||||
|
||||
// Init Roc decoder for the first time or reconfigure the existing decoder
|
||||
if (new_sps_activated_) {
|
||||
FillSeqCallbackFn(&m_sps_[m_active_sps_id_]);
|
||||
new_sps_activated_ = false;
|
||||
}
|
||||
|
||||
// Whenever new sei message found
|
||||
if (pfn_get_sei_message_cb_ && sei_message_count_ > 0) {
|
||||
FillSeiMessageCallbackFn();
|
||||
}
|
||||
|
||||
// Decode the picture
|
||||
if (SendPicForDecode() != PARSER_OK) {
|
||||
ERR(STR("Failed to decode!"));
|
||||
return ROCDEC_RUNTIME_ERROR;
|
||||
}
|
||||
|
||||
// Output decoded pictures from DPB if any are ready
|
||||
if (pfn_display_picture_cb_ && dpb_buffer_.num_output_pics > 0) {
|
||||
if (OutputDecodedPictures() != PARSER_OK) {
|
||||
return ROCDEC_RUNTIME_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
pic_count_++;
|
||||
} else if (!(p_data->flags & ROCDEC_PKT_ENDOFSTREAM)) {
|
||||
// If no payload and EOS is not set, treated as invalid.
|
||||
return ROCDEC_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
// Init Roc decoder for the first time or reconfigure the existing decoder
|
||||
if (new_sps_activated_) {
|
||||
FillSeqCallbackFn(&m_sps_[m_active_sps_id_]);
|
||||
new_sps_activated_ = false;
|
||||
if (p_data->flags & ROCDEC_PKT_ENDOFSTREAM) {
|
||||
if (FlushDpb() != PARSER_OK) {
|
||||
return ROCDEC_RUNTIME_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// Whenever new sei message found
|
||||
if (pfn_get_sei_message_cb_ && sei_message_count_ > 0) {
|
||||
FillSeiMessageCallbackFn();
|
||||
}
|
||||
|
||||
// Decode the picture
|
||||
if (SendPicForDecode() != PARSER_OK) {
|
||||
ERR(STR("Failed to decode!"));
|
||||
return ROCDEC_RUNTIME_ERROR;
|
||||
}
|
||||
|
||||
// Output decoded pictures from DPB if any are ready
|
||||
if (pfn_display_picture_cb_ && dpb_buffer_.output_pic_num > 0) {
|
||||
OutputDecodedPictures();
|
||||
}
|
||||
|
||||
pic_count_++;
|
||||
|
||||
return ROCDEC_SUCCESS;
|
||||
}
|
||||
|
||||
@@ -513,12 +526,14 @@ int HEVCVideoParser::SendPicForDecode() {
|
||||
int HEVCVideoParser::OutputDecodedPictures() {
|
||||
RocdecParserDispInfo disp_info = {0};
|
||||
disp_info.progressive_frame = m_sps_[m_active_sps_id_].profile_tier_level.general_progressive_source_flag;
|
||||
disp_info.top_field_first = 0;
|
||||
disp_info.top_field_first = 1;
|
||||
|
||||
for (int i = 0; i < dpb_buffer_.output_pic_num; i++) {
|
||||
for (int i = 0; i < dpb_buffer_.num_output_pics; i++) {
|
||||
disp_info.picture_index = dpb_buffer_.frame_buffer_list[dpb_buffer_.output_pic_list[i]].pic_idx;
|
||||
pfn_display_picture_cb_(parser_params_.pUserData, &disp_info);
|
||||
}
|
||||
|
||||
dpb_buffer_.num_output_pics = 0;
|
||||
return PARSER_OK;
|
||||
}
|
||||
|
||||
@@ -2171,7 +2186,7 @@ void HEVCVideoParser::InitDpb() {
|
||||
dpb_buffer_.dpb_size = 0;
|
||||
dpb_buffer_.dpb_fullness = 0;
|
||||
dpb_buffer_.num_needed_for_output = 0;
|
||||
dpb_buffer_.output_pic_num = 0;
|
||||
dpb_buffer_.num_output_pics = 0;
|
||||
}
|
||||
|
||||
void HEVCVideoParser::EmptyDpb() {
|
||||
@@ -2183,7 +2198,23 @@ void HEVCVideoParser::EmptyDpb() {
|
||||
}
|
||||
dpb_buffer_.dpb_fullness = 0;
|
||||
dpb_buffer_.num_needed_for_output = 0;
|
||||
dpb_buffer_.output_pic_num = 0;
|
||||
dpb_buffer_.num_output_pics = 0;
|
||||
}
|
||||
|
||||
int HEVCVideoParser::FlushDpb() {
|
||||
dpb_buffer_.num_output_pics = 0;
|
||||
// Bump the remaining pictures
|
||||
while (dpb_buffer_.num_needed_for_output) {
|
||||
if (BumpPicFromDpb() != PARSER_OK) {
|
||||
return PARSER_FAIL;
|
||||
}
|
||||
}
|
||||
if (pfn_display_picture_cb_ && dpb_buffer_.num_output_pics > 0) {
|
||||
if (OutputDecodedPictures() != PARSER_OK) {
|
||||
return PARSER_FAIL;
|
||||
}
|
||||
}
|
||||
return PARSER_OK;
|
||||
}
|
||||
|
||||
int HEVCVideoParser::MarkOutputPictures() {
|
||||
@@ -2321,12 +2352,12 @@ int HEVCVideoParser::BumpPicFromDpb() {
|
||||
}
|
||||
|
||||
// Insert into output/display picture list
|
||||
if (dpb_buffer_.output_pic_num >= HEVC_MAX_DPB_FRAMES) {
|
||||
if (dpb_buffer_.num_output_pics >= HEVC_MAX_DPB_FRAMES) {
|
||||
ERR("Error! DPB output buffer list overflow!");
|
||||
return PARSER_OUT_OF_RANGE;
|
||||
} else {
|
||||
dpb_buffer_.output_pic_list[dpb_buffer_.output_pic_num] = min_poc_pic_idx;
|
||||
dpb_buffer_.output_pic_num++;
|
||||
dpb_buffer_.output_pic_list[dpb_buffer_.num_output_pics] = min_poc_pic_idx;
|
||||
dpb_buffer_.num_output_pics++;
|
||||
}
|
||||
|
||||
return PARSER_OK;
|
||||
|
||||
Criar uma nova questão referindo esta
Bloquear um utilizador