* rocDecode/AVC: Added initial B frame support. (#214)

- Basic B frames are decoded clean now.
Этот коммит содержится в:
jeffqjiangNew
2024-02-01 09:58:00 -05:00
коммит произвёл GitHub
родитель 203bd98ccd
Коммит 300be009de
+134 -10
Просмотреть файл
@@ -1580,22 +1580,46 @@ static inline int ComparePicNumDesc(const void *p_pic_info_1, const void *p_pic_
if (pic_num_1 < pic_num_2) {
return 1;
}
if (pic_num_1 > pic_num_2) {
} else if (pic_num_1 > pic_num_2) {
return -1;
} else {
return 0;
}
}
static inline int ComparePocDesc(const void *p_pic_info_1, const void *p_pic_info_2) {
int poc_1 = ((AvcVideoParser::AvcPicture*)p_pic_info_1)->pic_order_cnt;
int poc_2 = ((AvcVideoParser::AvcPicture*)p_pic_info_2)->pic_order_cnt;
if (poc_1 < poc_2) {
return 1;
} else if (poc_1 > poc_2) {
return -1;
} else {
return 0;
}
}
static inline int ComparePocAsc(const void *p_pic_info_1, const void *p_pic_info_2) {
int poc_1 = ((AvcVideoParser::AvcPicture*)p_pic_info_1)->pic_order_cnt;
int poc_2 = ((AvcVideoParser::AvcPicture*)p_pic_info_2)->pic_order_cnt;
if (poc_1 < poc_2) {
return -1;
} else if (poc_1 > poc_2) {
return 1;
} else {
return 0;
}
}
static inline int CompareLongTermPicNumAsc(const void *p_pic_info_1, const void *p_pic_info_2) {
int long_term_pic_num_1 = ((AvcVideoParser::AvcPicture*)p_pic_info_1)->long_term_pic_num;
int long_term_pic_num_2 = ((AvcVideoParser::AvcPicture*)p_pic_info_2)->long_term_pic_num;
if (long_term_pic_num_1 < long_term_pic_num_2) {
return -1;
}
if (long_term_pic_num_1 > long_term_pic_num_2) {
} else if (long_term_pic_num_1 > long_term_pic_num_2) {
return 1;
} else {
return 0;
@@ -1608,6 +1632,9 @@ void AvcVideoParser::SetupReflist() {
AvcSliceHeader *p_slice_header = &slice_header_0_;
int i;
memset(ref_list_0_, 0, sizeof(ref_list_0_));
memset(ref_list_1_, 0, sizeof(ref_list_1_));
// 8.2.4.1. Calculate picture numbers
for (i = 0; i < AVC_MAX_DPB_FRAMES; i++) {
AvcPicture *p_ref_pic = &dpb_buffer_.frame_buffer_list[i];
@@ -1641,7 +1668,7 @@ void AvcVideoParser::SetupReflist() {
// 8.2.4.2 Initialisation process for reference picture lists
if (p_slice_header->slice_type == kAvcSliceTypeP || p_slice_header->slice_type == kAvcSliceTypeP_5) {
if (curr_pic_.pic_structure == kFrame) {
if (curr_pic_.pic_structure == kFrame) { // 8.2.4.2.1
// Group short term ref pictures
int ref_index = 0;
for (i = 0; i < AVC_MAX_DPB_FRAMES; i++) {
@@ -1660,23 +1687,120 @@ void AvcVideoParser::SetupReflist() {
}
}
// Sort short term refs with descending order of pic_num
if (dpb_buffer_.num_short_term) {
if (dpb_buffer_.num_short_term > 1) {
qsort((void*)ref_list_0_, dpb_buffer_.num_short_term, sizeof(AvcPicture), ComparePicNumDesc);
}
// Sort long term refs with ascending order of long_term_pic_num
if (dpb_buffer_.num_long_term) {
if (dpb_buffer_.num_long_term > 1) {
qsort((void*)&ref_list_0_[dpb_buffer_.num_short_term], dpb_buffer_.num_long_term, sizeof(AvcPicture), CompareLongTermPicNumAsc);
}
} else {
} else { // 8.2.4.2.2
std::cout << "Error!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Todo: Add P ref field list init." << std::endl;
}
} else {
std::cout << "Error!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Todo: Add B ref list init." << std::endl;
if (curr_pic_.pic_structure == kFrame) { // 8.2.4.2.3
// RefPicList0
int num_short_term_smaller = 0;
int num_short_term_greater = 0;
int num_long_term = 0;
int ref_index = 0;
// Group short term ref pictures that have smaller POC than the current picture
for (i = 0; i < AVC_MAX_DPB_FRAMES; i++) {
AvcPicture *p_ref_pic = &dpb_buffer_.frame_buffer_list[i];
if (p_ref_pic->is_reference == kUsedForShortTerm && p_ref_pic->pic_order_cnt < curr_pic_.pic_order_cnt) {
ref_list_0_[ref_index] = *p_ref_pic;
num_short_term_smaller++;
ref_index++;
}
}
// Sort in descending order of POC
if (num_short_term_smaller > 1) {
qsort((void*)ref_list_0_, num_short_term_smaller, sizeof(AvcPicture), ComparePocDesc);
}
// Group short term ref pictures that have greater POC than the current picture
for (i = 0; i < AVC_MAX_DPB_FRAMES; i++) {
AvcPicture *p_ref_pic = &dpb_buffer_.frame_buffer_list[i];
if (p_ref_pic->is_reference == kUsedForShortTerm && p_ref_pic->pic_order_cnt > curr_pic_.pic_order_cnt) {
ref_list_0_[ref_index] = *p_ref_pic;
num_short_term_greater++;
ref_index++;
}
}
// Sort in ascending order of POC
if (num_short_term_greater > 1) {
qsort((void*)&ref_list_0_[num_short_term_smaller], num_short_term_greater, sizeof(AvcPicture), ComparePocAsc);
}
// Group long term ref pictures
for (i = 0; i < AVC_MAX_DPB_FRAMES; i++) {
AvcPicture *p_ref_pic = &dpb_buffer_.frame_buffer_list[i];
if (p_ref_pic->is_reference == kUsedForLongTerm) {
ref_list_0_[ref_index] = *p_ref_pic;
num_long_term++;
ref_index++;
}
}
// Sort long term refs with ascending order of long_term_pic_num
if (num_long_term > 1) {
qsort((void*)&ref_list_0_[num_short_term_smaller + num_short_term_greater], num_long_term, sizeof(AvcPicture), CompareLongTermPicNumAsc);
}
// RefPicList1
num_short_term_smaller = 0;
num_short_term_greater = 0;
num_long_term = 0;
ref_index = 0;
// Group short term ref pictures that have greater POC than the current picture
for (i = 0; i < AVC_MAX_DPB_FRAMES; i++) {
AvcPicture *p_ref_pic = &dpb_buffer_.frame_buffer_list[i];
if (p_ref_pic->is_reference == kUsedForShortTerm && p_ref_pic->pic_order_cnt > curr_pic_.pic_order_cnt) {
ref_list_1_[ref_index] = *p_ref_pic;
num_short_term_greater++;
ref_index++;
}
}
// Sort in ascending order of POC
if (num_short_term_greater > 1) {
qsort((void*)ref_list_1_, num_short_term_greater, sizeof(AvcPicture), ComparePocAsc);
}
// Group short term ref pictures that have smaller POC than the current picture
for (i = 0; i < AVC_MAX_DPB_FRAMES; i++) {
AvcPicture *p_ref_pic = &dpb_buffer_.frame_buffer_list[i];
if (p_ref_pic->is_reference == kUsedForShortTerm && p_ref_pic->pic_order_cnt < curr_pic_.pic_order_cnt) {
ref_list_1_[ref_index] = *p_ref_pic;
num_short_term_smaller++;
ref_index++;
}
}
// Sort in descending order of POC
if (num_short_term_smaller > 1) {
qsort((void*)&ref_list_1_[num_short_term_greater], num_short_term_smaller, sizeof(AvcPicture), ComparePocDesc);
}
// Group long term ref pictures
for (i = 0; i < AVC_MAX_DPB_FRAMES; i++) {
AvcPicture *p_ref_pic = &dpb_buffer_.frame_buffer_list[i];
if (p_ref_pic->is_reference == kUsedForLongTerm) {
ref_list_1_[ref_index] = *p_ref_pic;
num_long_term++;
ref_index++;
}
}
// Sort long term refs with ascending order of long_term_pic_num
if (num_long_term > 1) {
qsort((void*)&ref_list_1_[num_short_term_smaller + num_short_term_greater], num_long_term, sizeof(AvcPicture), CompareLongTermPicNumAsc);
}
} else { // 8.2.4.2.4
std::cout << "Error!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Todo: Add B ref field list init." << std::endl;
}
}
// 8.2.4.3 Modification process for reference picture lists
if (p_slice_header->ref_pic_list.ref_pic_list_modification_flag_l0 == 1) {
std::cout << "Error! Todo: Added ref list 0 modification support." << std::endl;
std::cout << "Error!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Todo: Added ref list 0 modification support." << std::endl;
}
if (p_slice_header->slice_type == kAvcSliceTypeB || p_slice_header->slice_type == kAvcSliceTypeB_6) {