[vdpu2]: fix bug: set ref list

tips: listp list0 list1 should reoder by paired when field mode.

Change-Id: Ia1177c95e9d8fdc90293ddf8b16058592d2e0b15
Signed-off-by: Ding Wei <leo.ding@rock-chips.com>
This commit is contained in:
Ding Wei
2019-07-29 15:18:42 +08:00
committed by Herman Chen
parent 38eaa92f63
commit a57fd68ccc
4 changed files with 156 additions and 67 deletions

View File

@@ -259,3 +259,72 @@ MPP_RET adjust_input(H264dVdpuPriv_t *priv,
return ret = MPP_OK;
}
RK_S32 compare_p(const void *a, const void *b)
{
RK_S32 val = 0;
H264dRefsList_t *p0 = (H264dRefsList_t *)a;
H264dRefsList_t *p1 = (H264dRefsList_t *)b;
if (p0->lt_flag && p1->lt_flag) { // inc
val = (p0->ref_picnum > p1->ref_picnum) ? 1 : -1;
} else if (!p0->lt_flag && p1->lt_flag) { // dec
val = 1;
} else if (p0->lt_flag && !p1->lt_flag) { // inc
val = -1;
} else if (!p0->lt_flag && !p1->lt_flag) { // dec
val = (p0->ref_picnum < p1->ref_picnum) ? 1 : -1;
}
return val;
}
RK_S32 compare_b0(const void *a, const void *b)
{
RK_S32 val = 0;
H264dRefsList_t *p0 = (H264dRefsList_t *)a;
H264dRefsList_t *p1 = (H264dRefsList_t *)b;
if (p0->lt_flag && p1->lt_flag) { // inc
val = (p0->ref_picnum > p1->ref_picnum) ? 1 : -1;
} else if (!p0->lt_flag && p1->lt_flag) { // dec
val = 1;
} else if (p0->lt_flag && !p1->lt_flag) { // inc
val = -1;
} else if (!p0->lt_flag && !p1->lt_flag) {
if (MPP_MAX(p0->ref_poc, p1->ref_poc) < p0->cur_poc) { // dec
val = (p0->ref_poc < p1->ref_poc) ? 1 : -1;
} else if (MPP_MIN(p0->ref_poc, p1->ref_poc) > p0->cur_poc) { // inc
val = (p0->ref_poc > p1->ref_poc) ? 1 : -1;
} else {
val = (p0->ref_poc > p1->ref_poc) ? 1 : -1; // inc
}
}
return val;
}
RK_S32 compare_b1(const void *a, const void *b)
{
RK_S32 val = 0;
H264dRefsList_t *p0 = (H264dRefsList_t *)a;
H264dRefsList_t *p1 = (H264dRefsList_t *)b;
if (p0->lt_flag && p1->lt_flag) { // inc
val = (p0->ref_picnum > p1->ref_picnum) ? 1 : -1;
} else if (!p0->lt_flag && p1->lt_flag) {
val = 1;
} else if (p0->lt_flag && !p1->lt_flag) {
val = -1;
} else if (!p0->lt_flag && !p1->lt_flag) {
if (MPP_MIN(p0->ref_poc, p1->ref_poc) > p0->cur_poc) { // inc
val = (p0->ref_poc > p1->ref_poc) ? 1 : -1;
} else if (MPP_MAX(p0->ref_poc, p1->ref_poc) < p0->cur_poc) { // dec
val = (p0->ref_poc < p1->ref_poc) ? 1 : -1;
} else {
val = (p0->ref_poc < p1->ref_poc) ? 1 : -1; // dec
}
}
return val;
}

View File

@@ -236,6 +236,15 @@ typedef struct h264d_vdpu_buf_t {
void *regs;
} H264dVdpuBuf_t;
typedef struct h264d_refs_list_t {
RK_S32 idx;
RK_S32 cur_poc;
RK_S32 lt_flag;
RK_S32 ref_poc;
RK_S32 ref_picnum;
} H264dRefsList_t;
typedef struct h264d_vdpu_reg_ctx_t {
H264dVdpuBuf_t reg_buf[3];
@@ -254,4 +263,10 @@ MPP_RET adjust_input(H264dVdpuPriv_t *priv,
DXVA_Slice_H264_Long *p_long,
DXVA_PicParams_H264_MVC *pp);
RK_S32 compare_p(const void *a, const void *b);
RK_S32 compare_b0(const void *a, const void *b);
RK_S32 compare_b1(const void *a, const void *b);
#endif

View File

@@ -459,47 +459,49 @@ static MPP_RET vdpu1_set_vlc_regs(H264dHalCtx_t *p_hal,
static MPP_RET vdpu1_set_ref_regs(H264dHalCtx_t *p_hal,
H264dVdpu1Regs_t *p_regs)
{
RK_U32 i = 0, j = 0;
MPP_RET ret = MPP_ERR_UNKNOW;
DXVA_Slice_H264_Long *p_long = &p_hal->slice_long[0];
RK_U32 i = 0;
RK_U32 num_refs = 0;
H264dRefsList_t m_lists[3][16];
DXVA_PicParams_H264_MVC *pp = p_hal->pp;
//!< list0 list1 listP
for (j = 0; j < 3; j++) {
for (i = 0; i < 16; i++) {
RK_U16 val = 0;
if (p_hal->pp->field_pic_flag) { //!< field
RK_U32 nn = 0;
nn = p_hal->pp->CurrPic.AssociatedFlag ? (2 * i + 1) : (2 * i);
if (p_long->RefPicList[j][nn].bPicEntry == 0xff) {
val = vdpu_value_list[i];
} else {
val = p_long->RefPicList[j][nn].Index7Bits;
}
} else { //!< frame
if (p_long->RefPicList[j][i].bPicEntry == 0xff) {
val = vdpu_value_list[i];
} else {
val = p_long->RefPicList[j][i].Index7Bits;
}
// init list
memset(m_lists, 0, sizeof(m_lists));
for (i = 0; i < 16; i++) {
m_lists[0][i].idx = i;
m_lists[0][i].cur_poc = pp->CurrPic.AssociatedFlag
? pp->CurrFieldOrderCnt[1] : pp->CurrFieldOrderCnt[0];
RK_U32 ref_flag = pp->UsedForReferenceFlags >> (2 * i) & 0x3;
if (ref_flag) {
num_refs++;
m_lists[0][i].lt_flag = pp->RefFrameList[i].AssociatedFlag;
if (m_lists[0][i].lt_flag) {
m_lists[0][i].ref_picnum = pp->LongTermPicNumList[i];
} else {
m_lists[0][i].ref_picnum = pp->FrameNumList[i];
}
switch (j) {
case 0:
vdpu1_set_refer_pic_list_p(p_regs, i, val);
break;
case 1:
vdpu1_set_refer_pic_list_b0(p_regs, i, val);
break;
case 2:
vdpu1_set_refer_pic_list_b1(p_regs, i, val);
break;
default:
break;
if (ref_flag == 3) {
m_lists[0][i].ref_poc = MPP_MIN(pp->FieldOrderCntList[i][0], pp->FieldOrderCntList[i][1]);
} else if (ref_flag & 0x1) {
m_lists[0][i].ref_poc = pp->FieldOrderCntList[i][0];
} else if (ref_flag & 0x2) {
m_lists[0][i].ref_poc = pp->FieldOrderCntList[i][1];
}
}
}
memcpy(m_lists[1], m_lists[0], sizeof(m_lists[0]));
memcpy(m_lists[2], m_lists[0], sizeof(m_lists[0]));
qsort(m_lists[0], num_refs, sizeof(m_lists[0][0]), compare_p);
qsort(m_lists[1], num_refs, sizeof(m_lists[1][0]), compare_b0);
qsort(m_lists[2], num_refs, sizeof(m_lists[2][0]), compare_b1);
//!< list0 list1 listP
for (i = 0; i < 16; i++) {
vdpu1_set_refer_pic_list_p(p_regs, i, m_lists[0][i].idx);
vdpu1_set_refer_pic_list_b0(p_regs, i, m_lists[1][i].idx);
vdpu1_set_refer_pic_list_b1(p_regs, i, m_lists[2][i].idx);
}
return ret = MPP_OK;
}

View File

@@ -487,46 +487,49 @@ static MPP_RET set_vlc_regs(H264dHalCtx_t *p_hal, H264dVdpuRegs_t *p_regs)
static MPP_RET set_ref_regs(H264dHalCtx_t *p_hal, H264dVdpuRegs_t *p_regs)
{
RK_U32 i = 0, j = 0;
MPP_RET ret = MPP_ERR_UNKNOW;
DXVA_Slice_H264_Long *p_long = &p_hal->slice_long[0];
RK_U32 i = 0;
RK_U32 num_refs = 0;
H264dRefsList_t m_lists[3][16];
DXVA_PicParams_H264_MVC *pp = p_hal->pp;
//!< list0 list1 listP
for (j = 0; j < 3; j++) {
for (i = 0; i < 16; i++) {
RK_U16 val = 0;
if (p_hal->pp->field_pic_flag) { //!< field
RK_U32 nn = 0;
nn = p_hal->pp->CurrPic.AssociatedFlag ? (2 * i + 1) : (2 * i);
if (p_long->RefPicList[j][nn].bPicEntry == 0xff) {
val = vdpu_value_list[i];
} else {
val = p_long->RefPicList[j][nn].Index7Bits;
}
} else { //!< frame
if (p_long->RefPicList[j][i].bPicEntry == 0xff) {
val = vdpu_value_list[i];
} else {
val = p_long->RefPicList[j][i].Index7Bits;
}
// init list
memset(m_lists, 0, sizeof(m_lists));
for (i = 0; i < 16; i++) {
m_lists[0][i].idx = i;
m_lists[0][i].cur_poc = pp->CurrPic.AssociatedFlag
? pp->CurrFieldOrderCnt[1] : pp->CurrFieldOrderCnt[0];
RK_U32 ref_flag = pp->UsedForReferenceFlags >> (2 * i) & 0x3;
if (ref_flag) {
num_refs++;
m_lists[0][i].lt_flag = pp->RefFrameList[i].AssociatedFlag;
if (m_lists[0][i].lt_flag) {
m_lists[0][i].ref_picnum = pp->LongTermPicNumList[i];
} else {
m_lists[0][i].ref_picnum = pp->FrameNumList[i];
}
switch (j) {
case 0:
set_refer_pic_list_p(p_regs, i, val);
break;
case 1:
set_refer_pic_list_b0(p_regs, i, val);
break;
case 2:
set_refer_pic_list_b1(p_regs, i, val);
break;
default:
break;
if (ref_flag == 3) {
m_lists[0][i].ref_poc = MPP_MIN(pp->FieldOrderCntList[i][0], pp->FieldOrderCntList[i][1]);
} else if (ref_flag & 0x1) {
m_lists[0][i].ref_poc = pp->FieldOrderCntList[i][0];
} else if (ref_flag & 0x2) {
m_lists[0][i].ref_poc = pp->FieldOrderCntList[i][1];
}
}
}
memcpy(m_lists[1], m_lists[0], sizeof(m_lists[0]));
memcpy(m_lists[2], m_lists[0], sizeof(m_lists[0]));
qsort(m_lists[0], num_refs, sizeof(m_lists[0][0]), compare_p);
qsort(m_lists[1], num_refs, sizeof(m_lists[1][0]), compare_b0);
qsort(m_lists[2], num_refs, sizeof(m_lists[2][0]), compare_b1);
//!< list0 list1 listP
for (i = 0; i < 16; i++) {
set_refer_pic_list_p(p_regs, i, m_lists[0][i].idx);
set_refer_pic_list_b0(p_regs, i, m_lists[1][i].idx);
set_refer_pic_list_b1(p_regs, i, m_lists[2][i].idx);
}
return ret = MPP_OK;
}