From 3e74cd919bcad54cf24ec2b1aaf04e6006c3239a Mon Sep 17 00:00:00 2001 From: jeffqjiangNew <142832361+jeffqjiangNew@users.noreply.github.com> Date: Wed, 1 May 2024 08:29:26 -0400 Subject: [PATCH] AVC: Added support for picture adaptive frame-field (PICAFF) feature. (#325) * * rocDecode/AVC: Added initial field picture decode support. - 7 conformance streams pass. * * rocDecode/AVC: Minor change based on review comment. * * rocDecode/AVC: Fixed an issue with getting the decoded frame buffer index for the second field. - 10 more field conformance streams now pass. * * rocDecode/AVC: Added support for picture adaptive frame-field feature. - 10 more field conformance streams now pass. * * rocDecode/AVC: Added a missing change during last merge. [ROCm/rocdecode commit: d2b742ab4b819a0d9b6c0a64c0736a76a7f1f4e4] --- projects/rocdecode/src/parser/avc_parser.cpp | 16 ++++++++++++++-- projects/rocdecode/src/parser/avc_parser.h | 7 +++++-- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/projects/rocdecode/src/parser/avc_parser.cpp b/projects/rocdecode/src/parser/avc_parser.cpp index 53cbb34a21..c7dda06e5f 100644 --- a/projects/rocdecode/src/parser/avc_parser.cpp +++ b/projects/rocdecode/src/parser/avc_parser.cpp @@ -39,6 +39,7 @@ AvcVideoParser::AvcVideoParser() { slice_info_list_.assign(INIT_SLICE_LIST_NUM, {0}); slice_param_list_.assign(INIT_SLICE_LIST_NUM, {0}); memset(&curr_pic_, 0, sizeof(AvcPicture)); + field_pic_count_ = 0; second_field_ = 0; first_field_pic_idx_ = 0; InitDpb(); @@ -195,10 +196,12 @@ ParserResult AvcVideoParser::ParsePictureData(const uint8_t *p_stream, uint32_t // Start decode process if (num_slices_ == 0) { if (p_slice_header->field_pic_flag) { - second_field_ = pic_count_ & 1; + second_field_ = field_pic_count_ & 1; + field_pic_count_++; } else { second_field_ = 0; } + // Use the data directly from demuxer without copying pic_stream_data_ptr_ = pic_data_buffer_ptr_ + curr_start_code_offset_; // Picture stream data size is calculated as the diff between the frame end and the first slice offset. @@ -270,6 +273,7 @@ ParserResult AvcVideoParser::ParsePictureData(const uint8_t *p_stream, uint32_t case kAvcNalTypeEnd_Of_Stream: { pic_count_ = 0; + field_pic_count_ = 0; break; } @@ -2568,7 +2572,7 @@ ParserResult AvcVideoParser::CheckDpbAndOutput() { ParserResult AvcVideoParser::FindFreeBufInDpb() { int i; - if (!second_field_) { + if (curr_pic_.pic_structure == kFrame || !second_field_) { if (dpb_buffer_.dpb_fullness == dpb_buffer_.dpb_size) { if (BumpPicFromDpb() != PARSER_OK) { return PARSER_FAIL; @@ -2917,6 +2921,14 @@ ParserResult AvcVideoParser::InsertCurrPicIntoDpb() { } else if (curr_pic_.is_reference == kUsedForLongTerm) { dpb_buffer_.num_long_term++; } + + AvcSeqParameterSet *p_sps = &sps_list_[active_sps_id_]; + if (p_sps->frame_mbs_only_flag == 0) { // picture adaptive frame-field (PICAFF) + dpb_buffer_.field_pic_list[i * 2] = curr_pic_; + dpb_buffer_.field_pic_list[i * 2].pic_structure = kTopField; + dpb_buffer_.field_pic_list[i * 2 + 1] = curr_pic_; + dpb_buffer_.field_pic_list[i * 2 + 1].pic_structure = kBottomField; + } } else { if (second_field_ == 0) { diff --git a/projects/rocdecode/src/parser/avc_parser.h b/projects/rocdecode/src/parser/avc_parser.h index 79964990fa..805338c2f0 100644 --- a/projects/rocdecode/src/parser/avc_parser.h +++ b/projects/rocdecode/src/parser/avc_parser.h @@ -128,10 +128,13 @@ protected: int curr_ref_pic_bottom_field_; int max_long_term_frame_idx_; // MaxLongTermFrameIdx - // DPB - AvcPicture curr_pic_; + // Field picture info + uint32_t field_pic_count_; int second_field_; int first_field_pic_idx_; + + // DPB + AvcPicture curr_pic_; DecodedPictureBuffer dpb_buffer_; /*! \brief Function to notify decoder about video format change (new SPS) through callback