2
0

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:
jeffqjiangNew
2023-11-27 13:03:26 -05:00
cometido por GitHub
ascendente 049100d761
cometimento 7035965722
4 ficheiros modificados com 89 adições e 51 eliminações
+66 -35
Ver ficheiro
@@ -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;