cisco / openh264

Open Source H.264 Codec
BSD 2-Clause "Simplified" License
5.45k stars 1.77k forks source link

Differing output from JM reference decoder for B slices #3269

Open wrv opened 4 years ago

wrv commented 4 years ago

The attached .264 file produces a different output from the JM reference decoder at frames 14, 15, 16, and 19. The issue seems to be in the boundary strength calculation for deblocking of macroblock type B_L1_16x16.

In the video, macroblock 5 of frame 15 (POC 30) has type B_L1_16x16 with the list 1 reference pointing to POC 34. The difference in boundary strength calculation leads to a YUV value different from JM. Frames 14 and 16 both depend on frame 15 for their output, so that's why they differ. Frame 19 (POC 38) macroblocks 19 and 44 are both type B_L1_16x16 and also exhibit a different output.

I traced it to where the boundary strengths are calculated in deblocking.cpp:WelsDeblockingMb. The boundary strengths are all set to 0, but in the reference software the first strengths are set to 1 with all other values set to 0, i.e. nBS[0][0] = nBS[1][0] = 0x01010101. The output YUV values are the same in JM whenever we insert the code below before the call to DeblockingInterMb on line 1302:

}
// <new code>
// if iCurMbType == B_L1_16x16
if (iCurMbType == 16392){
      * (uint32_t*)nBS[0][0] = 0x01010101;
      * (uint32_t*)nBS[1][0] = 0x01010101;
}
// </new code>
DeblockingInterMb (pCurDqLayer, pFilter, nBS, iBoundryFlag);
break;

Is this intended, or a potential bug?

Test file: simple.zip

thaytan commented 4 years ago

Any variation from the reference decoder is a bug by definition - there are a few differences like this that still need ironing out.

huili2 commented 4 years ago

@xiaotianshi2 @xiaotiansf do you have any idea on this mismatch? Thanks.

xiaotiansf commented 4 years ago

@huili2 @thaytan I'll investigate this deblocking issue.

xiaotiansf commented 4 years ago

I confirmed that I'll need to update the code to calculate the MB boundary strength for B-slice deblocking.