diff --git a/cfg/encoder_lowdelay_P_vtm.cfg b/cfg/encoder_lowdelay_P_vtm.cfg index 05e397497277e92803b7f09accf295a0f689338d..331590546bfba77386df88ea66e32e356607cca4 100644 --- a/cfg/encoder_lowdelay_P_vtm.cfg +++ b/cfg/encoder_lowdelay_P_vtm.cfg @@ -17,11 +17,11 @@ GOPSize : 4 # GOP Size (number of B slice = GOPS IntraQPOffset : -1 LambdaFromQpEnable : 1 # see JCTVC-X0038 for suitable parameters for IntraQPOffset, QPoffset, QPOffsetModelOff, QPOffsetModelScale when enabled -# Type POC QPoffset QPOffsetModelOff QPOffsetModelScale CbQPoffset CrQPoffset QPfactor tcOffsetDiv2 betaOffsetDiv2 temporal_id #ref_pics_active #ref_pics reference pictures predict deltaRPS #ref_idcs reference idcs -Frame1: P 1 5 -6.5 0.2590 0 0 1.0 0 0 0 4 4 -1 -5 -9 -13 0 -Frame2: P 2 4 -6.5 0.2590 0 0 1.0 0 0 0 4 4 -1 -2 -6 -10 1 -1 5 1 1 1 0 1 -Frame3: P 3 5 -6.5 0.2590 0 0 1.0 0 0 0 4 4 -1 -3 -7 -11 1 -1 5 0 1 1 1 1 -Frame4: P 4 1 0.0 0.0 0 0 1.0 0 0 0 4 4 -1 -4 -8 -12 1 -1 5 0 1 1 1 1 +# Type POC QPoffset QPOffsetModelOff QPOffsetModelScale CbQPoffset CrQPoffset QPfactor tcOffsetDiv2 betaOffsetDiv2 temporal_id #ref_pics_active_L0 #ref_pics_L0 reference_pictures_L0 #ref_pics_active_L1 #ref_pics_L1 reference_pictures_L1 +Frame1: B 1 5 -6.5 0.2590 0 0 1.0 0 0 0 4 4 1 5 9 13 0 0 +Frame2: B 2 4 -6.5 0.2590 0 0 1.0 0 0 0 4 4 1 2 6 10 0 0 +Frame3: B 3 5 -6.5 0.2590 0 0 1.0 0 0 0 4 4 1 3 7 11 0 0 +Frame4: B 4 1 0.0 0.0 0 0 1.0 0 0 0 4 4 1 4 8 12 0 0 #=========== Motion Search ============= FastSearch : 1 # 0:Full search 1:TZ search diff --git a/cfg/encoder_lowdelay_vtm.cfg b/cfg/encoder_lowdelay_vtm.cfg index 9bba84edce17860bcb30f0cdb315525ed14bd45a..2a681a36aea3252bc086f4b3da5970b5d06128b6 100644 --- a/cfg/encoder_lowdelay_vtm.cfg +++ b/cfg/encoder_lowdelay_vtm.cfg @@ -17,11 +17,11 @@ GOPSize : 4 # GOP Size (number of B slice = GOPS IntraQPOffset : -1 LambdaFromQpEnable : 1 # see JCTVC-X0038 for suitable parameters for IntraQPOffset, QPoffset, QPOffsetModelOff, QPOffsetModelScale when enabled -# Type POC QPoffset QPOffsetModelOff QPOffsetModelScale CbQPoffset CrQPoffset QPfactor tcOffsetDiv2 betaOffsetDiv2 temporal_id #ref_pics_active #ref_pics reference pictures predict deltaRPS #ref_idcs reference idcs -Frame1: B 1 5 -6.5 0.2590 0 0 1.0 0 0 0 4 4 -1 -5 -9 -13 0 -Frame2: B 2 4 -6.5 0.2590 0 0 1.0 0 0 0 4 4 -1 -2 -6 -10 1 -1 5 1 1 1 0 1 -Frame3: B 3 5 -6.5 0.2590 0 0 1.0 0 0 0 4 4 -1 -3 -7 -11 1 -1 5 0 1 1 1 1 -Frame4: B 4 1 0.0 0.0 0 0 1.0 0 0 0 4 4 -1 -4 -8 -12 1 -1 5 0 1 1 1 1 +# Type POC QPoffset QPOffsetModelOff QPOffsetModelScale CbQPoffset CrQPoffset QPfactor tcOffsetDiv2 betaOffsetDiv2 temporal_id #ref_pics_active_L0 #ref_pics_L0 reference_pictures_L0 #ref_pics_active_L1 #ref_pics_L1 reference_pictures_L1 +Frame1: B 1 5 -6.5 0.2590 0 0 1.0 0 0 0 4 4 1 5 9 13 4 4 1 5 9 13 +Frame2: B 2 4 -6.5 0.2590 0 0 1.0 0 0 0 4 4 1 2 6 10 4 4 1 2 6 10 +Frame3: B 3 5 -6.5 0.2590 0 0 1.0 0 0 0 4 4 1 3 7 11 4 4 1 3 7 11 +Frame4: B 4 1 0.0 0.0 0 0 1.0 0 0 0 4 4 1 4 8 12 4 4 1 4 8 12 #=========== Motion Search ============= FastSearch : 1 # 0:Full search 1:TZ search diff --git a/cfg/encoder_randomaccess_vtm.cfg b/cfg/encoder_randomaccess_vtm.cfg index 86dcefd4a1addeb27ef8439a57c5c95992671968..d3e23e2b430e9a42e6c34c7affa5bdff050e0b73 100644 --- a/cfg/encoder_randomaccess_vtm.cfg +++ b/cfg/encoder_randomaccess_vtm.cfg @@ -17,23 +17,23 @@ GOPSize : 16 # GOP Size (number of B slice = GOPS IntraQPOffset : -3 LambdaFromQpEnable : 1 # see JCTVC-X0038 for suitable parameters for IntraQPOffset, QPoffset, QPOffsetModelOff, QPOffsetModelScale when enabled -# Type POC QPoffset QPOffsetModelOff QPOffsetModelScale CbQPoffset CrQPoffset QPfactor tcOffsetDiv2 betaOffsetDiv2 temporal_id #ref_pics_active #ref_pics reference pictures predict deltaRPS #ref_idcs reference idcs -Frame1: B 16 1 0.0 0.0 0 0 1.0 0 0 0 2 3 -16 -24 -32 0 -Frame2: B 8 1 -4.8848 0.2061 0 0 1.0 0 0 1 2 3 -8 -16 8 1 8 4 1 1 0 1 -Frame3: B 4 4 -5.7476 0.2286 0 0 1.0 0 0 2 2 4 -4 -12 4 12 1 4 4 1 1 1 1 -Frame4: B 2 5 -5.90 0.2333 0 0 1.0 0 0 3 2 5 -2 -10 2 6 14 1 2 5 1 1 1 1 1 -Frame5: B 1 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 1 3 7 15 1 1 6 1 0 1 1 1 1 -Frame6: B 3 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -3 1 5 13 1 -2 6 1 1 1 1 1 0 -Frame7: B 6 5 -5.90 0.2333 0 0 1.0 0 0 3 2 4 -2 -6 2 10 1 -3 6 0 1 1 1 1 0 -Frame8: B 5 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -5 1 3 11 1 1 5 1 1 1 1 1 -Frame9: B 7 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -3 -7 1 9 1 -2 6 1 1 1 1 1 0 -Frame10: B 12 4 -5.7476 0.2286 0 0 1.0 0 0 2 2 3 -4 -12 4 1 -5 6 0 0 1 1 1 0 -Frame11: B 10 5 -5.90 0.2333 0 0 1.0 0 0 3 2 4 -2 -10 2 6 1 2 4 1 1 1 1 -Frame12: B 9 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -9 1 3 7 1 1 5 1 1 1 1 1 -Frame13: B 11 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -3 -11 1 5 1 -2 6 1 1 1 1 1 0 -Frame14: B 14 5 -5.90 0.2333 0 0 1.0 0 0 3 2 4 -2 -6 -14 2 1 -3 6 0 1 1 1 1 0 -Frame15: B 13 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -5 -13 1 3 1 1 5 1 1 1 1 1 -Frame16: B 15 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -3 -7 -15 1 1 -2 6 1 1 1 1 1 0 +# Type POC QPoffset QPOffsetModelOff QPOffsetModelScale CbQPoffset CrQPoffset QPfactor tcOffsetDiv2 betaOffsetDiv2 temporal_id #ref_pics_active_L0 #ref_pics_L0 reference_pictures_L0 #ref_pics_active_L1 #ref_pics_L1 reference_pictures_L1 +Frame1: B 16 1 0.0 0.0 0 0 1.0 0 0 0 2 3 16 32 24 2 2 16 32 +Frame2: B 8 1 -4.8848 0.2061 0 0 1.0 0 0 1 2 2 8 16 2 2 -8 8 +Frame3: B 4 4 -5.7476 0.2286 0 0 1.0 0 0 2 2 2 4 12 2 2 -4 -12 +Frame4: B 2 5 -5.90 0.2333 0 0 1.0 0 0 3 2 2 2 10 2 3 -2 -6 -14 +Frame5: B 1 6 -7.1444 0.3 0 0 1.0 0 0 4 2 2 1 -1 2 4 -1 -3 -7 -15 +Frame6: B 3 6 -7.1444 0.3 0 0 1.0 0 0 4 2 2 1 3 2 3 -1 -5 -13 +Frame7: B 6 5 -5.90 0.2333 0 0 1.0 0 0 3 2 2 2 6 2 2 -2 -10 +Frame8: B 5 6 -7.1444 0.3 0 0 1.0 0 0 4 2 2 1 5 2 3 -1 -3 -11 +Frame9: B 7 6 -7.1444 0.3 0 0 1.0 0 0 4 2 3 1 3 7 2 2 -1 -9 +Frame10: B 12 4 -5.7476 0.2286 0 0 1.0 0 0 2 2 2 4 12 2 2 -4 4 +Frame11: B 10 5 -5.90 0.2333 0 0 1.0 0 0 3 2 2 2 10 2 2 -2 -6 +Frame12: B 9 6 -7.1444 0.3 0 0 1.0 0 0 4 2 2 1 9 2 3 -1 -3 -7 +Frame13: B 11 6 -7.1444 0.3 0 0 1.0 0 0 4 2 3 1 3 11 2 2 -1 -5 +Frame14: B 14 5 -5.90 0.2333 0 0 1.0 0 0 3 2 3 2 6 14 2 2 -2 2 +Frame15: B 13 6 -7.1444 0.3 0 0 1.0 0 0 4 2 3 1 5 13 2 2 -1 -3 +Frame16: B 15 6 -7.1444 0.3 0 0 1.0 0 0 4 2 4 1 3 7 15 2 2 -1 1 #=========== Motion Search ============= FastSearch : 1 # 0:Full search 1:TZ search diff --git a/cfg/nonCTC-SliceConfigExamples/encoder_randomaccess_vtm_RasterScanSlice.cfg b/cfg/nonCTC-SliceConfigExamples/encoder_randomaccess_vtm_RasterScanSlice.cfg index 696b74021059863e2ebd111f0beeb9184777c5d0..f24e8c0321c7812a6432662dac7aa00201f80663 100644 --- a/cfg/nonCTC-SliceConfigExamples/encoder_randomaccess_vtm_RasterScanSlice.cfg +++ b/cfg/nonCTC-SliceConfigExamples/encoder_randomaccess_vtm_RasterScanSlice.cfg @@ -17,23 +17,23 @@ GOPSize : 16 # GOP Size (number of B slice = GOPS IntraQPOffset : -3 LambdaFromQpEnable : 1 # see JCTVC-X0038 for suitable parameters for IntraQPOffset, QPoffset, QPOffsetModelOff, QPOffsetModelScale when enabled -# Type POC QPoffset QPOffsetModelOff QPOffsetModelScale CbQPoffset CrQPoffset QPfactor tcOffsetDiv2 betaOffsetDiv2 temporal_id #ref_pics_active #ref_pics reference pictures predict deltaRPS #ref_idcs reference idcs -Frame1: B 16 1 0.0 0.0 0 0 1.0 0 0 0 2 3 -16 -24 -32 0 -Frame2: B 8 1 -4.8848 0.2061 0 0 1.0 0 0 1 2 3 -8 -16 8 1 8 4 1 1 0 1 -Frame3: B 4 4 -5.7476 0.2286 0 0 1.0 0 0 2 2 4 -4 -12 4 12 1 4 4 1 1 1 1 -Frame4: B 2 5 -5.90 0.2333 0 0 1.0 0 0 3 2 5 -2 -10 2 6 14 1 2 5 1 1 1 1 1 -Frame5: B 1 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 1 3 7 15 1 1 6 1 0 1 1 1 1 -Frame6: B 3 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -3 1 5 13 1 -2 6 1 1 1 1 1 0 -Frame7: B 6 5 -5.90 0.2333 0 0 1.0 0 0 3 2 4 -2 -6 2 10 1 -3 6 0 1 1 1 1 0 -Frame8: B 5 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -5 1 3 11 1 1 5 1 1 1 1 1 -Frame9: B 7 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -3 -7 1 9 1 -2 6 1 1 1 1 1 0 -Frame10: B 12 4 -5.7476 0.2286 0 0 1.0 0 0 2 2 3 -4 -12 4 1 -5 6 0 0 1 1 1 0 -Frame11: B 10 5 -5.90 0.2333 0 0 1.0 0 0 3 2 4 -2 -10 2 6 1 2 4 1 1 1 1 -Frame12: B 9 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -9 1 3 7 1 1 5 1 1 1 1 1 -Frame13: B 11 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -3 -11 1 5 1 -2 6 1 1 1 1 1 0 -Frame14: B 14 5 -5.90 0.2333 0 0 1.0 0 0 3 2 4 -2 -6 -14 2 1 -3 6 0 1 1 1 1 0 -Frame15: B 13 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -5 -13 1 3 1 1 5 1 1 1 1 1 -Frame16: B 15 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -3 -7 -15 1 1 -2 6 1 1 1 1 1 0 +# Type POC QPoffset QPOffsetModelOff QPOffsetModelScale CbQPoffset CrQPoffset QPfactor tcOffsetDiv2 betaOffsetDiv2 temporal_id #ref_pics_active_L0 #ref_pics_L0 reference_pictures_L0 #ref_pics_active_L1 #ref_pics_L1 reference_pictures_L1 +Frame1: B 16 1 0.0 0.0 0 0 1.0 0 0 0 2 3 16 32 24 2 2 16 32 +Frame2: B 8 1 -4.8848 0.2061 0 0 1.0 0 0 1 2 2 8 16 2 2 -8 8 +Frame3: B 4 4 -5.7476 0.2286 0 0 1.0 0 0 2 2 2 4 12 2 2 -4 -12 +Frame4: B 2 5 -5.90 0.2333 0 0 1.0 0 0 3 2 2 2 10 2 3 -2 -6 -14 +Frame5: B 1 6 -7.1444 0.3 0 0 1.0 0 0 4 2 2 1 -1 2 4 -1 -3 -7 -15 +Frame6: B 3 6 -7.1444 0.3 0 0 1.0 0 0 4 2 2 1 3 2 3 -1 -5 -13 +Frame7: B 6 5 -5.90 0.2333 0 0 1.0 0 0 3 2 2 2 6 2 2 -2 -10 +Frame8: B 5 6 -7.1444 0.3 0 0 1.0 0 0 4 2 2 1 5 2 3 -1 -3 -11 +Frame9: B 7 6 -7.1444 0.3 0 0 1.0 0 0 4 2 3 1 3 7 2 2 -1 -9 +Frame10: B 12 4 -5.7476 0.2286 0 0 1.0 0 0 2 2 2 4 12 2 2 -4 4 +Frame11: B 10 5 -5.90 0.2333 0 0 1.0 0 0 3 2 2 2 10 2 2 -2 -6 +Frame12: B 9 6 -7.1444 0.3 0 0 1.0 0 0 4 2 2 1 9 2 3 -1 -3 -7 +Frame13: B 11 6 -7.1444 0.3 0 0 1.0 0 0 4 2 3 1 3 11 2 2 -1 -5 +Frame14: B 14 5 -5.90 0.2333 0 0 1.0 0 0 3 2 3 2 6 14 2 2 -2 2 +Frame15: B 13 6 -7.1444 0.3 0 0 1.0 0 0 4 2 3 1 5 13 2 2 -1 -3 +Frame16: B 15 6 -7.1444 0.3 0 0 1.0 0 0 4 2 4 1 3 7 15 2 2 -1 1 #=========== Motion Search ============= FastSearch : 1 # 0:Full search 1:TZ search diff --git a/cfg/nonCTC-SliceConfigExamples/encoder_randomaccess_vtm_RectangularSlice.cfg b/cfg/nonCTC-SliceConfigExamples/encoder_randomaccess_vtm_RectangularSlice.cfg index 06ddb38c304f36e1f6bc43ef8c1beb85be59b4c6..6f4ae96c47c679b6f4f31020d52be51f1763fc5b 100644 --- a/cfg/nonCTC-SliceConfigExamples/encoder_randomaccess_vtm_RectangularSlice.cfg +++ b/cfg/nonCTC-SliceConfigExamples/encoder_randomaccess_vtm_RectangularSlice.cfg @@ -17,23 +17,23 @@ GOPSize : 16 # GOP Size (number of B slice = GOPS IntraQPOffset : -3 LambdaFromQpEnable : 1 # see JCTVC-X0038 for suitable parameters for IntraQPOffset, QPoffset, QPOffsetModelOff, QPOffsetModelScale when enabled -# Type POC QPoffset QPOffsetModelOff QPOffsetModelScale CbQPoffset CrQPoffset QPfactor tcOffsetDiv2 betaOffsetDiv2 temporal_id #ref_pics_active #ref_pics reference pictures predict deltaRPS #ref_idcs reference idcs -Frame1: B 16 1 0.0 0.0 0 0 1.0 0 0 0 2 3 -16 -24 -32 0 -Frame2: B 8 1 -4.8848 0.2061 0 0 1.0 0 0 1 2 3 -8 -16 8 1 8 4 1 1 0 1 -Frame3: B 4 4 -5.7476 0.2286 0 0 1.0 0 0 2 2 4 -4 -12 4 12 1 4 4 1 1 1 1 -Frame4: B 2 5 -5.90 0.2333 0 0 1.0 0 0 3 2 5 -2 -10 2 6 14 1 2 5 1 1 1 1 1 -Frame5: B 1 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 1 3 7 15 1 1 6 1 0 1 1 1 1 -Frame6: B 3 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -3 1 5 13 1 -2 6 1 1 1 1 1 0 -Frame7: B 6 5 -5.90 0.2333 0 0 1.0 0 0 3 2 4 -2 -6 2 10 1 -3 6 0 1 1 1 1 0 -Frame8: B 5 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -5 1 3 11 1 1 5 1 1 1 1 1 -Frame9: B 7 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -3 -7 1 9 1 -2 6 1 1 1 1 1 0 -Frame10: B 12 4 -5.7476 0.2286 0 0 1.0 0 0 2 2 3 -4 -12 4 1 -5 6 0 0 1 1 1 0 -Frame11: B 10 5 -5.90 0.2333 0 0 1.0 0 0 3 2 4 -2 -10 2 6 1 2 4 1 1 1 1 -Frame12: B 9 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -9 1 3 7 1 1 5 1 1 1 1 1 -Frame13: B 11 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -3 -11 1 5 1 -2 6 1 1 1 1 1 0 -Frame14: B 14 5 -5.90 0.2333 0 0 1.0 0 0 3 2 4 -2 -6 -14 2 1 -3 6 0 1 1 1 1 0 -Frame15: B 13 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -5 -13 1 3 1 1 5 1 1 1 1 1 -Frame16: B 15 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -3 -7 -15 1 1 -2 6 1 1 1 1 1 0 +# Type POC QPoffset QPOffsetModelOff QPOffsetModelScale CbQPoffset CrQPoffset QPfactor tcOffsetDiv2 betaOffsetDiv2 temporal_id #ref_pics_active_L0 #ref_pics_L0 reference_pictures_L0 #ref_pics_active_L1 #ref_pics_L1 reference_pictures_L1 +Frame1: B 16 1 0.0 0.0 0 0 1.0 0 0 0 2 3 16 32 24 2 2 16 32 +Frame2: B 8 1 -4.8848 0.2061 0 0 1.0 0 0 1 2 2 8 16 2 2 -8 8 +Frame3: B 4 4 -5.7476 0.2286 0 0 1.0 0 0 2 2 2 4 12 2 2 -4 -12 +Frame4: B 2 5 -5.90 0.2333 0 0 1.0 0 0 3 2 2 2 10 2 3 -2 -6 -14 +Frame5: B 1 6 -7.1444 0.3 0 0 1.0 0 0 4 2 2 1 -1 2 4 -1 -3 -7 -15 +Frame6: B 3 6 -7.1444 0.3 0 0 1.0 0 0 4 2 2 1 3 2 3 -1 -5 -13 +Frame7: B 6 5 -5.90 0.2333 0 0 1.0 0 0 3 2 2 2 6 2 2 -2 -10 +Frame8: B 5 6 -7.1444 0.3 0 0 1.0 0 0 4 2 2 1 5 2 3 -1 -3 -11 +Frame9: B 7 6 -7.1444 0.3 0 0 1.0 0 0 4 2 3 1 3 7 2 2 -1 -9 +Frame10: B 12 4 -5.7476 0.2286 0 0 1.0 0 0 2 2 2 4 12 2 2 -4 4 +Frame11: B 10 5 -5.90 0.2333 0 0 1.0 0 0 3 2 2 2 10 2 2 -2 -6 +Frame12: B 9 6 -7.1444 0.3 0 0 1.0 0 0 4 2 2 1 9 2 3 -1 -3 -7 +Frame13: B 11 6 -7.1444 0.3 0 0 1.0 0 0 4 2 3 1 3 11 2 2 -1 -5 +Frame14: B 14 5 -5.90 0.2333 0 0 1.0 0 0 3 2 3 2 6 14 2 2 -2 2 +Frame15: B 13 6 -7.1444 0.3 0 0 1.0 0 0 4 2 3 1 5 13 2 2 -1 -3 +Frame16: B 15 6 -7.1444 0.3 0 0 1.0 0 0 4 2 4 1 3 7 15 2 2 -1 1 #=========== Motion Search ============= FastSearch : 1 # 0:Full search 1:TZ search diff --git a/cfg/nonCTC-SliceConfigExamples/encoder_randomaccess_vtm_SingleTilePerSlice.cfg b/cfg/nonCTC-SliceConfigExamples/encoder_randomaccess_vtm_SingleTilePerSlice.cfg index 24ee96ef370f52bd25ec37d1c3d38d0af832e145..845a1e9c47c9cb31c7d5b1c7437eddcf1ee31967 100644 --- a/cfg/nonCTC-SliceConfigExamples/encoder_randomaccess_vtm_SingleTilePerSlice.cfg +++ b/cfg/nonCTC-SliceConfigExamples/encoder_randomaccess_vtm_SingleTilePerSlice.cfg @@ -17,23 +17,23 @@ GOPSize : 16 # GOP Size (number of B slice = GOPS IntraQPOffset : -3 LambdaFromQpEnable : 1 # see JCTVC-X0038 for suitable parameters for IntraQPOffset, QPoffset, QPOffsetModelOff, QPOffsetModelScale when enabled -# Type POC QPoffset QPOffsetModelOff QPOffsetModelScale CbQPoffset CrQPoffset QPfactor tcOffsetDiv2 betaOffsetDiv2 temporal_id #ref_pics_active #ref_pics reference pictures predict deltaRPS #ref_idcs reference idcs -Frame1: B 16 1 0.0 0.0 0 0 1.0 0 0 0 2 3 -16 -24 -32 0 -Frame2: B 8 1 -4.8848 0.2061 0 0 1.0 0 0 1 2 3 -8 -16 8 1 8 4 1 1 0 1 -Frame3: B 4 4 -5.7476 0.2286 0 0 1.0 0 0 2 2 4 -4 -12 4 12 1 4 4 1 1 1 1 -Frame4: B 2 5 -5.90 0.2333 0 0 1.0 0 0 3 2 5 -2 -10 2 6 14 1 2 5 1 1 1 1 1 -Frame5: B 1 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 1 3 7 15 1 1 6 1 0 1 1 1 1 -Frame6: B 3 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -3 1 5 13 1 -2 6 1 1 1 1 1 0 -Frame7: B 6 5 -5.90 0.2333 0 0 1.0 0 0 3 2 4 -2 -6 2 10 1 -3 6 0 1 1 1 1 0 -Frame8: B 5 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -5 1 3 11 1 1 5 1 1 1 1 1 -Frame9: B 7 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -3 -7 1 9 1 -2 6 1 1 1 1 1 0 -Frame10: B 12 4 -5.7476 0.2286 0 0 1.0 0 0 2 2 3 -4 -12 4 1 -5 6 0 0 1 1 1 0 -Frame11: B 10 5 -5.90 0.2333 0 0 1.0 0 0 3 2 4 -2 -10 2 6 1 2 4 1 1 1 1 -Frame12: B 9 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -9 1 3 7 1 1 5 1 1 1 1 1 -Frame13: B 11 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -3 -11 1 5 1 -2 6 1 1 1 1 1 0 -Frame14: B 14 5 -5.90 0.2333 0 0 1.0 0 0 3 2 4 -2 -6 -14 2 1 -3 6 0 1 1 1 1 0 -Frame15: B 13 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -5 -13 1 3 1 1 5 1 1 1 1 1 -Frame16: B 15 6 -7.1444 0.3 0 0 1.0 0 0 4 2 5 -1 -3 -7 -15 1 1 -2 6 1 1 1 1 1 0 +# Type POC QPoffset QPOffsetModelOff QPOffsetModelScale CbQPoffset CrQPoffset QPfactor tcOffsetDiv2 betaOffsetDiv2 temporal_id #ref_pics_active_L0 #ref_pics_L0 reference_pictures_L0 #ref_pics_active_L1 #ref_pics_L1 reference_pictures_L1 +Frame1: B 16 1 0.0 0.0 0 0 1.0 0 0 0 2 3 16 32 24 2 2 16 32 +Frame2: B 8 1 -4.8848 0.2061 0 0 1.0 0 0 1 2 2 8 16 2 2 -8 8 +Frame3: B 4 4 -5.7476 0.2286 0 0 1.0 0 0 2 2 2 4 12 2 2 -4 -12 +Frame4: B 2 5 -5.90 0.2333 0 0 1.0 0 0 3 2 2 2 10 2 3 -2 -6 -14 +Frame5: B 1 6 -7.1444 0.3 0 0 1.0 0 0 4 2 2 1 -1 2 4 -1 -3 -7 -15 +Frame6: B 3 6 -7.1444 0.3 0 0 1.0 0 0 4 2 2 1 3 2 3 -1 -5 -13 +Frame7: B 6 5 -5.90 0.2333 0 0 1.0 0 0 3 2 2 2 6 2 2 -2 -10 +Frame8: B 5 6 -7.1444 0.3 0 0 1.0 0 0 4 2 2 1 5 2 3 -1 -3 -11 +Frame9: B 7 6 -7.1444 0.3 0 0 1.0 0 0 4 2 3 1 3 7 2 2 -1 -9 +Frame10: B 12 4 -5.7476 0.2286 0 0 1.0 0 0 2 2 2 4 12 2 2 -4 4 +Frame11: B 10 5 -5.90 0.2333 0 0 1.0 0 0 3 2 2 2 10 2 2 -2 -6 +Frame12: B 9 6 -7.1444 0.3 0 0 1.0 0 0 4 2 2 1 9 2 3 -1 -3 -7 +Frame13: B 11 6 -7.1444 0.3 0 0 1.0 0 0 4 2 3 1 3 11 2 2 -1 -5 +Frame14: B 14 5 -5.90 0.2333 0 0 1.0 0 0 3 2 3 2 6 14 2 2 -2 2 +Frame15: B 13 6 -7.1444 0.3 0 0 1.0 0 0 4 2 3 1 5 13 2 2 -1 -3 +Frame16: B 15 6 -7.1444 0.3 0 0 1.0 0 0 4 2 4 1 3 7 15 2 2 -1 1 #=========== Motion Search ============= FastSearch : 1 # 0:Full search 1:TZ search diff --git a/doc/software-manual.tex b/doc/software-manual.tex index efd734e2126efe1293e303c7385a7ca322d71710..2ecf08b30603ba6418ddfec6bd97164660b8adf2 100644 --- a/doc/software-manual.tex +++ b/doc/software-manual.tex @@ -467,68 +467,47 @@ predict from a frame with a higher temporal id. If a frame with higher temporal IDs is listed among a frame's reference pictures, it is not used, but is kept for possible use in future frames. -\item[]\textbf{num_ref_pics_active}: Size of reference picture lists L0 -and L1, indicating how many reference pictures in each direction that -are used during coding. +\item[]\textbf{num_ref_pics_active_L0}: Number of reference pictures in lists L0 +that are used during coding. -\item[]\textbf{num_ref_pics}: The number of reference pictures kept for -this frame. This includes pictures that are used for reference for the +\item[]\textbf{num_ref_pics_L0}: Size of reference picture list L0. +This includes pictures that are used for reference for the current picture as well as pictures that will be used for reference in the future. -\item[]\textbf{reference_pictures}: A space-separated list of +\item[]\textbf{reference_pictures_L0}: A space-separated list of num_ref_pics integers, specifying the POC of the reference pictures kept, relative the POC of the current frame. The picture list shall be -ordered, first with negative numbers from largest to smallest, followed -by positive numbers from smallest to largest (e.g. \verb|-1 -3 -5 1 3|). -Note that any pictures not supplied in this list will be discarded and +ordered as their intendend order in the L0. +Note that any pictures not supplied in this list and in the list of L1 will be discarded and therefore not available as reference pictures later. -\item[]\textbf{predict}: Defines the value of the syntax element -inter_ref_pic_set_prediction_flag. A value of 0 indicates that the -reference picture set is encoded without inter RPS prediction and the -subsequent parameters deltaRIdx$-1$, deltaRPS, num_ref_idcs and -Reference_idcs are ignored and do not need to be present. A value of 1 -indicates that the reference picture set is encoded with inter -prediction RPS using the subsequent parameters deltaRIdx$-1$, deltaRPS, -num_ref_idcs and Reference_idcs in the line. A value of 2 indicates that -the reference picture set is encoded with inter RPS but only the -deltaRIdx$-1$ parameters is needed. The deltaRPS, num_ref_idcs and -Reference_idcs values are automatically derived by the encoder based on -the POC and refPic values of the current line and the RPS pointed to by -the deltaRIdx$-1$ parameters. - -\item[]\textbf{deltaRIdx$-1$}: The difference between the index of the -curent RPS and the predictor RPS minus 1. - -\item[]\textbf{deltaRPS}: The difference between the POC of the -predictor RPS and POC the current RPS. - -\item[]\textbf{num_ref_idcs}: The number of ref_idcs to encode for the -current RPS. The value is equal to the value of num_ref_pics of the -predictor RPS plus 1. - -\item[]\textbf{reference_idcs}: A space-separated list of num_ref_idcs -integers, specifying the ref idcs of the inter RPS prediction. The value -of ref_idcs may be 0, 1 or 2 indicating that the reference picture is a -reference picture used by the current picture, a reference picture used -for future picture or not a reference picture anymore, respectively. The -first num_ref_pics of ref_idcs correspond to the Reference pictures in -the predictor RPS. The last ref_idcs corresponds to the predictor -picture. -\end{itemize} +\item[]\textbf{num_ref_pics_active_L1}: Number of reference pictures in lists L1 +that are used during coding. + +\item[]\textbf{num_ref_pics_L1}: Size of reference picture list L1. +This includes pictures that are used for reference for the +current picture as well as pictures that will be used for reference in +the future. + +\item[]\textbf{reference_pictures_L1}: A space-separated list of +num_ref_pics integers, specifying the POC of the reference pictures +kept, relative the POC of the current frame. The picture list shall be +ordered as their intendend order in the L1. +Note that any pictures not supplied in this list and in the list of L0 will be discarded and +therefore not available as reference pictures later. For example, consider the coding structure of Figure~\ref{fig:gop-example}. This coding structure is of size 4. The pictures are listed in decoding order. Frame1 shall therefore describe picture with $\textrm{POC}=4$. It -references picture 0, and therefore has $-4$ as a reference picture. +references picture 0, and therefore has 4 as a reference picture. Similarly, Frame2 has a POC of 2, and since it references pictures 0 and -4, its reference pictures are listed as \verb|-2 2|. Frame3 is a special +4, its reference pictures are listed as \verb|2 -2|. Frame3 is a special case: even though it only references pictures with POC 0 and 2, it also needs to include the picture with POC 4, which must be kept in order to -be used as a reference picture in the future. The reference picture list -for Frame3 therefore becomes \verb|-1 1 3|. Frame4 has a POC of 3 and -its list of reference pictures is \verb|-1 1|. +be used as a reference picture in the future. Note that picture with POC 4 can be +included in the L0 or L1. The reference picture list for Frame3 therefore becomes \verb|1 -1 -3|. +Frame4 has a POC of 3 and its list of reference pictures is \verb|1 -1|. \begin{figure}[h] \caption{A GOP structure} @@ -537,27 +516,6 @@ its list of reference pictures is \verb|-1 1|. \includegraphics[width=0.7\textwidth]{figures/gop-structure-example} \end{figure} -Inter RPS prediction may be used for Frame2, Frame3 and Frame4, hence -the predict parameter is set to 1 for these frames. Frame2 uses Frame1 -as the predictor hence the deltaRIdx$-1$ is 0. Similarly for Frame3 and -Frame4 which use Frame2 and Frame3 as predictors, respectively. The -deltaRPS is equal to the POC of the predictor minus the POC of the -current picture, therefore the deltaRPS for Frame2 is $4 -2 = 2$, for -Frame3 is $2 - 1 = 1$ and for Frame4 is $1 - 3 = -2$. - -In Frame2, reference pictures with POC 0 and 2 are used, so the -reference idcs for Frame2 are \verb|1 1| indicating that the reference -picture, $-4$, in Frame1 is still a reference picture in Frame2 and -Frame1 is also a reference picture in Frame2. The reference idcs for -Frame3 are \verb|1 1 1|. The first and second “1â€s indicating that -the reference pictures "$-2$ $2$" in Frame2 are still reference pictures in -Frame3 and the last “1†indicating that Frame2 is also a reference -picture in Frame3. In Frame 4, the reference idcs are \verb|0 1 1 0|. -The first “0†indicates that the reference pictures “-1†in Frame 3 is -no longer a reference picture in Frame4. The next two “1â€s indicate that -the reference pictures “$1$ $3$†are now reference pictures of Frame4. -The final “0†indicates that Frame3 is not a reference picture. - In order to specify this to the encoder, the parameters in Table~\ref{tab:gop-example} could be used. @@ -574,25 +532,23 @@ Table~\ref{tab:gop-example} could be used. \thead{Frame3} & \thead{Frame4} \\ \hline -Type & P & B & B & B \\ -POC & 4 & 2 & 1 & 3 \\ -QPOffset & 1 & 2 & 3 & 3 \\ -QPOffsetModelOff & 0.0 & 0.0 & 0.0 & 0.0 \\ -QPOffsetModelScale & 0.0 & 0.0 & 0.0 & 0.0 \\ -SliceCbQPOffset & 0 & 0 & 0 & 0 \\ -SliceCrQPOffset & 0 & 0 & 0 & 0 \\ -QPfactor & 0.5 & 0.5 & 0.5 & 0.5 \\ -tcOffsetDiv2 & 0 & 1 & 2 & 2 \\ -betaOffsetDiv2 & 0 & 0 & 0 & 0 \\ -temporal_id & 0 & 1 & 2 & 2 \\ -num_ref_pics_active & 1 & 1 & 1 & 1 \\ -num_ref_pics & 1 & 2 & 3 & 2 \\ -reference_pictures & $-$4 & $-$2 2 & $-$1 1 3 & $-$1 1 \\ -predict & 0 & 1 & 1 & 1 \\ -deltaRIdx$-$1 & & 0 & 0 & 0 \\ -deltaRPS & & 2 & 1 & $-$2 \\ -num_ref_idcs & & 2 & 3 & 4 \\ -reference_idcs & & 1 1 & 1 1 1 & 0 1 1 0 \\ +Type & P & B & B & B \\ +POC & 4 & 2 & 1 & 3 \\ +QPOffset & 1 & 2 & 3 & 3 \\ +QPOffsetModelOff & 0.0 & 0.0 & 0.0 & 0.0 \\ +QPOffsetModelScale & 0.0 & 0.0 & 0.0 & 0.0 \\ +SliceCbQPOffset & 0 & 0 & 0 & 0 \\ +SliceCrQPOffset & 0 & 0 & 0 & 0 \\ +QPfactor & 0.5 & 0.5 & 0.5 & 0.5 \\ +tcOffsetDiv2 & 0 & 1 & 2 & 2 \\ +betaOffsetDiv2 & 0 & 0 & 0 & 0 \\ +temporal_id & 0 & 1 & 2 & 2 \\ +num_ref_pics_active_L0 & 1 & 1 & 1 & 1 \\ +num_ref_pics_L0 & 1 & 1 & 1 & 1 \\ +reference_pictures_L0 & 4 & 2 & 1 & 1 \\ +num_ref_pics_active_L1 & 0 & 1 & 1 & 1 \\ +num_ref_pics_L1 & 0 & 1 & 2 & 1 \\ +reference_pictures_L1 & & $-$2 & $-$1 $-$3 & $-$1 \\ \hline \end{tabular} \end{table} @@ -605,51 +561,12 @@ line should contain information for one frame, so this configuration would be specified as: \begin{verbatim} -Frame1: P 4 1 0 0 0.5 0 0 0 1 1 -4 0 -Frame2: B 2 2 0 0 0.5 1 0 1 1 2 -2 2 1 0 2 2 1 1 -Frame3: B 1 3 0 0 0.5 2 0 2 1 3 -1 1 3 1 0 1 3 1 1 1 -Frame4: B 3 3 0 0 0.5 2 0 2 1 2 -1 1 1 0 -2 4 0 1 1 0 +Frame1: P 4 1 0 0 0.5 0 0 0 1 1 4 1 1 4 +Frame2: B 2 2 0 0 0.5 1 0 1 1 1 2 1 1 -2 +Frame3: B 1 3 0 0 0.5 2 0 2 1 1 1 1 2 -1 -3 +Frame4: B 3 3 0 0 0.5 2 0 2 1 1 1 1 1 -1 \end{verbatim} -The values of deltaRIdx$-1$, deltaRPS, num_ref_idcs and reference -idcs of Frame$K$ can be derived from the POC value of Frame$_K$ and -the POC, num_ref_pics and reference_pictures values of Frame$_M$, where -$K$ is the index of the RPS to be inter coded and the $M$ is the -index of the reference RPS, as follows. - -\setlength{\algomargin}{2em} -\begin{algorithm}[ht] -\SetKwData{deltaRIdx}{deltaRIdx} -\SetKwData{deltaRPS}{deltaRPS} -\SetKwData{numrefidcs}{num_ref_idcs} -\SetKwData{numrefpics}{num_ref_pics} -\SetKwData{referencepictures}{reference_pictures} -\SetKwData{referenceidcs}{reference_idcs} -\SetKwData{POC}{POC} - -$\deltaRIdx_K - 1 \leftarrow K - M - 1$ \; -$\deltaRPS_K \leftarrow \POC_M - \POC_K$ \; -$\numrefidcs_K \leftarrow \numrefpics_M + 1$ \; - -\For{$j \leftarrow 0$ \KwTo $\numrefpics_M$}{ - \For{$i \leftarrow 0$ \KwTo $\numrefidcs_K$}{ - \eIf{$\referencepictures_{M,j} + \deltaRPS_K == \referencepictures_{K,i}$}{ - \lIf{$\referencepictures_{K,i}$ is used by the current frame}{ - $\referenceidcs_{K,j} = 1$} \; - \lElse{$\referenceidcs_{K,j} = 2$} \; - }{ - $\referenceidcs_K[j] = 0$ \; - } - } -} - -\tcc{$\referencepictures_{M,\numrefpics_M}$ does not exist and is assumed to be 0} -\end{algorithm} - -Note: The above (automatic) generation of the inter RPS parameter -values has been integrated into the encoder, and is activated by -the value of predict $= 2$ followed by the value of deltaRIdx$-1$, -only, as described above. diff --git a/source/App/EncoderApp/EncApp.cpp b/source/App/EncoderApp/EncApp.cpp index a184009d77f25fa88fddea06e3e40083a846a581..af0e4e7b8b41171412282f7804b49331cda8cd57 100644 --- a/source/App/EncoderApp/EncApp.cpp +++ b/source/App/EncoderApp/EncApp.cpp @@ -177,9 +177,15 @@ void EncApp::xInitLibCfg() m_cEncLib.setGOPSize ( m_iGOPSize ); #if JCTVC_Y0038_PARAMS m_cEncLib.setReWriteParamSets ( m_rewriteParamSets ); +#endif +#if JVET_M0128 + m_cEncLib.setRPLList0 ( m_RPLList0); + m_cEncLib.setRPLList1 ( m_RPLList1); #endif m_cEncLib.setGopList ( m_GOPList ); +#if !JVET_M0128 m_cEncLib.setExtraRPSs ( m_extraRPSs ); +#endif for(int i = 0; i < MAX_TLAYER; i++) { m_cEncLib.setNumReorderPics ( m_numReorderPics[i], i ); diff --git a/source/App/EncoderApp/EncAppCfg.cpp b/source/App/EncoderApp/EncAppCfg.cpp index 59a2d03f5b49b690f30624c4635dec56a010a243..f8feb0fcd096b79626bbd51a483454c94bbbb186 100644 --- a/source/App/EncoderApp/EncAppCfg.cpp +++ b/source/App/EncoderApp/EncAppCfg.cpp @@ -214,7 +214,21 @@ std::istringstream &operator>>(std::istringstream &in, GOPEntry &entry) //in in>>entry.m_tcOffsetDiv2; in>>entry.m_betaOffsetDiv2; in>>entry.m_temporalId; - in>>entry.m_numRefPicsActive; +#if JVET_M0128 + in >> entry.m_numRefPicsActive0; + in >> entry.m_numRefPics0; + for (int i = 0; i < entry.m_numRefPics0; i++) + { + in >> entry.m_deltaRefPics0[i]; + } + in >> entry.m_numRefPicsActive1; + in >> entry.m_numRefPics1; + for (int i = 0; i < entry.m_numRefPics1; i++) + { + in >> entry.m_deltaRefPics1[i]; + } +#else + in >> entry.m_numRefPicsActive; in>>entry.m_numRefPics; for ( int i = 0; i < entry.m_numRefPics; i++ ) { @@ -234,6 +248,7 @@ std::istringstream &operator>>(std::istringstream &in, GOPEntry &entry) //in { in>>entry.m_deltaRPS; } +#endif return in; } @@ -1454,16 +1469,49 @@ bool EncAppCfg::parseCfg( int argc, char* argv[] ) po::ErrorReporter err; const list<const char*>& argv_unhandled = po::scanArgv(opts, argc, (const char**) argv, err); +#if JVET_M0128 + for (int i = 0; m_GOPList[i].m_POC != -1 && i < MAX_GOP + 1; i++) + { + m_RPLList0[i].m_POC = m_RPLList1[i].m_POC = m_GOPList[i].m_POC; + m_RPLList0[i].m_temporalId = m_RPLList1[i].m_temporalId = m_GOPList[i].m_temporalId; + m_RPLList0[i].m_refPic = m_RPLList1[i].m_refPic = m_GOPList[i].m_refPic; + m_RPLList0[i].m_sliceType = m_RPLList1[i].m_sliceType = m_GOPList[i].m_sliceType; + m_RPLList0[i].m_isEncoded = m_RPLList1[i].m_isEncoded = m_GOPList[i].m_isEncoded; + + m_RPLList0[i].m_numRefPicsActive = m_GOPList[i].m_numRefPicsActive0; + m_RPLList1[i].m_numRefPicsActive = m_GOPList[i].m_numRefPicsActive1; + m_RPLList0[i].m_numRefPics = m_GOPList[i].m_numRefPics0; + m_RPLList1[i].m_numRefPics = m_GOPList[i].m_numRefPics1; + for (int j = 0; j < m_GOPList[i].m_numRefPics0; j++) + m_RPLList0[i].m_deltaRefPics[j] = m_GOPList[i].m_deltaRefPics0[j]; + for (int j = 0; j < m_GOPList[i].m_numRefPics1; j++) + m_RPLList1[i].m_deltaRefPics[j] = m_GOPList[i].m_deltaRefPics1[j]; + } +#endif + if (m_compositeRefEnabled) { for (int i = 0; i < m_iGOPSize; i++) { m_GOPList[i].m_POC *= 2; +#if !JVET_M0128 m_GOPList[i].m_deltaRPS *= 2; for (int j = 0; j < m_GOPList[i].m_numRefPics; j++) { m_GOPList[i].m_referencePics[j] *= 2; } +#else + m_RPLList0[i].m_POC *= 2; + m_RPLList1[i].m_POC *= 2; + for (int j = 0; j < m_RPLList0[i].m_numRefPics; j++) + { + m_RPLList0[i].m_deltaRefPics[j] *= 2; + } + for (int j = 0; j < m_RPLList1[i].m_numRefPics; j++) + { + m_RPLList1[i].m_deltaRefPics[j] *= 2; + } +#endif } } @@ -2756,7 +2804,15 @@ bool EncAppCfg::xCheckParameter() m_GOPList[0].m_betaOffsetDiv2 = 0; m_GOPList[0].m_tcOffsetDiv2 = 0; m_GOPList[0].m_POC = 1; +#if JVET_M0128 + m_RPLList0[0] = RPLEntry(); + m_RPLList1[0] = RPLEntry(); + m_RPLList0[0].m_POC = m_RPLList1[0].m_POC = 1; + m_RPLList0[0].m_numRefPicsActive = 4; + m_GOPList[0].m_numRefPicsActive0 = 4; +#else m_GOPList[0].m_numRefPicsActive = 4; +#endif } else { @@ -2813,6 +2869,250 @@ bool EncAppCfg::xCheckParameter() xConfirmPara( abs(m_sliceChromaQpOffsetIntraOrPeriodic[1] + m_crQpOffset ) > 12, "Intra/periodic Cr QP Offset, when combined with the PPS Cr offset, exceeds supported range (-12 to 12)" ); #endif +#if JVET_M0128 + int extraRPLs = 0; + //start looping through frames in coding order until we can verify that the GOP structure is correct. + while (!verifiedGOP && !errorGOP) + { + int curGOP = (checkGOP - 1) % m_iGOPSize; + int curPOC = ((checkGOP - 1) / m_iGOPSize)*m_iGOPSize * multipleFactor + m_RPLList0[curGOP].m_POC; + if (m_RPLList0[curGOP].m_POC < 0 || m_RPLList1[curGOP].m_POC < 0) + { + msg(WARNING, "\nError: found fewer Reference Picture Sets than GOPSize\n"); + errorGOP = true; + } + else + { + //check that all reference pictures are available, or have a POC < 0 meaning they might be available in the next GOP. + bool beforeI = false; + for (int i = 0; i< m_RPLList0[curGOP].m_numRefPics; i++) + { + int absPOC = curPOC - m_RPLList0[curGOP].m_deltaRefPics[i]; + if (absPOC < 0) + { + beforeI = true; + } + else + { + bool found = false; + for (int j = 0; j<numRefs; j++) + { + if (refList[j] == absPOC) + { + found = true; + for (int k = 0; k<m_iGOPSize; k++) + { + if (absPOC % (m_iGOPSize * multipleFactor) == m_RPLList0[k].m_POC % (m_iGOPSize * multipleFactor)) + { + if (m_RPLList0[k].m_temporalId == m_RPLList0[curGOP].m_temporalId) + { + m_RPLList0[k].m_refPic = true; + } + } + } + } + } + if (!found) + { + msg(WARNING, "\nError: ref pic %d is not available for GOP frame %d\n", m_RPLList0[curGOP].m_deltaRefPics[i], curGOP + 1); + errorGOP = true; + } + } + } + if (!beforeI && !errorGOP) + { + //all ref frames were present + if (!isOK[curGOP]) + { + numOK++; + isOK[curGOP] = true; + if (numOK == m_iGOPSize) + { + verifiedGOP = true; + } + } + } + else + { + //create a new RPLEntry for this frame containing all the reference pictures that were available (POC > 0) + m_RPLList0[m_iGOPSize + extraRPLs] = m_RPLList0[curGOP]; + m_RPLList1[m_iGOPSize + extraRPLs] = m_RPLList1[curGOP]; + int newRefs0 = 0; + for (int i = 0; i< m_RPLList0[curGOP].m_numRefPics; i++) + { + int absPOC = curPOC - m_RPLList0[curGOP].m_deltaRefPics[i]; + if (absPOC >= 0) + { + m_RPLList0[m_iGOPSize + extraRPLs].m_deltaRefPics[newRefs0] = m_RPLList0[curGOP].m_deltaRefPics[i]; + newRefs0++; + } + } + int numPrefRefs0 = m_RPLList0[curGOP].m_numRefPicsActive; + + int newRefs1 = 0; + for (int i = 0; i< m_RPLList1[curGOP].m_numRefPics; i++) + { + int absPOC = curPOC - m_RPLList1[curGOP].m_deltaRefPics[i]; + if (absPOC >= 0) + { + m_RPLList1[m_iGOPSize + extraRPLs].m_deltaRefPics[newRefs1] = m_RPLList1[curGOP].m_deltaRefPics[i]; + newRefs1++; + } + } + int numPrefRefs1 = m_RPLList1[curGOP].m_numRefPicsActive; + + for (int offset = -1; offset>-checkGOP; offset--) + { + //step backwards in coding order and include any extra available pictures we might find useful to replace the ones with POC < 0. + int offGOP = (checkGOP - 1 + offset) % m_iGOPSize; + int offPOC = ((checkGOP - 1 + offset) / m_iGOPSize)*(m_iGOPSize * multipleFactor) + m_RPLList0[offGOP].m_POC; + if (offPOC >= 0 && m_RPLList0[offGOP].m_temporalId <= m_RPLList0[curGOP].m_temporalId) + { + bool newRef = false; + for (int i = 0; i<(newRefs0 + newRefs1); i++) + { + if (refList[i] == offPOC) + { + newRef = true; + } + } + for (int i = 0; i<newRefs0; i++) + { + if (m_RPLList0[m_iGOPSize + extraRPLs].m_deltaRefPics[i] == curPOC - offPOC) + { + newRef = false; + } + } + if (newRef) + { + int insertPoint = newRefs0; + //this picture can be added, find appropriate place in list and insert it. + if (m_RPLList0[offGOP].m_temporalId == m_RPLList0[curGOP].m_temporalId) + { + m_RPLList0[offGOP].m_refPic = true; + } + for (int j = 0; j<newRefs0; j++) + { + if (m_RPLList0[m_iGOPSize + extraRPLs].m_deltaRefPics[j] > curPOC - offPOC && curPOC - offPOC > 0) + { + insertPoint = j; + break; + } + } + int prev = curPOC - offPOC; + for (int j = insertPoint; j<newRefs0 + 1; j++) + { + int newPrev = m_RPLList0[m_iGOPSize + extraRPLs].m_deltaRefPics[j]; + m_RPLList0[m_iGOPSize + extraRPLs].m_deltaRefPics[j] = prev; + prev = newPrev; + } + newRefs0++; + } + } + if (newRefs0 >= numPrefRefs0) + { + break; + } + } + + for (int offset = -1; offset>-checkGOP; offset--) + { + //step backwards in coding order and include any extra available pictures we might find useful to replace the ones with POC < 0. + int offGOP = (checkGOP - 1 + offset) % m_iGOPSize; + int offPOC = ((checkGOP - 1 + offset) / m_iGOPSize)*(m_iGOPSize * multipleFactor) + m_RPLList1[offGOP].m_POC; + if (offPOC >= 0 && m_RPLList1[offGOP].m_temporalId <= m_RPLList1[curGOP].m_temporalId) + { + bool newRef = false; + for (int i = 0; i<(newRefs0 + newRefs1); i++) + { + if (refList[i] == offPOC) + { + newRef = true; + } + } + for (int i = 0; i<newRefs1; i++) + { + if (m_RPLList1[m_iGOPSize + extraRPLs].m_deltaRefPics[i] == curPOC - offPOC) + { + newRef = false; + } + } + if (newRef) + { + int insertPoint = newRefs1; + //this picture can be added, find appropriate place in list and insert it. + if (m_RPLList1[offGOP].m_temporalId == m_RPLList1[curGOP].m_temporalId) + { + m_RPLList1[offGOP].m_refPic = true; + } + for (int j = 0; j<newRefs1; j++) + { + if (m_RPLList1[m_iGOPSize + extraRPLs].m_deltaRefPics[j] > curPOC - offPOC && curPOC - offPOC > 0) + { + insertPoint = j; + break; + } + } + int prev = curPOC - offPOC; + for (int j = insertPoint; j<newRefs1 + 1; j++) + { + int newPrev = m_RPLList1[m_iGOPSize + extraRPLs].m_deltaRefPics[j]; + m_RPLList1[m_iGOPSize + extraRPLs].m_deltaRefPics[j] = prev; + prev = newPrev; + } + newRefs1++; + } + } + if (newRefs1 >= numPrefRefs1) + { + break; + } + } + + m_RPLList0[m_iGOPSize + extraRPLs].m_numRefPics = newRefs0; + m_RPLList0[m_iGOPSize + extraRPLs].m_numRefPicsActive = min(m_RPLList0[m_iGOPSize + extraRPLs].m_numRefPics, m_RPLList0[m_iGOPSize + extraRPLs].m_numRefPicsActive); + m_RPLList1[m_iGOPSize + extraRPLs].m_numRefPics = newRefs1; + m_RPLList1[m_iGOPSize + extraRPLs].m_numRefPicsActive = min(m_RPLList1[m_iGOPSize + extraRPLs].m_numRefPics, m_RPLList1[m_iGOPSize + extraRPLs].m_numRefPicsActive); + curGOP = m_iGOPSize + extraRPLs; + extraRPLs++; + } + numRefs = 0; + for (int i = 0; i< m_RPLList0[curGOP].m_numRefPics; i++) + { + int absPOC = curPOC - m_RPLList0[curGOP].m_deltaRefPics[i]; + if (absPOC >= 0) + { + refList[numRefs] = absPOC; + numRefs++; + } + } + for (int i = 0; i< m_RPLList1[curGOP].m_numRefPics; i++) + { + int absPOC = curPOC - m_RPLList1[curGOP].m_deltaRefPics[i]; + if (absPOC >= 0) + { + bool alreadyExist = false; + for (int j = 0; !alreadyExist && j < numRefs; j++) + { + if (refList[j] == absPOC) + { + alreadyExist = true; + } + } + if (!alreadyExist) + { + refList[numRefs] = absPOC; + numRefs++; + } + } + } + refList[numRefs] = curPOC; + numRefs++; + } + checkGOP++; + } + xConfirmPara(errorGOP, "Invalid GOP structure given"); +#else m_extraRPSs=0; //start looping through frames in coding order until we can verify that the GOP structure is correct. while(!verifiedGOP&&!errorGOP) @@ -3008,7 +3308,10 @@ bool EncAppCfg::xCheckParameter() checkGOP++; } xConfirmPara(errorGOP,"Invalid GOP structure given"); +#endif + m_maxTempLayer = 1; + for(int i=0; i<m_iGOPSize; i++) { if(m_GOPList[i].m_temporalId >= m_maxTempLayer) @@ -3024,10 +3327,27 @@ bool EncAppCfg::xCheckParameter() } for(int i=0; i<m_iGOPSize; i++) { +#if JVET_M0128 + int numRefPic = m_RPLList0[i].m_numRefPics; + for (int tmp = 0; tmp < m_RPLList1[i].m_numRefPics; tmp++) + { + bool notSame = true; + for (int jj = 0; notSame && jj < m_RPLList0[i].m_numRefPics; jj++) + { + if (m_RPLList1[i].m_deltaRefPics[tmp] == m_RPLList0[i].m_deltaRefPics[jj]) notSame = false; + } + if (notSame) numRefPic++; + } + if (numRefPic + 1 > m_maxDecPicBuffering[m_GOPList[i].m_temporalId]) + { + m_maxDecPicBuffering[m_GOPList[i].m_temporalId] = numRefPic + 1; + } +#else if(m_GOPList[i].m_numRefPics+1 > m_maxDecPicBuffering[m_GOPList[i].m_temporalId]) { m_maxDecPicBuffering[m_GOPList[i].m_temporalId] = m_GOPList[i].m_numRefPics + 1; } +#endif int highestDecodingNumberWithLowerPOC = 0; for(int j=0; j<m_iGOPSize; j++) { @@ -3050,6 +3370,7 @@ bool EncAppCfg::xCheckParameter() m_numReorderPics[m_GOPList[i].m_temporalId] = numReorder; } } + for(int i=0; i<MAX_TLAYER-1; i++) { // a lower layer can not have higher value of m_numReorderPics than a higher layer diff --git a/source/App/EncoderApp/EncAppCfg.h b/source/App/EncoderApp/EncAppCfg.h index 07789ce25a23c07ecfc64cb54f19e86dc908fb71..903082d70b610da140f7d22c45f92f58d0357a19 100644 --- a/source/App/EncoderApp/EncAppCfg.h +++ b/source/App/EncoderApp/EncAppCfg.h @@ -186,7 +186,12 @@ protected: #if JCTVC_Y0038_PARAMS bool m_rewriteParamSets; ///< Flag to enable rewriting of parameter sets at random access points #endif +#if JVET_M0128 + RPLEntry m_RPLList0[MAX_GOP]; ///< the RPL entries from the config file + RPLEntry m_RPLList1[MAX_GOP]; ///< the RPL entries from the config file +#else int m_extraRPSs; ///< extra RPSs added to handle CRA +#endif GOPEntry m_GOPList[MAX_GOP]; ///< the coding structure entries from the config file #if JVET_N0857_TILES_BRICKS BrickSplit m_brickSplits[MAX_TILES]; diff --git a/source/Lib/CommonLib/Slice.cpp b/source/Lib/CommonLib/Slice.cpp index 8a0e1ecd5e6ac4229a8d6fa35754a93f1b2c787f..ef03c18ec61f9899e747897c21229b7da4deab3f 100644 --- a/source/Lib/CommonLib/Slice.cpp +++ b/source/Lib/CommonLib/Slice.cpp @@ -53,10 +53,15 @@ Slice::Slice() , m_iLastIDR ( 0 ) , m_iAssociatedIRAP ( 0 ) , m_iAssociatedIRAPType ( NAL_UNIT_INVALID ) +#if JVET_M0128 +, m_rpl0Idx ( -1 ) +, m_rpl1Idx ( -1 ) +#else , m_pRPS ( 0 ) , m_localRPS ( ) , m_rpsIdx ( 0 ) , m_RefPicListModification ( ) +#endif , m_eNalUnitType ( NAL_UNIT_CODED_SLICE_IDR_W_RADL ) , m_eSliceType ( I_SLICE ) , m_iSliceQp ( 0 ) @@ -387,6 +392,66 @@ void Slice::setList1IdxToList0Idx() } } +#if JVET_M0128 +void Slice::constructRefPicList(PicList& rcListPic) +{ + ::memset(m_bIsUsedAsLongTerm, 0, sizeof(m_bIsUsedAsLongTerm)); + if (m_eSliceType == I_SLICE) + { + ::memset(m_apcRefPicList, 0, sizeof(m_apcRefPicList)); + ::memset(m_aiNumRefIdx, 0, sizeof(m_aiNumRefIdx)); + return; + } + + Picture* pcRefPic = NULL; + uint32_t numOfActiveRef = 0; + //construct L0 + numOfActiveRef = getNumRefIdx(REF_PIC_LIST_0); + for (int ii = 0; ii < numOfActiveRef; ii++) + { + if (!m_pRPL0->isRefPicLongterm(ii)) + { + pcRefPic = xGetRefPic(rcListPic, getPOC() - m_pRPL0->getRefPicIdentifier(ii)); + pcRefPic->longTerm = false; + } + else + { + int pocBits = getSPS()->getBitsForPOC(); + int pocMask = (1 << pocBits) - 1; + int ltrpPoc = m_pRPL0->getRefPicIdentifier(ii) & pocMask; + ltrpPoc += m_localRPL0.getDeltaPocMSBPresentFlag(ii) ? (pocMask + 1) * m_localRPL0.getDeltaPocMSBCycleLT(ii) : 0; + pcRefPic = xGetLongTermRefPic(rcListPic, ltrpPoc, m_localRPL0.getDeltaPocMSBPresentFlag(ii)); + pcRefPic->longTerm = true; + } + pcRefPic->extendPicBorder(); + m_apcRefPicList[REF_PIC_LIST_0][ii] = pcRefPic; + m_bIsUsedAsLongTerm[REF_PIC_LIST_0][ii] = pcRefPic->longTerm; + } + + //construct L1 + numOfActiveRef = getNumRefIdx(REF_PIC_LIST_1); + for (int ii = 0; ii < numOfActiveRef; ii++) + { + if (!m_pRPL1->isRefPicLongterm(ii)) + { + pcRefPic = xGetRefPic(rcListPic, getPOC() - m_pRPL1->getRefPicIdentifier(ii)); + pcRefPic->longTerm = false; + } + else + { + int pocBits = getSPS()->getBitsForPOC(); + int pocMask = (1 << pocBits) - 1; + int ltrpPoc = m_pRPL1->getRefPicIdentifier(ii) & pocMask; + ltrpPoc += m_localRPL1.getDeltaPocMSBPresentFlag(ii) ? (pocMask + 1) * m_localRPL1.getDeltaPocMSBCycleLT(ii) : 0; + pcRefPic = xGetLongTermRefPic(rcListPic, ltrpPoc, m_localRPL1.getDeltaPocMSBPresentFlag(ii)); + pcRefPic->longTerm = true; + } + pcRefPic->extendPicBorder(); + m_apcRefPicList[REF_PIC_LIST_1][ii] = pcRefPic; + m_bIsUsedAsLongTerm[REF_PIC_LIST_1][ii] = pcRefPic->longTerm; + } +} +#else void Slice::setRefPicList( PicList& rcListPic, bool checkNumPocTotalCurr, bool bCopyL0toL1ErrorCase ) { if ( m_eSliceType == I_SLICE) @@ -563,6 +628,7 @@ int Slice::getNumRpsCurrTempList() const } return numRpsCurrTempList; } +#endif void Slice::initEqualRef() { @@ -602,6 +668,57 @@ void Slice::checkColRefIdx(uint32_t curSliceSegmentIdx, const Picture* pic) } } +#if JVET_M0128 +void Slice::checkCRA(const ReferencePictureList *pRPL0, const ReferencePictureList *pRPL1, int& pocCRA, NalUnitType& associatedIRAPType, PicList& rcListPic) +{ + if (pocCRA < MAX_UINT && getPOC() > pocCRA) + { + uint32_t numRefPic = pRPL0->getNumberOfShorttermPictures() + pRPL0->getNumberOfLongtermPictures(); + for (int i = 0; i < numRefPic; i++) + { + if (!pRPL0->isRefPicLongterm(i)) + { + CHECK(getPOC() - pRPL0->getRefPicIdentifier(i) < pocCRA, "Invalid state"); + } + else + { + CHECK(xGetLongTermRefPic(rcListPic, pRPL0->getRefPicIdentifier(i), pRPL0->getDeltaPocMSBPresentFlag(i))->getPOC() < pocCRA, "Invalid state"); + } + } + numRefPic = pRPL1->getNumberOfShorttermPictures() + pRPL1->getNumberOfLongtermPictures(); + for (int i = 0; i < numRefPic; i++) + { + if (!pRPL1->isRefPicLongterm(i)) + { + CHECK(getPOC() - pRPL1->getRefPicIdentifier(i) < pocCRA, "Invalid state"); + } + else + { + CHECK(xGetLongTermRefPic(rcListPic, pRPL1->getRefPicIdentifier(i), pRPL1->getDeltaPocMSBPresentFlag(i))->getPOC() < pocCRA, "Invalid state"); + } + } + } + if (getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL || getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP) // IDR picture found + { + pocCRA = getPOC(); + associatedIRAPType = getNalUnitType(); + } + else if (getNalUnitType() == NAL_UNIT_CODED_SLICE_CRA) // CRA picture found + { + pocCRA = getPOC(); + associatedIRAPType = getNalUnitType(); + } +#if !JVET_M0101_HLS + else if (getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_LP + || getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_W_RADL + || getNalUnitType() == NAL_UNIT_CODED_SLICE_BLA_N_LP) // BLA picture found + { + pocCRA = getPOC(); + associatedIRAPType = getNalUnitType(); + } +#endif +} +#else void Slice::checkCRA(const ReferencePictureSet *pReferencePictureSet, int& pocCRA, NalUnitType& associatedIRAPType, PicList& rcListPic) { for(int i = 0; i < pReferencePictureSet->getNumberOfNegativePictures()+pReferencePictureSet->getNumberOfPositivePictures(); i++) @@ -645,6 +762,7 @@ void Slice::checkCRA(const ReferencePictureSet *pReferencePictureSet, int& pocCR } #endif } +#endif /** Function for marking the reference pictures when an IDR/CRA/CRANT/BLA/BLANT is encountered. * \param pocCRA POC of the CRA/CRANT/BLA/BLANT picture @@ -806,7 +924,12 @@ void Slice::copySliceInfo(Slice *pSrc, bool cpyAlmostAll) if( cpyAlmostAll ) m_iDepth = pSrc->m_iDepth; // access channel +#if JVET_M0128 + if (cpyAlmostAll) m_pRPL0 = pSrc->m_pRPL0; + if (cpyAlmostAll) m_pRPL1 = pSrc->m_pRPL1; +#else if( cpyAlmostAll ) m_pRPS = pSrc->m_pRPS; +#endif m_iLastIDR = pSrc->m_iLastIDR; if( cpyAlmostAll ) m_pcPic = pSrc->m_pcPic; @@ -1178,6 +1301,7 @@ void Slice::checkLeadingPictureRestrictions(PicList& rcListPic) const +#if !JVET_M0128 /** Function for applying picture marking based on the Reference Picture Set in pReferencePictureSet. */ void Slice::applyReferencePictureSet( PicList& rcListPic, const ReferencePictureSet *pReferencePictureSet) const @@ -1629,6 +1753,330 @@ void Slice::createExplicitReferencePictureSetFromReference(PicList& rcListPic, c this->setRPS(pLocalRPS); this->setRPSidx(-1); } +#endif + +#if JVET_M0128 +//Function for applying picture marking based on the Reference Picture List +void Slice::applyReferencePictureListBasedMarking(PicList& rcListPic, const ReferencePictureList *pRPL0, const ReferencePictureList *pRPL1) const +{ + int i, isReference; + checkLeadingPictureRestrictions(rcListPic); + + bool isNeedToCheck = (this->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_N_LP || this->getNalUnitType() == NAL_UNIT_CODED_SLICE_IDR_W_RADL) ? false : true; + + // loop through all pictures in the reference picture buffer + PicList::iterator iterPic = rcListPic.begin(); + while (iterPic != rcListPic.end()) + { + Picture* pcPic = *(iterPic++); + + if (!pcPic->referenced) + continue; + + isReference = 0; + // loop through all pictures in the Reference Picture Set + // to see if the picture should be kept as reference picture + for (i = 0; isNeedToCheck && !isReference && i<pRPL0->getNumberOfShorttermPictures() + pRPL0->getNumberOfLongtermPictures(); i++) + { + if (!(pRPL0->isRefPicLongterm(i))) + { + if (pcPic->poc == this->getPOC() - pRPL0->getRefPicIdentifier(i)) + { + isReference = 1; + pcPic->longTerm = false; + } + } + else + { + int pocCycle = 1 << (pcPic->cs->sps->getBitsForPOC()); + int curPoc = pcPic->poc & (pocCycle - 1); + if (pcPic->longTerm && curPoc == pRPL0->getRefPicIdentifier(i)) + { + isReference = 1; + pcPic->longTerm = true; + } + } + } + for (i = 0; isNeedToCheck && !isReference && i<pRPL1->getNumberOfShorttermPictures() + pRPL1->getNumberOfLongtermPictures(); i++) + { + if (!(pRPL1->isRefPicLongterm(i))) + { + if (pcPic->poc == this->getPOC() - pRPL1->getRefPicIdentifier(i)) + { + isReference = 1; + pcPic->longTerm = false; + } + } + else + { + int pocCycle = 1 << (pcPic->cs->sps->getBitsForPOC()); + int curPoc = pcPic->poc & (pocCycle - 1); + if (pcPic->longTerm && curPoc == pRPL1->getRefPicIdentifier(i)) + { + isReference = 1; + pcPic->longTerm = true; + } + } + } + // mark the picture as "unused for reference" if it is not in + // the Reference Picture List + if (pcPic->poc != this->getPOC() && isReference == 0) + { + pcPic->referenced = false; + pcPic->longTerm = false; + } + + // sanity checks + if (pcPic->referenced) + { + //check that pictures of higher temporal layers are not used + CHECK(pcPic->usedByCurr && !(pcPic->layer <= this->getTLayer()), "Invalid state"); + } + } +} + +int Slice::checkThatAllRefPicsAreAvailable(PicList& rcListPic, const ReferencePictureList *pRPL, int rplIdx, bool printErrors) const +{ + Picture* rpcPic; + int isAvailable = 0; + int notPresentPoc = 0; + + if (this->isIDRorBLA()) return 0; //Assume that all pic in the DPB will be flushed anyway so no need to check. + + int numberOfPictures = pRPL->getNumberOfLongtermPictures() + pRPL->getNumberOfShorttermPictures(); + //Check long term ref pics + for (int ii = 0; pRPL->getNumberOfLongtermPictures() > 0 && ii < numberOfPictures; ii++) + { + if (!pRPL->isRefPicLongterm(ii)) + continue; + + notPresentPoc = pRPL->getRefPicIdentifier(ii); + isAvailable = 0; + PicList::iterator iterPic = rcListPic.begin(); + while (iterPic != rcListPic.end()) + { + rpcPic = *(iterPic++); + int pocCycle = 1 << (rpcPic->cs->sps->getBitsForPOC()); + int curPoc = rpcPic->getPOC() & (pocCycle - 1); + int refPoc = pRPL->getRefPicIdentifier(ii) & (pocCycle - 1); + if (rpcPic->longTerm && curPoc == refPoc && rpcPic->referenced) + { + isAvailable = 1; + break; + } + } + // if there was no such long-term check the short terms + if (!isAvailable) + { + iterPic = rcListPic.begin(); + while (iterPic != rcListPic.end()) + { + rpcPic = *(iterPic++); + int pocCycle = 1 << (rpcPic->cs->sps->getBitsForPOC()); + int curPoc = rpcPic->getPOC() & (pocCycle - 1); + int refPoc = pRPL->getRefPicIdentifier(ii) & (pocCycle - 1); + if (!rpcPic->longTerm && curPoc == refPoc && rpcPic->referenced) + { + isAvailable = 1; + rpcPic->longTerm = true; + break; + } + } + } + if (!isAvailable) + { + if (printErrors) + { + msg(ERROR, "\nCurrent picture: %d Long-term reference picture with POC = %3d seems to have been removed or not correctly decoded.", this->getPOC(), notPresentPoc); + } + return notPresentPoc; + } + } + //report that a picture is lost if it is in the Reference Picture List but not in the DPB + + isAvailable = 0; + //Check short term ref pics + for (int ii = 0; ii < numberOfPictures; ii++) + { + if (pRPL->isRefPicLongterm(ii)) + continue; + + notPresentPoc = this->getPOC() - pRPL->getRefPicIdentifier(ii); + isAvailable = 0; + PicList::iterator iterPic = rcListPic.begin(); + while (iterPic != rcListPic.end()) + { + rpcPic = *(iterPic++); + if (!rpcPic->longTerm && rpcPic->getPOC() == this->getPOC() - pRPL->getRefPicIdentifier(ii) && rpcPic->referenced) + { + isAvailable = 1; + break; + } + } + //report that a picture is lost if it is in the Reference Picture List but not in the DPB + if (isAvailable == 0 && pRPL->getNumberOfShorttermPictures() > 0) + { + if (printErrors) + { + msg(ERROR, "\nCurrent picture: %d Short-term reference picture with POC = %3d seems to have been removed or not correctly decoded.", this->getPOC(), notPresentPoc); + } + return notPresentPoc; + } + } + return 0; +} + +void Slice::createExplicitReferencePictureSetFromReference(PicList& rcListPic, const ReferencePictureList *pRPL0, const ReferencePictureList *pRPL1) +{ + Picture* rpcPic; + int pocCycle = 0; + + + ReferencePictureList* pLocalRPL0 = this->getLocalRPL0(); + (*pLocalRPL0) = ReferencePictureList(); + + uint32_t numOfSTRPL0 = 0; + uint32_t numOfLTRPL0 = 0; + uint32_t numOfRefPic = pRPL0->getNumberOfShorttermPictures() + pRPL0->getNumberOfLongtermPictures(); + uint32_t refPicIdxL0 = 0; + for (int ii = 0; ii < numOfRefPic; ii++) + { + // loop through all pictures in the reference picture buffer + PicList::iterator iterPic = rcListPic.begin(); + bool isAvailable = false; + + pocCycle = 1 << (this->getSPS()->getBitsForPOC()); + while (iterPic != rcListPic.end()) + { + rpcPic = *(iterPic++); + if (!pRPL0->isRefPicLongterm(ii) && rpcPic->referenced && rpcPic->getPOC() == this->getPOC() - pRPL0->getRefPicIdentifier(ii)) + { + isAvailable = true; + break; + } + else if (pRPL0->isRefPicLongterm(ii) && rpcPic->referenced && (rpcPic->getPOC() & (pocCycle - 1)) == pRPL0->getRefPicIdentifier(ii)) + { + isAvailable = true; + break; + } + } + if (isAvailable) + { + pLocalRPL0->setRefPicIdentifier(refPicIdxL0, pRPL0->getRefPicIdentifier(ii), pRPL0->isRefPicLongterm(ii)); + refPicIdxL0++; + numOfSTRPL0 = numOfSTRPL0 + ((pRPL0->isRefPicLongterm(ii)) ? 0 : 1); + numOfLTRPL0 = numOfLTRPL0 + ((pRPL0->isRefPicLongterm(ii)) ? 1 : 0); + isAvailable = false; + } + } + + ReferencePictureList* pLocalRPL1 = this->getLocalRPL1(); + (*pLocalRPL1) = ReferencePictureList(); + + uint32_t numOfSTRPL1 = 0; + uint32_t numOfLTRPL1 = 0; + numOfRefPic = pRPL1->getNumberOfShorttermPictures() + pRPL1->getNumberOfLongtermPictures(); + uint32_t refPicIdxL1 = 0; + for (int ii = 0; ii < numOfRefPic; ii++) + { + // loop through all pictures in the reference picture buffer + PicList::iterator iterPic = rcListPic.begin(); + bool isAvailable = false; + pocCycle = 1 << (this->getSPS()->getBitsForPOC()); + while (iterPic != rcListPic.end()) + { + rpcPic = *(iterPic++); + if (!pRPL1->isRefPicLongterm(ii) && rpcPic->referenced && rpcPic->getPOC() == this->getPOC() - pRPL1->getRefPicIdentifier(ii)) + { + isAvailable = true; + break; + } + else if (pRPL1->isRefPicLongterm(ii) && rpcPic->referenced && (rpcPic->getPOC() & (pocCycle - 1)) == pRPL1->getRefPicIdentifier(ii)) + { + isAvailable = true; + break; + } + } + if (isAvailable) + { + pLocalRPL1->setRefPicIdentifier(refPicIdxL1, pRPL1->getRefPicIdentifier(ii), pRPL1->isRefPicLongterm(ii)); + refPicIdxL1++; + numOfSTRPL1 = numOfSTRPL1 + ((pRPL1->isRefPicLongterm(ii)) ? 0 : 1); + numOfLTRPL1 = numOfLTRPL1 + ((pRPL1->isRefPicLongterm(ii)) ? 1 : 0); + isAvailable = false; + } + } + + //Copy from L1 if we have less than active ref pic + int numOfNeedToFill = pRPL0->getNumberOfActivePictures() - (numOfLTRPL0 + numOfSTRPL0); + bool isDisallowMixedRefPic = (this->getSPS()->getAllActiveRplEntriesHasSameSignFlag()) ? true : false; + int originalL0StrpNum = numOfSTRPL0; + int originalL0LtrpNum = numOfLTRPL0; + for (int ii = 0; numOfNeedToFill > 0 && ii < (pLocalRPL1->getNumberOfLongtermPictures() + pLocalRPL1->getNumberOfShorttermPictures()); ii++) + { + if (ii <= (numOfLTRPL1 + numOfSTRPL1 - 1)) + { + //Make sure this copy is not already in L0 + bool canIncludeThis = true; + for (int jj = 0; jj < refPicIdxL0; jj++) + { + if ((pLocalRPL1->getRefPicIdentifier(ii) == pLocalRPL0->getRefPicIdentifier(jj)) && (pLocalRPL1->isRefPicLongterm(ii) == pLocalRPL0->isRefPicLongterm(jj))) + canIncludeThis = false; + bool sameSign = (pLocalRPL1->getRefPicIdentifier(ii) > 0) == (pLocalRPL0->getRefPicIdentifier(0) > 0); + if (isDisallowMixedRefPic && canIncludeThis && !pLocalRPL1->isRefPicLongterm(ii) && !sameSign) + canIncludeThis = false; + } + if (canIncludeThis) + { + pLocalRPL0->setRefPicIdentifier(refPicIdxL0, pLocalRPL1->getRefPicIdentifier(ii), pLocalRPL1->isRefPicLongterm(ii)); + refPicIdxL0++; + numOfSTRPL0 = numOfSTRPL0 + ((pRPL1->isRefPicLongterm(ii)) ? 0 : 1); + numOfLTRPL0 = numOfLTRPL0 + ((pRPL1->isRefPicLongterm(ii)) ? 1 : 0); + + numOfNeedToFill--; + } + } + } + pLocalRPL0->setNumberOfLongtermPictures(numOfLTRPL0); + pLocalRPL0->setNumberOfShorttermPictures(numOfSTRPL0); + pLocalRPL0->setNumberOfActivePictures((numOfLTRPL0 + numOfSTRPL0 < pRPL0->getNumberOfActivePictures()) ? numOfLTRPL0 + numOfSTRPL0 : pRPL0->getNumberOfActivePictures()); + this->setRPL0idx(-1); + this->setRPL0(pLocalRPL0); + + //Copy from L0 if we have less than active ref pic + numOfNeedToFill = pLocalRPL0->getNumberOfActivePictures() - (numOfLTRPL1 + numOfSTRPL1); + for (int ii = 0; numOfNeedToFill > 0 && ii < (pLocalRPL0->getNumberOfLongtermPictures() + pLocalRPL0->getNumberOfShorttermPictures()); ii++) + { + if (ii <= (originalL0StrpNum + originalL0LtrpNum - 1)) + { + //Make sure this copy is not already in L0 + bool canIncludeThis = true; + for (int jj = 0; jj < refPicIdxL1; jj++) + { + if ((pLocalRPL0->getRefPicIdentifier(ii) == pLocalRPL1->getRefPicIdentifier(jj)) && (pLocalRPL0->isRefPicLongterm(ii) == pLocalRPL1->isRefPicLongterm(jj))) + canIncludeThis = false; + bool sameSign = (pLocalRPL0->getRefPicIdentifier(ii) > 0) == (pLocalRPL1->getRefPicIdentifier(0) > 0); + if (isDisallowMixedRefPic && canIncludeThis && !pLocalRPL0->isRefPicLongterm(ii) && !sameSign) + canIncludeThis = false; + } + if (canIncludeThis) + { + pLocalRPL1->setRefPicIdentifier(refPicIdxL1, pLocalRPL0->getRefPicIdentifier(ii), pLocalRPL0->isRefPicLongterm(ii)); + refPicIdxL1++; + numOfSTRPL1 = numOfSTRPL1 + ((pRPL0->isRefPicLongterm(ii)) ? 0 : 1); + numOfLTRPL1 = numOfLTRPL1 + ((pRPL0->isRefPicLongterm(ii)) ? 1 : 0); + + numOfNeedToFill--; + } + } + } + pLocalRPL1->setNumberOfLongtermPictures(numOfLTRPL1); + pLocalRPL1->setNumberOfShorttermPictures(numOfSTRPL1); + pLocalRPL1->setNumberOfActivePictures((isDisallowMixedRefPic) ? (numOfLTRPL1 + numOfSTRPL1) : (((numOfLTRPL1 + numOfSTRPL1) < pRPL1->getNumberOfActivePictures()) ? (numOfLTRPL1 + numOfSTRPL1) : pRPL1->getNumberOfActivePictures())); + this->setRPL1idx(-1); + this->setRPL1(pLocalRPL1); +} +#endif //! get AC and DC values for weighted pred void Slice::getWpAcDcParam(const WPACDCParam *&wp) const @@ -1733,7 +2181,11 @@ unsigned Slice::getMinPictureDistance() const { for (int refIdx = 0; refIdx < getNumRefIdx(REF_PIC_LIST_1); refIdx++) { +#if JVET_M0128 //[HD] Please check if this is correct. Seems like a software bug to me. + minPicDist = std::min(minPicDist, std::abs(currPOC - getRefPic(REF_PIC_LIST_1, refIdx)->getPOC())); +#else minPicDist = std::min( minPicDist, std::abs(currPOC - getRefPic(REF_PIC_LIST_0, refIdx)->getPOC())); +#endif } } } @@ -1886,6 +2338,13 @@ SPS::SPS() , m_uiMaxCUWidth ( 32) , m_uiMaxCUHeight ( 32) , m_uiMaxCodingDepth ( 3) +#if JVET_M0128 +, m_numRPL0 ( 0 ) +, m_numRPL1 ( 0 ) +, m_rpl1CopyFromRpl0Flag ( false ) +, m_rpl1IdxPresentFlag ( false ) +, m_allRplEntriesHasSameSignFlag ( true ) +#endif , m_bLongTermRefsPresent (false) // Tool list , m_pcmEnabledFlag (false) @@ -1956,15 +2415,34 @@ SPS::SPS() SPS::~SPS() { +#if !JVET_M0128 m_RPSList.destroy(); +#endif } +#if JVET_M0128 +void SPS::createRPLList0(int numRPL) +{ + m_RPLList0.destroy(); + m_RPLList0.create(numRPL); + m_numRPL0 = numRPL; + m_rpl1IdxPresentFlag = (m_numRPL0 != m_numRPL1) ? true : false; +} +void SPS::createRPLList1(int numRPL) +{ + m_RPLList1.destroy(); + m_RPLList1.create(numRPL); + m_numRPL1 = numRPL; + + m_rpl1IdxPresentFlag = (m_numRPL0 != m_numRPL1) ? true : false; +} +#else void SPS::createRPSList( int numRPS ) { m_RPSList.destroy(); m_RPSList.create(numRPS); } - +#endif const int SPS::m_winUnitX[]={1,2,2,1}; @@ -2001,6 +2479,9 @@ PPS::PPS() #endif , m_numRefIdxL0DefaultActive (1) , m_numRefIdxL1DefaultActive (1) +#if JVET_M0128 +, m_rpl1IdxPresentFlag (false) +#endif , m_TransquantBypassEnabledFlag (false) , m_useTransformSkip (false) #if !JVET_N0857_TILES_BRICKS @@ -2058,6 +2539,8 @@ APS::APS() APS::~APS() { } + +#if !JVET_M0128 ReferencePictureSet::ReferencePictureSet() : m_numberOfPictures (0) , m_numberOfNegativePictures (0) @@ -2214,6 +2697,97 @@ RefPicListModification::RefPicListModification() RefPicListModification::~RefPicListModification() { } +#endif + +#if JVET_M0128 +ReferencePictureList::ReferencePictureList() + : m_numberOfShorttermPictures(0) + , m_numberOfLongtermPictures(0) + , m_numberOfActivePictures(MAX_INT) +{ + ::memset(m_isLongtermRefPic, 0, sizeof(m_isLongtermRefPic)); + ::memset(m_refPicIdentifier, 0, sizeof(m_refPicIdentifier)); + ::memset(m_POC, 0, sizeof(m_POC)); +} + +ReferencePictureList::~ReferencePictureList() +{ +} + +void ReferencePictureList::setRefPicIdentifier(int idx, int identifier, bool isLongterm) +{ + m_refPicIdentifier[idx] = identifier; + m_isLongtermRefPic[idx] = isLongterm; + + m_deltaPocMSBPresentFlag[idx] = false; + m_deltaPOCMSBCycleLT[idx] = 0; +} + +int ReferencePictureList::getRefPicIdentifier(int idx) const +{ + return m_refPicIdentifier[idx]; +} + + +bool ReferencePictureList::isRefPicLongterm(int idx) const +{ + return m_isLongtermRefPic[idx]; +} + +void ReferencePictureList::setNumberOfShorttermPictures(int numberOfStrp) +{ + m_numberOfShorttermPictures = numberOfStrp; +} + +int ReferencePictureList::getNumberOfShorttermPictures() const +{ + return m_numberOfShorttermPictures; +} + +void ReferencePictureList::setNumberOfLongtermPictures(int numberOfLtrp) +{ + m_numberOfLongtermPictures = numberOfLtrp; +} + +int ReferencePictureList::getNumberOfLongtermPictures() const +{ + return m_numberOfLongtermPictures; +} + +void ReferencePictureList::setPOC(int idx, int POC) +{ + m_POC[idx] = POC; +} + +int ReferencePictureList::getPOC(int idx) const +{ + return m_POC[idx]; +} + +void ReferencePictureList::setNumberOfActivePictures(int numberActive) +{ + m_numberOfActivePictures = numberActive; +} + +int ReferencePictureList::getNumberOfActivePictures() const +{ + return m_numberOfActivePictures; +} + +void ReferencePictureList::printRefPicInfo() const +{ + //DTRACE(g_trace_ctx, D_RPSINFO, "RefPics = { "); + printf("RefPics = { "); + int numRefPic = getNumberOfShorttermPictures() + getNumberOfLongtermPictures(); + for (int ii = 0; ii < numRefPic; ii++) + { + //DTRACE(g_trace_ctx, D_RPSINFO, "%d%s ", m_refPicIdentifier[ii], (m_isLongtermRefPic[ii] == 1) ? "[LT]" : "[ST]"); + printf("%d%s ", m_refPicIdentifier[ii], (m_isLongtermRefPic[ii] == 1) ? "[LT]" : "[ST]"); + } + //DTRACE(g_trace_ctx, D_RPSINFO, "}\n"); + printf("}\n"); +} +#endif #if HEVC_USE_SCALING_LISTS ScalingList::ScalingList() diff --git a/source/Lib/CommonLib/Slice.h b/source/Lib/CommonLib/Slice.h index ed592fefaef7aea1139f6100fef7c6f95f0e37c2..15db1dc20d7d2c337902cd8ea126b765aea9fc14 100644 --- a/source/Lib/CommonLib/Slice.h +++ b/source/Lib/CommonLib/Slice.h @@ -69,6 +69,7 @@ typedef std::list<Picture*> PicList; // Class definition // ==================================================================================================================== +#if !JVET_M0128 /// Reference Picture Set class class ReferencePictureSet { @@ -153,6 +154,69 @@ public: int getNumberOfReferencePictureSets() const { return int(m_referencePictureSets.size()); } }; +#endif + +#if JVET_M0128 +class ReferencePictureList +{ +private: + int m_numberOfShorttermPictures; + int m_numberOfLongtermPictures; + int m_isLongtermRefPic[MAX_NUM_REF_PICS]; + int m_refPicIdentifier[MAX_NUM_REF_PICS]; //This can be delta POC for STRP or POC LSB for LTRP + int m_POC[MAX_NUM_REF_PICS]; + int m_numberOfActivePictures; + bool m_deltaPocMSBPresentFlag[MAX_NUM_REF_PICS]; + int m_deltaPOCMSBCycleLT[MAX_NUM_REF_PICS]; + +public: + ReferencePictureList(); + virtual ~ReferencePictureList(); + + void setRefPicIdentifier(int idx, int identifier, bool isLongterm); + int getRefPicIdentifier(int idx) const; + bool isRefPicLongterm(int idx) const; + + void setNumberOfShorttermPictures(int numberOfStrp); + int getNumberOfShorttermPictures() const; + + void setNumberOfLongtermPictures(int numberOfLtrp); + int getNumberOfLongtermPictures() const; + + void setPOC(int idx, int POC); + int getPOC(int idx) const; + + void setNumberOfActivePictures(int numberOfLtrp); + int getNumberOfActivePictures() const; + + int getDeltaPocMSBCycleLT(int i) const { return m_deltaPOCMSBCycleLT[i]; } + void setDeltaPocMSBCycleLT(int i, int x) { m_deltaPOCMSBCycleLT[i] = x; } + bool getDeltaPocMSBPresentFlag(int i) const { return m_deltaPocMSBPresentFlag[i]; } + void setDeltaPocMSBPresentFlag(int i, bool x) { m_deltaPocMSBPresentFlag[i] = x; } + + void printRefPicInfo() const; +}; + +/// Reference Picture List set class +class RPLList +{ +private: + std::vector<ReferencePictureList> m_referencePictureLists; + +public: + RPLList() { } + virtual ~RPLList() { } + + void create(int numberOfEntries) { m_referencePictureLists.resize(numberOfEntries); } + void destroy() { } + + + ReferencePictureList* getReferencePictureList(int referencePictureListIdx) { return &m_referencePictureLists[referencePictureListIdx]; } + const ReferencePictureList* getReferencePictureList(int referencePictureListIdx) const { return &m_referencePictureLists[referencePictureListIdx]; } + + int getNumberOfReferencePictureLists() const { return int(m_referencePictureLists.size()); } +}; +#endif #if HEVC_USE_SCALING_LISTS /// SCALING_LIST class @@ -1146,7 +1210,17 @@ private: Window m_conformanceWindow; +#if JVET_M0128 + RPLList m_RPLList0; + RPLList m_RPLList1; + uint32_t m_numRPL0; + uint32_t m_numRPL1; + bool m_rpl1CopyFromRpl0Flag; + bool m_rpl1IdxPresentFlag; + bool m_allRplEntriesHasSameSignFlag; +#else RPSList m_RPSList; +#endif bool m_bLongTermRefsPresent; bool m_SPSTemporalMVPEnabledFlag; int m_numReorderPics[MAX_TLAYER]; @@ -1411,9 +1485,25 @@ public: uint32_t getBitsForPOC() const { return m_uiBitsForPOC; } void setNumReorderPics(int i, uint32_t tlayer) { m_numReorderPics[tlayer] = i; } int getNumReorderPics(uint32_t tlayer) const { return m_numReorderPics[tlayer]; } +#if JVET_M0128 + void createRPLList0(int numRPL); + void createRPLList1(int numRPL); + const RPLList* getRPLList0() const { return &m_RPLList0; } + RPLList* getRPLList0() { return &m_RPLList0; } + const RPLList* getRPLList1() const { return &m_RPLList1; } + RPLList* getRPLList1() { return &m_RPLList1; } + uint32_t getNumRPL0() const { return m_numRPL0; } + uint32_t getNumRPL1() const { return m_numRPL1; } + void setRPL1CopyFromRPL0Flag(bool isCopy) { m_rpl1CopyFromRpl0Flag = isCopy; } + bool getRPL1CopyFromRPL0Flag() const { return m_rpl1CopyFromRpl0Flag; } + bool getRPL1IdxPresentFlag() const { return m_rpl1IdxPresentFlag; } + void setAllActiveRplEntriesHasSameSignFlag(bool isAllSame) { m_allRplEntriesHasSameSignFlag = isAllSame; } + bool getAllActiveRplEntriesHasSameSignFlag() const { return m_allRplEntriesHasSameSignFlag; } +#else void createRPSList( int numRPS ); const RPSList* getRPSList() const { return &m_RPSList; } RPSList* getRPSList() { return &m_RPSList; } +#endif bool getLongTermRefsPresent() const { return m_bLongTermRefsPresent; } void setLongTermRefsPresent(bool b) { m_bLongTermRefsPresent=b; } bool getSPSTemporalMVPEnabledFlag() const { return m_SPSTemporalMVPEnabledFlag; } @@ -1573,7 +1663,7 @@ public: /// Reference Picture Lists class - +#if !JVET_M0128 class RefPicListModification { private: @@ -1595,7 +1685,7 @@ public: uint32_t getRefPicSetIdxL1(uint32_t idx) const { CHECK(idx>=REF_PIC_LIST_NUM_IDX, "Invalid ref-pic-list index"); return m_RefPicSetIdxL1[idx]; } void setRefPicSetIdxL1(uint32_t idx, uint32_t refPicSetIdx) { CHECK(idx>=REF_PIC_LIST_NUM_IDX, "Invalid ref-pic-list index"); m_RefPicSetIdxL1[idx] = refPicSetIdx; } }; - +#endif /// PPS RExt class @@ -1682,6 +1772,10 @@ private: uint32_t m_numRefIdxL0DefaultActive; uint32_t m_numRefIdxL1DefaultActive; +#if JVET_M0128 + bool m_rpl1IdxPresentFlag; +#endif + bool m_bUseWeightPred; //!< Use of Weighting Prediction (P_SLICE) bool m_useWeightedBiPred; //!< Use of Weighting Bi-Prediction (B_SLICE) bool m_OutputFlagPresentFlag; //!< Indicates the presence of output_flag in slice header @@ -1813,6 +1907,11 @@ public: void setNumRefIdxL1DefaultActive(uint32_t ui) { m_numRefIdxL1DefaultActive=ui; } uint32_t getNumRefIdxL1DefaultActive() const { return m_numRefIdxL1DefaultActive; } +#if JVET_M0128 + void setRpl1IdxPresentFlag(bool isPresent) { m_rpl1IdxPresentFlag = isPresent; } + uint32_t getRpl1IdxPresentFlag() const { return m_rpl1IdxPresentFlag; } +#endif + bool getUseWP() const { return m_bUseWeightPred; } bool getWPBiPred() const { return m_useWeightedBiPred; } void setUseWP( bool b ) { m_bUseWeightPred = b; } @@ -2014,10 +2113,19 @@ private: int m_iLastIDR; int m_iAssociatedIRAP; NalUnitType m_iAssociatedIRAPType; +#if JVET_M0128 + const ReferencePictureList* m_pRPL0; //< pointer to RPL for L0, either in the SPS or the local RPS in the same slice header + const ReferencePictureList* m_pRPL1; //< pointer to RPL for L1, either in the SPS or the local RPS in the same slice header + ReferencePictureList m_localRPL0; //< RPL for L0 when present in slice header + ReferencePictureList m_localRPL1; //< RPL for L1 when present in slice header + int m_rpl0Idx; //< index of used RPL in the SPS or -1 for local RPL in the slice header + int m_rpl1Idx; //< index of used RPL in the SPS or -1 for local RPL in the slice header +#else const ReferencePictureSet* m_pRPS; //< pointer to RPS, either in the SPS or the local RPS in the same slice header ReferencePictureSet m_localRPS; //< RPS when present in slice header int m_rpsIdx; //< index of used RPS in the SPS or -1 for local RPS in the slice header RefPicListModification m_RefPicListModification; +#endif NalUnitType m_eNalUnitType; ///< Nal unit type for the slice SliceType m_eSliceType; int m_iSliceQp; @@ -2209,6 +2317,18 @@ public: bool getPicOutputFlag() const { return m_PicOutputFlag; } void setSaoEnabledFlag(ChannelType chType, bool s) {m_saoEnabledFlag[chType] =s; } bool getSaoEnabledFlag(ChannelType chType) const { return m_saoEnabledFlag[chType]; } +#if JVET_M0128 + void setRPL0(const ReferencePictureList *pcRPL) { m_pRPL0 = pcRPL; } + void setRPL1(const ReferencePictureList *pcRPL) { m_pRPL1 = pcRPL; } + const ReferencePictureList* getRPL0() { return m_pRPL0; } + const ReferencePictureList* getRPL1() { return m_pRPL1; } + ReferencePictureList* getLocalRPL0() { return &m_localRPL0; } + ReferencePictureList* getLocalRPL1() { return &m_localRPL1; } + void setRPL0idx(int rplIdx) { m_rpl0Idx = rplIdx; } + void setRPL1idx(int rplIdx) { m_rpl1Idx = rplIdx; } + int getRPL0idx() const { return m_rpl0Idx; } + int getRPL1idx() const { return m_rpl1Idx; } +#else void setRPS( const ReferencePictureSet *pcRPS ) { m_pRPS = pcRPS; } const ReferencePictureSet* getRPS() { return m_pRPS; } ReferencePictureSet* getLocalRPS() { return &m_localRPS; } @@ -2216,6 +2336,7 @@ public: void setRPSidx( int rpsIdx ) { m_rpsIdx = rpsIdx; } int getRPSidx() const { return m_rpsIdx; } RefPicListModification* getRefPicListModification() { return &m_RefPicListModification; } +#endif void setLastIDR(int iIDRPOC) { m_iLastIDR = iIDRPOC; } int getLastIDR() const { return m_iLastIDR; } void setAssociatedIRAPPOC(int iAssociatedIRAPPOC) { m_iAssociatedIRAP = iAssociatedIRAPPOC; } @@ -2249,7 +2370,9 @@ public: void setIsUsedAsLongTerm(int i, int j, bool value) { m_bIsUsedAsLongTerm[i][j] = value; } bool getCheckLDC() const { return m_bCheckLDC; } bool getMvdL1ZeroFlag() const { return m_bLMvdL1Zero; } +#if !JVET_M0128 int getNumRpsCurrTempList() const; +#endif int getList1IdxToList0Idx( int list1Idx ) const { return m_list1IdxToList0Idx[list1Idx]; } #if !JVET_M0101_HLS bool isReferenceNalu() const { return ((getNalUnitType() <= NAL_UNIT_RESERVED_VCL_R15) && (getNalUnitType()%2 != 0)) || ((getNalUnitType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP) && (getNalUnitType() <= NAL_UNIT_RESERVED_IRAP_VCL23) ); } @@ -2271,7 +2394,11 @@ public: bool isIDRorBLA() const { return (getNalUnitType() >= NAL_UNIT_CODED_SLICE_IDR_W_RADL) && (getNalUnitType() <= NAL_UNIT_CODED_SLICE_IDR_N_LP); } #endif #endif +#if !JVET_M0128 void checkCRA(const ReferencePictureSet *pReferencePictureSet, int& pocCRA, NalUnitType& associatedIRAPType, PicList& rcListPic); +#else + void checkCRA(const ReferencePictureList *pRPL0, const ReferencePictureList *pRPL1, int& pocCRA, NalUnitType& associatedIRAPType, PicList& rcListPic); +#endif void decodingRefreshMarking(int& pocCRA, bool& bRefreshPending, PicList& rcListPic, const bool bEfficientFieldIRAPEnabled); void setSliceType( SliceType e ) { m_eSliceType = e; } void setSliceQp( int i ) { m_iSliceQp = i; } @@ -2287,7 +2414,11 @@ public: void setPic( Picture* p ) { m_pcPic = p; } void setDepth( int iDepth ) { m_iDepth = iDepth; } +#if JVET_M0128 + void constructRefPicList(PicList& rcListPic); +#else void setRefPicList( PicList& rcListPic, bool checkNumPocTotalCurr = false, bool bCopyL0toL1ErrorCase = false ); +#endif void setRefPOCList(); void setColFromL0Flag( bool colFromL0 ) { m_colFromL0Flag = colFromL0; } @@ -2360,13 +2491,22 @@ public: void setTLayer( uint32_t uiTLayer ) { m_uiTLayer = uiTLayer; } void checkLeadingPictureRestrictions( PicList& rcListPic ) const; +#if JVET_M0128 + void applyReferencePictureListBasedMarking( PicList& rcListPic, const ReferencePictureList *pRPL0, const ReferencePictureList *pRPL1 ) const; +#else void applyReferencePictureSet( PicList& rcListPic, const ReferencePictureSet *RPSList) const; +#endif bool isTemporalLayerSwitchingPoint( PicList& rcListPic ) const; bool isStepwiseTemporalLayerSwitchingPointCandidate( PicList& rcListPic ) const; +#if JVET_M0128 + int checkThatAllRefPicsAreAvailable(PicList& rcListPic, const ReferencePictureList *pRPL, int rplIdx, bool printErrors) const; + void createExplicitReferencePictureSetFromReference(PicList& rcListPic, const ReferencePictureList *pRPL0, const ReferencePictureList *pRPL1); +#else int checkThatAllRefPicsAreAvailable( PicList& rcListPic, const ReferencePictureSet *pReferencePictureSet, bool printErrors, int pocRandomAccess = 0, bool bUseRecoveryPoint = false) const; void createExplicitReferencePictureSetFromReference(PicList& rcListPic, const ReferencePictureSet *pReferencePictureSet, bool isRAP, int pocRandomAccess, bool bUseRecoveryPoint, const bool bEfficientFieldIRAPEnabled , bool isEncodeLtRef, bool isCompositeRefEnable ); +#endif void setMaxNumMergeCand(uint32_t val ) { m_maxNumMergeCand = val; } uint32_t getMaxNumMergeCand() const { return m_maxNumMergeCand; } void setMaxNumAffineMergeCand( uint32_t val ) { m_maxNumAffineMergeCand = val; } diff --git a/source/Lib/CommonLib/TypeDef.h b/source/Lib/CommonLib/TypeDef.h index c19af4551d8bead6f5cee3d317d801327971bc88..ccba812dcf6e1c8f4b86b22225ac598c7abe665e 100644 --- a/source/Lib/CommonLib/TypeDef.h +++ b/source/Lib/CommonLib/TypeDef.h @@ -218,6 +218,8 @@ #define JVET_M0497_MATRIX_MULT 0 // 0: Fast method; 1: Matrix multiplication +#define JVET_M0128 1 // Implementation of RPL as in JVET-M0128 + #define APPLY_SBT_SL_ON_MTS 1 // apply save & load fast algorithm on inter MTS when SBT is on #define FIX_PCM 1 // Fix PCM bugs in VTM3 diff --git a/source/Lib/DecoderLib/DecLib.cpp b/source/Lib/DecoderLib/DecLib.cpp index af7bb897a30ee255b3258f1533644f183e19533b..2c56028fe8ce21ce7a08c3b4bef1787f4164cc0d 100644 --- a/source/Lib/DecoderLib/DecLib.cpp +++ b/source/Lib/DecoderLib/DecLib.cpp @@ -877,7 +877,11 @@ void DecLib::xActivateParameterSets() // Get a new picture buffer. This will also set up m_pcPic, and therefore give us a SPS and PPS pointer that we can use. m_pcPic = xGetNewPicBuffer (*sps, *pps, m_apcSlicePilot->getTLayer()); +#if JVET_M0128 + m_apcSlicePilot->applyReferencePictureListBasedMarking(m_cListPic, m_apcSlicePilot->getRPL0(), m_apcSlicePilot->getRPL1()); +#else m_apcSlicePilot->applyReferencePictureSet(m_cListPic, m_apcSlicePilot->getRPS()); +#endif #if JVET_N0415_CTB_ALF #if JVET_N0805_APS_LMCS m_pcPic->finalInit(*sps, *pps, apss, *lmcsAPS); @@ -1280,10 +1284,17 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl //detect lost reference picture and insert copy of earlier frame. { int lostPoc; +#if JVET_M0128 + while ((lostPoc = m_apcSlicePilot->checkThatAllRefPicsAreAvailable(m_cListPic, m_apcSlicePilot->getRPL0(), 0, true)) > 0) + xCreateLostPicture(lostPoc - 1); + while ((lostPoc = m_apcSlicePilot->checkThatAllRefPicsAreAvailable(m_cListPic, m_apcSlicePilot->getRPL1(), 1, true)) > 0) + xCreateLostPicture(lostPoc - 1); +#else while((lostPoc=m_apcSlicePilot->checkThatAllRefPicsAreAvailable(m_cListPic, m_apcSlicePilot->getRPS(), true, m_pocRandomAccess)) > 0) { xCreateLostPicture(lostPoc-1); } +#endif } m_prevPOC = m_apcSlicePilot->getPOC(); @@ -1349,9 +1360,14 @@ bool DecLib::xDecodeSlice(InputNALUnit &nalu, int &iSkipFrame, int iPOCLastDispl pcSlice->setSliceCurEndCtuTsAddr(endCtuIdx); #endif +#if JVET_M0128 + pcSlice->checkCRA(pcSlice->getRPL0(), pcSlice->getRPL1(), m_pocCRA, m_associatedIRAPType, m_cListPic); + pcSlice->constructRefPicList(m_cListPic); +#else pcSlice->checkCRA(pcSlice->getRPS(), m_pocCRA, m_associatedIRAPType, m_cListPic ); // Set reference list pcSlice->setRefPicList( m_cListPic, true, true ); +#endif if (!pcSlice->isIntra()) { diff --git a/source/Lib/DecoderLib/VLCReader.cpp b/source/Lib/DecoderLib/VLCReader.cpp index 47dc85d2099ac4fd499f229dd0ab9f56fda9f572..e9ead8c277e73634d4c68a774f56d01d14b0de66 100644 --- a/source/Lib/DecoderLib/VLCReader.cpp +++ b/source/Lib/DecoderLib/VLCReader.cpp @@ -269,6 +269,77 @@ HLSyntaxReader::~HLSyntaxReader() // Public member functions // ==================================================================================================================== +#if JVET_M0128 +void HLSyntaxReader::copyRefPicList(SPS* sps, ReferencePictureList* source_rpl, ReferencePictureList* dest_rp) +{ + dest_rp->setNumberOfShorttermPictures(source_rpl->getNumberOfShorttermPictures()); + + if (sps->getLongTermRefsPresent()) + dest_rp->setNumberOfLongtermPictures(dest_rp->getNumberOfLongtermPictures()); + else + dest_rp->setNumberOfLongtermPictures(0); + + uint32_t numRefPic = dest_rp->getNumberOfShorttermPictures() + dest_rp->getNumberOfLongtermPictures(); + for (int ii = 0; ii < numRefPic; ii++) + dest_rp->setRefPicIdentifier(ii, source_rpl->getRefPicIdentifier(ii), source_rpl->isRefPicLongterm(ii)); +} + +void HLSyntaxReader::parseRefPicList(SPS* sps, ReferencePictureList* rpl) +{ + uint32_t code; + READ_UVLC(code, "num_ref_entries[ listIdx ][ rplsIdx ]"); + uint32_t numRefPic = code; + uint32_t numStrp = 0; + uint32_t numLtrp = 0; + + bool isLongTerm; + int prevDelta = MAX_INT; + int deltaValue = 0; + bool firstSTRP = true; + for (int ii = 0; ii < numRefPic; ii++) + { + isLongTerm = false; + if (sps->getLongTermRefsPresent()) + { + READ_FLAG(code, "st_ref_pic_flag[ listIdx ][ rplsIdx ][ i ]"); + isLongTerm = (code == 1) ? false : true; + } + else + isLongTerm = false; + + if (!isLongTerm) + { + READ_UVLC(code, "abs_delta_poc_st[ listIdx ][ rplsIdx ][ i ]"); + int readValue = code; + if (readValue > 0) + READ_FLAG(code, "strp_entry_sign_flag[ listIdx ][ rplsIdx ][ i ]"); + else + code = 1; + readValue = (code) ? readValue : 0 - readValue; //true means positive delta POC -- false otherwise + if (firstSTRP) + { + firstSTRP = false; + prevDelta = deltaValue = readValue; + } + else + { + deltaValue = prevDelta + readValue; + prevDelta = deltaValue; + } + rpl->setRefPicIdentifier(ii, deltaValue, isLongTerm); + numStrp++; + } + else + { + READ_CODE(sps->getBitsForPOC(), code, "poc_lsb_lt[listIdx][rplsIdx][i]"); + rpl->setRefPicIdentifier(ii, code, isLongTerm); + numLtrp++; + } + } + rpl->setNumberOfShorttermPictures(numStrp); + rpl->setNumberOfLongtermPictures(numLtrp); +} +#else void HLSyntaxReader::parseShortTermRefPicSet( SPS* sps, ReferencePictureSet* rps, int idx ) { uint32_t code; @@ -367,6 +438,7 @@ void HLSyntaxReader::parseShortTermRefPicSet( SPS* sps, ReferencePictureSet* rps rps->printDeltaPOC(); } +#endif #if JVET_N0438_LOOP_FILTER_DISABLED_ACROSS_VIR_BOUND void HLSyntaxReader::parsePPS( PPS* pcPPS, ParameterSetManager *parameterSetManager ) @@ -405,6 +477,11 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS ) CHECK(uiCode > 14, "Invalid code read"); pcPPS->setNumRefIdxL1DefaultActive(uiCode+1); +#if JVET_M0128 + READ_FLAG(uiCode, "rpl1_idx_present_flag"); + pcPPS->setRpl1IdxPresentFlag(uiCode); +#endif + READ_SVLC(iCode, "init_qp_minus26" ); pcPPS->setPicInitQPMinus26(iCode); READ_FLAG( uiCode, "constrained_intra_pred_flag" ); pcPPS->setConstrainedIntraPred( uiCode ? true : false ); READ_FLAG( uiCode, "transform_skip_enabled_flag" ); @@ -767,8 +844,10 @@ void HLSyntaxReader::parsePPS( PPS* pcPPS ) } #endif +#if !JVET_M0128 READ_FLAG( uiCode, "lists_modification_present_flag"); pcPPS->setListsModificationPresentFlag(uiCode); +#endif READ_UVLC( uiCode, "log2_parallel_merge_level_minus2"); pcPPS->setLog2ParallelMergeLevelMinus2 (uiCode); @@ -1510,6 +1589,47 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) } } +#if JVET_M0128 + READ_FLAG(uiCode, "long_term_ref_pics_flag"); pcSPS->setLongTermRefsPresent(uiCode); + READ_FLAG(uiCode, "rpl1_copy_from_rpl0_flag"); + pcSPS->setRPL1CopyFromRPL0Flag(uiCode); + + //Read candidate for List0 + READ_UVLC(uiCode, "num_ref_pic_lists_in_sps[0]"); + uint32_t numberOfRPL = uiCode; + pcSPS->createRPLList0(numberOfRPL + 1); + RPLList* rplList = pcSPS->getRPLList0(); + ReferencePictureList* rpl; + for (uint32_t ii = 0; ii < numberOfRPL; ii++) + { + rpl = rplList->getReferencePictureList(ii); + parseRefPicList(pcSPS, rpl); + } + + //Read candidate for List1 + if (!pcSPS->getRPL1CopyFromRPL0Flag()) + { + READ_UVLC(uiCode, "num_ref_pic_lists_in_sps[1]"); + numberOfRPL = uiCode; + pcSPS->createRPLList1(numberOfRPL + 1); + rplList = pcSPS->getRPLList1(); + for (uint32_t ii = 0; ii < numberOfRPL; ii++) + { + rpl = rplList->getReferencePictureList(ii); + parseRefPicList(pcSPS, rpl); + } + } + else + { + numberOfRPL = pcSPS->getNumRPL0(); + pcSPS->createRPLList1(numberOfRPL); + RPLList* rplListSource = pcSPS->getRPLList0(); + RPLList* rplListDest = pcSPS->getRPLList1(); + for (uint32_t ii = 0; ii < numberOfRPL; ii++) + copyRefPicList(pcSPS, rplListSource->getReferencePictureList(ii), rplListDest->getReferencePictureList(ii)); + } +#endif + unsigned minQT[3] = { 0, 0, 0 }; unsigned maxBTD[3] = { 0, 0, 0 }; @@ -1697,6 +1817,7 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) #endif // KJS: reference picture sets to be replaced +#if !JVET_M0128 READ_UVLC( uiCode, "num_short_term_ref_pic_sets" ); CHECK(uiCode > 64, "Invalid code"); pcSPS->createRPSList(uiCode); @@ -1722,6 +1843,7 @@ void HLSyntaxReader::parseSPS(SPS* pcSPS) pcSPS->setUsedByCurrPicLtSPSFlag(k, uiCode?1:0); } } +#endif // KJS: not found in draft -> does not exist #if HEVC_USE_INTRA_SMOOTHING_T32 || HEVC_USE_INTRA_SMOOTHING_T64 @@ -2104,9 +2226,11 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para { READ_CODE(sps->getBitsForPOC(), uiCode, "slice_pic_order_cnt_lsb"); pcSlice->setPOC(uiCode); +#if !JVET_M0128 ReferencePictureSet* rps = pcSlice->getLocalRPS(); (*rps)=ReferencePictureSet(); pcSlice->setRPS(rps); +#endif } else { @@ -2140,6 +2264,127 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para #endif pcSlice->setPOC (iPOCmsb+iPOClsb); +#if JVET_M0128 + //Read L0 related syntax elements + if (sps->getNumRPL0() > 0) + { + READ_FLAG(uiCode, "ref_pic_list_sps_flag[0]"); + } + else + { + uiCode = 0; + } + + if (!uiCode) //explicitly carried in this SH + { + ReferencePictureList* rpl0 = pcSlice->getLocalRPL0(); + (*rpl0) = ReferencePictureList(); + parseRefPicList(sps, rpl0); + pcSlice->setRPL0idx(-1); + pcSlice->setRPL0(rpl0); + } + else //Refer to list in SPS + { + if (sps->getNumRPL0() > 1) + { + int numBits = (int)ceil(log2(sps->getNumRPL0())); + READ_CODE(numBits, uiCode, "ref_pic_list_idx[0]"); + pcSlice->setRPL0idx(uiCode); + pcSlice->setRPL0(sps->getRPLList0()->getReferencePictureList(uiCode)); + } + } + //Deal POC Msb cycle signalling for LTRP + for (int i = 0; i < pcSlice->getRPL0()->getNumberOfLongtermPictures() + pcSlice->getRPL0()->getNumberOfShorttermPictures(); i++) + { + pcSlice->getLocalRPL0()->setDeltaPocMSBPresentFlag(i, false); + pcSlice->getLocalRPL0()->setDeltaPocMSBCycleLT(i, 0); + } + if (pcSlice->getRPL0()->getNumberOfLongtermPictures()) + { + for (int i = 0; i < pcSlice->getRPL0()->getNumberOfLongtermPictures() + pcSlice->getRPL0()->getNumberOfShorttermPictures(); i++) + { + if (pcSlice->getRPL0()->isRefPicLongterm(i)) + { + READ_FLAG(uiCode, "delta_poc_msb_present_flag[i][j]"); + pcSlice->getLocalRPL0()->setDeltaPocMSBPresentFlag(i, uiCode ? true : false); + if (uiCode) + { + READ_FLAG(uiCode, "delta_poc_msb_cycle_lt[i][j]"); + pcSlice->getLocalRPL0()->setDeltaPocMSBCycleLT(i, uiCode); + } + } + } + } + + //Read L1 related syntax elements + if (!pps->getRpl1IdxPresentFlag()) + { + pcSlice->setRPL1idx(pcSlice->getRPL0idx()); + if (pcSlice->getRPL1idx() != -1) + pcSlice->setRPL1(sps->getRPLList1()->getReferencePictureList(pcSlice->getRPL0idx())); + } + else + { + if (sps->getNumRPL0() > 0) + { + READ_FLAG(uiCode, "ref_pic_list_sps_flag[1]"); + } + else + { + uiCode = 0; + } + if (uiCode == 1) + { + if (sps->getNumRPL1() > 1) + { + int numBits = (int)ceil(log2(sps->getNumRPL1())); + READ_CODE(numBits, uiCode, "ref_pic_list_idx[1]"); + pcSlice->setRPL1idx(uiCode); + pcSlice->setRPL1(sps->getRPLList1()->getReferencePictureList(uiCode)); + } + else + { + pcSlice->setRPL1idx(0); + pcSlice->setRPL1(sps->getRPLList1()->getReferencePictureList(0)); + } + } + else + { + pcSlice->setRPL1idx(-1); + } + } + if (pcSlice->getRPL1idx() == -1) //explicitly carried in this SH + { + ReferencePictureList* rpl1 = pcSlice->getLocalRPL1(); + (*rpl1) = ReferencePictureList(); + parseRefPicList(sps, rpl1); + pcSlice->setRPL1idx(-1); + pcSlice->setRPL1(rpl1); + } + + //Deal POC Msb cycle signalling for LTRP + for (int i = 0; i < pcSlice->getRPL1()->getNumberOfLongtermPictures() + pcSlice->getRPL1()->getNumberOfShorttermPictures(); i++) + { + pcSlice->getLocalRPL1()->setDeltaPocMSBPresentFlag(i, false); + pcSlice->getLocalRPL1()->setDeltaPocMSBCycleLT(i, 0); + } + if (pcSlice->getRPL1()->getNumberOfLongtermPictures()) + { + for (int i = 0; i < pcSlice->getRPL1()->getNumberOfLongtermPictures() + pcSlice->getRPL1()->getNumberOfShorttermPictures(); i++) + { + if (pcSlice->getRPL1()->isRefPicLongterm(i)) + { + READ_FLAG(uiCode, "delta_poc_msb_present_flag[i][j]"); + pcSlice->getLocalRPL1()->setDeltaPocMSBPresentFlag(i, uiCode ? true : false); + if (uiCode) + { + READ_FLAG(uiCode, "delta_poc_msb_cycle_lt[i][j]"); + pcSlice->getLocalRPL1()->setDeltaPocMSBCycleLT(i, uiCode); + } + } + } + } +#else ReferencePictureSet* rps; rps = pcSlice->getLocalRPS(); (*rps)=ReferencePictureSet(); @@ -2264,6 +2509,8 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para pcSlice->setRPS(rps); } #endif +#endif + if (sps->getSPSTemporalMVPEnabledFlag()) { READ_FLAG( uiCode, "slice_temporal_mvp_enabled_flag" ); @@ -2386,6 +2633,7 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para } } // } +#if !JVET_M0128 RefPicListModification* refPicListModification = pcSlice->getRefPicListModification(); if(!pcSlice->isIntra()) { @@ -2472,6 +2720,8 @@ void HLSyntaxReader::parseSliceHeader (Slice* pcSlice, ParameterSetManager *para { refPicListModification->setRefPicListModificationFlagL1(0); } +#endif + if (pcSlice->isInterB()) { READ_FLAG( uiCode, "mvd_l1_zero_flag" ); pcSlice->setMvdL1ZeroFlag( (uiCode ? true : false) ); diff --git a/source/Lib/DecoderLib/VLCReader.h b/source/Lib/DecoderLib/VLCReader.h index 786d17e88e20f676959ae3c2762ab6998744eb33..9c70f565b00cc746bf16b584a1c1b1a3a30c4346 100644 --- a/source/Lib/DecoderLib/VLCReader.h +++ b/source/Lib/DecoderLib/VLCReader.h @@ -143,7 +143,12 @@ public: virtual ~HLSyntaxReader(); protected: +#if JVET_M0128 + void copyRefPicList(SPS* pcSPS, ReferencePictureList* source_rpl, ReferencePictureList* dest_rpl); + void parseRefPicList(SPS* pcSPS, ReferencePictureList* rpl); +#else void parseShortTermRefPicSet (SPS* pcSPS, ReferencePictureSet* pcRPS, int idx); +#endif public: void setBitstream ( InputBitstream* p ) { m_pcBitstream = p; } diff --git a/source/Lib/EncoderLib/EncCfg.h b/source/Lib/EncoderLib/EncCfg.h index c024b9d3b39761d8b66231dca87bbc41ed174e6a..c296937385c1809eabfa65d24f1e4cacbc019503 100644 --- a/source/Lib/EncoderLib/EncCfg.h +++ b/source/Lib/EncoderLib/EncCfg.h @@ -64,8 +64,18 @@ struct GOPEntry int m_betaOffsetDiv2; int m_temporalId; bool m_refPic; +#if !JVET_M0128 int m_numRefPicsActive; +#endif int8_t m_sliceType; +#if JVET_M0128 + int m_numRefPicsActive0; + int m_numRefPics0; + int m_deltaRefPics0[MAX_NUM_REF_PICS]; + int m_numRefPicsActive1; + int m_numRefPics1; + int m_deltaRefPics1[MAX_NUM_REF_PICS]; +#else int m_numRefPics; int m_referencePics[MAX_NUM_REF_PICS]; int m_usedByCurrPic[MAX_NUM_REF_PICS]; @@ -73,6 +83,7 @@ struct GOPEntry int m_deltaRPS; int m_numRefIdc; int m_refIdc[MAX_NUM_REF_PICS+1]; +#endif bool m_isEncoded; GOPEntry() : m_POC(-1) @@ -90,19 +101,58 @@ struct GOPEntry , m_betaOffsetDiv2(0) , m_temporalId(0) , m_refPic(false) +#if !JVET_M0128 , m_numRefPicsActive(0) +#endif , m_sliceType('P') +#if JVET_M0128 + , m_numRefPicsActive0(0) + , m_numRefPics0(0) + , m_numRefPicsActive1(0) + , m_numRefPics1(0) +#else , m_numRefPics(0) , m_interRPSPrediction(false) , m_deltaRPS(0) , m_numRefIdc(0) +#endif , m_isEncoded(false) { +#if JVET_M0128 + ::memset(m_deltaRefPics0, 0, sizeof(m_deltaRefPics0)); + ::memset(m_deltaRefPics1, 0, sizeof(m_deltaRefPics1)); +#else ::memset( m_referencePics, 0, sizeof(m_referencePics) ); ::memset( m_usedByCurrPic, 0, sizeof(m_usedByCurrPic) ); ::memset( m_refIdc, 0, sizeof(m_refIdc) ); +#endif + } +}; + +#if JVET_M0128 +struct RPLEntry +{ + int m_POC; + int m_temporalId; + bool m_refPic; + int m_numRefPicsActive; + int8_t m_sliceType; + int m_numRefPics; + int m_deltaRefPics[MAX_NUM_REF_PICS]; + bool m_isEncoded; + RPLEntry() + : m_POC(-1) + , m_temporalId(0) + , m_refPic(false) + , m_numRefPicsActive(0) + , m_sliceType('P') + , m_numRefPics(0) + , m_isEncoded(false) + { + ::memset(m_deltaRefPics, 0, sizeof(m_deltaRefPics)); } }; +#endif std::istringstream &operator>>(std::istringstream &in, GOPEntry &entry); //input @@ -222,14 +272,26 @@ protected: bool m_lowerBitRateConstraintFlag; //====== Coding Structure ======== +#if JVET_M0128 + int m_uiIntraPeriod; // needs to be signed to allow '-1' for no intra period +#else uint32_t m_uiIntraPeriod; // TODO: make this an int - it can be -1! +#endif uint32_t m_uiDecodingRefreshType; ///< the type of decoding refresh employed for the random access. #if JCTVC_Y0038_PARAMS bool m_rewriteParamSets; #endif int m_iGOPSize; +#if JVET_M0128 + RPLEntry m_RPLList0[MAX_GOP]; + RPLEntry m_RPLList1[MAX_GOP]; + int m_numRPLList0; + int m_numRPLList1; +#endif GOPEntry m_GOPList[MAX_GOP]; +#if !JVET_M0128 int m_extraRPSs; +#endif int m_maxDecPicBuffering[MAX_TLAYER]; int m_numReorderPics[MAX_TLAYER]; @@ -818,16 +880,47 @@ public: void setCabacZeroWordPaddingEnabled(bool value) { m_cabacZeroWordPaddingEnabled = value; } //====== Coding Structure ======== +#if JVET_M0128 + void setIntraPeriod (int i) { m_uiIntraPeriod = i; } +#else void setIntraPeriod ( int i ) { m_uiIntraPeriod = (uint32_t)i; } +#endif void setDecodingRefreshType ( int i ) { m_uiDecodingRefreshType = (uint32_t)i; } #if JCTVC_Y0038_PARAMS void setReWriteParamSets ( bool b ) { m_rewriteParamSets = b; } #endif void setGOPSize ( int i ) { m_iGOPSize = i; } - void setGopList ( const GOPEntry GOPList[MAX_GOP] ) { for ( int i = 0; i < MAX_GOP; i++ ) m_GOPList[i] = GOPList[i]; } + void setGopList(const GOPEntry GOPList[MAX_GOP]) { for (int i = 0; i < MAX_GOP; i++) m_GOPList[i] = GOPList[i]; } +#if !JVET_M0128 void setExtraRPSs ( int i ) { m_extraRPSs = i; } +#endif const GOPEntry &getGOPEntry ( int i ) const { return m_GOPList[i]; } +#if !JVET_M0128 void setEncodedFlag ( int i, bool value ) { m_GOPList[i].m_isEncoded = value; } +#endif +#if JVET_M0128 + void setRPLList0(const RPLEntry RPLList[MAX_GOP]) + { + m_numRPLList0 = 0; + for (int i = 0; i < MAX_GOP; i++) + { + m_RPLList0[i] = RPLList[i]; + if (m_RPLList0[i].m_POC != -1) m_numRPLList0++; + } + } + void setRPLList1(const RPLEntry RPLList[MAX_GOP]) + { + m_numRPLList1 = 0; + for (int i = 0; i < MAX_GOP; i++) + { + m_RPLList1[i] = RPLList[i]; + if (m_RPLList1[i].m_POC != -1) m_numRPLList1++; + } + } + const RPLEntry &getRPLEntry(int L01, int idx) const { return (L01 == 0) ? m_RPLList0[idx] : m_RPLList1[idx]; } + int getRPLCandidateSize(int L01) const { return (L01 == 0) ? m_numRPLList0 : m_numRPLList1; } + void setEncodedFlag(uint32_t i, bool value) { m_RPLList0[i].m_isEncoded = value; m_RPLList1[i].m_isEncoded = value; } +#endif void setMaxDecPicBuffering ( uint32_t u, uint32_t tlayer ) { m_maxDecPicBuffering[tlayer] = u; } void setNumReorderPics ( int i, uint32_t tlayer ) { m_numReorderPics[tlayer] = i; } diff --git a/source/Lib/EncoderLib/EncGOP.cpp b/source/Lib/EncoderLib/EncGOP.cpp index f7fce5ab6bd409389e500d25bb40f75e9871c976..1c86cbe07c2e9a1c38890f302c7008a4256723f9 100644 --- a/source/Lib/EncoderLib/EncGOP.cpp +++ b/source/Lib/EncoderLib/EncGOP.cpp @@ -1606,6 +1606,16 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, setLastLTRefPoc(-1); } +#if JVET_M0128 + if (m_pcCfg->getUseCompositeRef() && m_picBg->getSpliceFull() && getUseLTRef()) + { + m_pcEncLib->selectReferencePictureList(pcSlice, pocCurr, iGOPid, m_bgPOC); + } + else + { + m_pcEncLib->selectReferencePictureList(pcSlice, pocCurr, iGOPid, -1); + } +#else if (m_pcCfg->getUseCompositeRef() && m_picBg->getSpliceFull() && getUseLTRef()) { m_pcEncLib->selectReferencePictureSet(pcSlice, pocCurr, iGOPid, m_bgPOC); @@ -1614,6 +1624,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, { m_pcEncLib->selectReferencePictureSet(pcSlice, pocCurr, iGOPid, -1); } +#endif if (!m_pcCfg->getEfficientFieldIRAPEnabled()) { #if !JVET_M0101_HLS @@ -1636,6 +1647,14 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, pcSlice->setAssociatedIRAPPOC(m_associatedIRAPPOC); } +#if JVET_M0128 + if (pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPL0(), 0, false) != 0 || pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPL1(), 1, false) != 0) + { + pcSlice->createExplicitReferencePictureSetFromReference(rcListPic, pcSlice->getRPL0(), pcSlice->getRPL1()); + } + + pcSlice->applyReferencePictureListBasedMarking(rcListPic, pcSlice->getRPL0(), pcSlice->getRPL1()); +#else if ((pcSlice->checkThatAllRefPicsAreAvailable(rcListPic, pcSlice->getRPS(), false, m_iLastRecoveryPicPOC, m_pcCfg->getDecodingRefreshType() == 3) != 0) || (pcSlice->isIRAP()) #if !JVET_M0101_HLS || (m_pcCfg->getEfficientFieldIRAPEnabled() && isField && pcSlice->getAssociatedIRAPType() >= NAL_UNIT_CODED_SLICE_BLA_W_LP && pcSlice->getAssociatedIRAPType() <= NAL_UNIT_CODED_SLICE_CRA && pcSlice->getAssociatedIRAPPOC() == pcSlice->getPOC()+1) @@ -1650,6 +1669,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, } pcSlice->applyReferencePictureSet(rcListPic, pcSlice->getRPS()); +#endif if(pcSlice->getTLayer() > 0 #if !JVET_M0101_HLS @@ -1683,6 +1703,51 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, bool isSTSA=true; for(int ii=iGOPid+1;(ii<m_pcCfg->getGOPSize() && isSTSA==true);ii++) { +#if JVET_M0128 + int lTid = m_pcCfg->getRPLEntry(0, ii).m_temporalId; + + if (lTid == pcSlice->getTLayer()) + { + const ReferencePictureList* rpl0 = pcSlice->getSPS()->getRPLList0()->getReferencePictureList(ii); + for (int jj = 0; jj < pcSlice->getRPL0()->getNumberOfActivePictures(); jj++) + { + int tPoc = m_pcCfg->getRPLEntry(0, ii).m_POC + rpl0->getRefPicIdentifier(jj); + int kk = 0; + for (kk = 0; kk<m_pcCfg->getGOPSize(); kk++) + { + if (m_pcCfg->getRPLEntry(0, kk).m_POC == tPoc) + { + break; + } + } + int tTid = m_pcCfg->getRPLEntry(0, kk).m_temporalId; + if (tTid >= pcSlice->getTLayer()) + { + isSTSA = false; + break; + } + } + const ReferencePictureList* rpl1 = pcSlice->getSPS()->getRPLList1()->getReferencePictureList(ii); + for (int jj = 0; jj < pcSlice->getRPL1()->getNumberOfActivePictures(); jj++) + { + int tPoc = m_pcCfg->getRPLEntry(1, ii).m_POC + rpl1->getRefPicIdentifier(jj); + int kk = 0; + for (kk = 0; kk<m_pcCfg->getGOPSize(); kk++) + { + if (m_pcCfg->getRPLEntry(1, kk).m_POC == tPoc) + { + break; + } + } + int tTid = m_pcCfg->getRPLEntry(1, kk).m_temporalId; + if (tTid >= pcSlice->getTLayer()) + { + isSTSA = false; + break; + } + } + } +#else int lTid= m_pcCfg->getGOPEntry(ii).m_temporalId; if(lTid==pcSlice->getTLayer()) { @@ -1709,6 +1774,7 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, } } } +#endif } if(isSTSA==true) { @@ -1727,12 +1793,26 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, } } } +#if !JVET_M0128 if (pcSlice->getRPSidx() == -1) arrangeLongtermPicturesInRPS(pcSlice, rcListPic); RefPicListModification* refPicListModification = pcSlice->getRefPicListModification(); refPicListModification->setRefPicListModificationFlagL0(0); refPicListModification->setRefPicListModificationFlagL1(0); +#endif +#if JVET_M0128 + if (m_pcCfg->getUseCompositeRef() && getUseLTRef() && (pocCurr > getLastLTRefPoc())) + { + pcSlice->setNumRefIdx(REF_PIC_LIST_0, (pcSlice->isIntra()) ? 0 : min(m_pcCfg->getRPLEntry(0, iGOPid).m_numRefPicsActive + 1, pcSlice->getRPL0()->getNumberOfActivePictures())); + pcSlice->setNumRefIdx(REF_PIC_LIST_1, (!pcSlice->isInterB()) ? 0 : min(m_pcCfg->getRPLEntry(1, iGOPid).m_numRefPicsActive + 1, pcSlice->getRPL1()->getNumberOfActivePictures())); + } + else + { + pcSlice->setNumRefIdx(REF_PIC_LIST_0, (pcSlice->isIntra()) ? 0 : pcSlice->getRPL0()->getNumberOfActivePictures()); + pcSlice->setNumRefIdx(REF_PIC_LIST_1, (!pcSlice->isInterB()) ? 0 : pcSlice->getRPL1()->getNumberOfActivePictures()); + } +#else if (m_pcCfg->getUseCompositeRef() && getUseLTRef() && (pocCurr > getLastLTRefPoc())) { pcSlice->setNumRefIdx(REF_PIC_LIST_0, min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive + 1, pcSlice->getRPS()->getNumberOfPictures())); @@ -1743,11 +1823,16 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, pcSlice->setNumRefIdx(REF_PIC_LIST_0, std::min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive, pcSlice->getRPS()->getNumberOfPictures())); pcSlice->setNumRefIdx(REF_PIC_LIST_1, std::min(m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive, pcSlice->getRPS()->getNumberOfPictures())); } +#endif if (m_pcCfg->getUseCompositeRef() && getPrepareLTRef()) { arrangeCompositeReference(pcSlice, rcListPic, pocCurr); } // Set reference list +#if JVET_M0128 + pcSlice->constructRefPicList(rcListPic); +#else pcSlice->setRefPicList ( rcListPic ); +#endif if (m_pcCfg->getUseHashME()) { @@ -2735,8 +2820,15 @@ void EncGOP::compressGOP( int iPOCLast, int iNumPicRcvd, PicList& rcListPic, } m_pcSliceEncoder->setSliceSegmentIdx(sliceSegmentIdxCount); +#if JVET_M0128 + pcSlice->setRPL0(pcPic->slices[0]->getRPL0()); + pcSlice->setRPL1(pcPic->slices[0]->getRPL1()); + pcSlice->setRPL0idx(pcPic->slices[0]->getRPL0idx()); + pcSlice->setRPL1idx(pcPic->slices[0]->getRPL1idx()); +#else pcSlice->setRPS (pcPic->slices[0]->getRPS()); pcSlice->setRPSidx(pcPic->slices[0]->getRPSidx()); +#endif for ( uint32_t ui = 0 ; ui < numSubstreams; ui++ ) { @@ -3907,6 +3999,7 @@ void EncGOP::xAttachSliceDataToNalUnit (OutputNALUnit& rNalu, OutputBitstream* c codedSliceData->clear(); } +#if !JVET_M0128 // Function will arrange the long-term pictures in the decreasing order of poc_lsb_lt, // and among the pictures with the same lsb, it arranges them in increasing delta_poc_msb_cycle_lt value void EncGOP::arrangeLongtermPicturesInRPS(Slice *pcSlice, PicList& rcListPic) @@ -4013,6 +4106,7 @@ void EncGOP::arrangeLongtermPicturesInRPS(Slice *pcSlice, PicList& rcListPic) } } } +#endif void EncGOP::arrangeCompositeReference(Slice* pcSlice, PicList& rcListPic, int pocCurr) { diff --git a/source/Lib/EncoderLib/EncGOP.h b/source/Lib/EncoderLib/EncGOP.h index 984c957daab29590b13625c93f7f4f25918eae8e..7db9df8a7bbd16569abfc047ddae92b214af028e 100644 --- a/source/Lib/EncoderLib/EncGOP.h +++ b/source/Lib/EncoderLib/EncGOP.h @@ -208,7 +208,9 @@ public: #endif EncSlice* getSliceEncoder() { return m_pcSliceEncoder; } NalUnitType getNalUnitType( int pocCurr, int lastIdr, bool isField ); +#if !JVET_M0128 void arrangeLongtermPicturesInRPS(Slice *, PicList& ); +#endif void arrangeCompositeReference(Slice* pcSlice, PicList& rcListPic, int pocCurr); void updateCompositeReference(Slice* pcSlice, PicList& rcListPic, int pocCurr); diff --git a/source/Lib/EncoderLib/EncLib.cpp b/source/Lib/EncoderLib/EncLib.cpp index af79a559495178466512ee67a9fcea077d5b2365..563fa171c67dc398fd6f6e00cec2830f0484f9b8 100644 --- a/source/Lib/EncoderLib/EncLib.cpp +++ b/source/Lib/EncoderLib/EncLib.cpp @@ -295,7 +295,11 @@ void EncLib::init( bool isFieldCoding, AUWriterIf* auWriterIf ) #if !JVET_N0415_CTB_ALF xInitAPS(aps0); #endif +#if JVET_M0128 + xInitRPL(sps0, isFieldCoding); +#else xInitRPS(sps0, isFieldCoding); +#endif #if ER_CHROMA_QP_WCG_PPS if (m_wcgChromaQpControl.isEnabled()) @@ -1298,6 +1302,11 @@ void EncLib::xInitSPS(SPS &sps) sps.getSpsRangeExtension().setHighPrecisionOffsetsEnabledFlag(m_highPrecisionOffsetsEnabledFlag); sps.getSpsRangeExtension().setPersistentRiceAdaptationEnabledFlag(m_persistentRiceAdaptationEnabledFlag); sps.getSpsRangeExtension().setCabacBypassAlignmentEnabledFlag(m_cabacBypassAlignmentEnabledFlag); + +#if JVET_M0128 + if (m_uiIntraPeriod < 0) + sps.setRPL1CopyFromRPL0Flag(true); +#endif } void EncLib::xInitHrdParameters(SPS &sps) @@ -1517,8 +1526,13 @@ void EncLib::xInitPPS(PPS &pps, const SPS &sps) } for( int i = 0; i < getGOPSize(); i++) { +#if JVET_M0128 + CHECK(!(getRPLEntry(0, i).m_numRefPicsActive >= 0 && getRPLEntry(0, i).m_numRefPicsActive <= MAX_NUM_REF), "Unspecified error"); + histogram[getRPLEntry(0, i).m_numRefPicsActive]++; +#else CHECK(!(getGOPEntry(i).m_numRefPicsActive >= 0 && getGOPEntry(i).m_numRefPicsActive <= MAX_NUM_REF), "Unspecified error"); histogram[getGOPEntry(i).m_numRefPicsActive]++; +#endif } int maxHist=-1; @@ -1556,12 +1570,192 @@ void EncLib::xInitPPS(PPS &pps, const SPS &sps) #endif pps.pcv = new PreCalcValues( sps, pps, true ); +#if JVET_M0128 + pps.setRpl1IdxPresentFlag(sps.getRPL1IdxPresentFlag()); +#endif } void EncLib::xInitAPS(APS &aps) { //Do nothing now } + +#if JVET_M0128 +void EncLib::xInitRPL(SPS &sps, bool isFieldCoding) +{ + ReferencePictureList* rpl; + + int numRPLCandidates = getRPLCandidateSize(0); + sps.createRPLList0(numRPLCandidates + 1); + sps.createRPLList1(numRPLCandidates + 1); + RPLList* rplList = 0; + + for (int i = 0; i < 2; i++) + { + rplList = (i == 0) ? sps.getRPLList0() : sps.getRPLList1(); + for (int j = 0; j < numRPLCandidates; j++) + { + const RPLEntry &ge = getRPLEntry(i, j); + rpl = rplList->getReferencePictureList(j); + rpl->setNumberOfShorttermPictures(ge.m_numRefPics); + rpl->setNumberOfLongtermPictures(0); //Hardcoded as 0 for now. need to update this when implementing LTRP + rpl->setNumberOfActivePictures(ge.m_numRefPicsActive); + + for (int k = 0; k < ge.m_numRefPics; k++) + { + rpl->setRefPicIdentifier(k, ge.m_deltaRefPics[k], 0); + } + } + } + + //Check if all delta POC of STRP in each RPL has the same sign + //Check RPLL0 first + const RPLList* rplList0 = sps.getRPLList0(); + const RPLList* rplList1 = sps.getRPLList1(); + uint32_t numberOfRPL = sps.getNumRPL0() - 1; + + bool isAllEntriesinRPLHasSameSignFlag = true; + bool isFirstEntry = true; + bool lastSign = true; //true = positive ; false = negative + for (uint32_t ii = 0; isAllEntriesinRPLHasSameSignFlag && ii < numberOfRPL; ii++) + { + const ReferencePictureList* rpl = rplList0->getReferencePictureList(ii); + for (uint32_t jj = 0; isAllEntriesinRPLHasSameSignFlag && jj < rpl->getNumberOfActivePictures(); jj++) + { + if (!rpl->isRefPicLongterm(jj) && isFirstEntry) + { + lastSign = (rpl->getRefPicIdentifier(jj) >= 0) ? true : false; + isFirstEntry = false; + } + else if (!rpl->isRefPicLongterm(jj) && (((rpl->getRefPicIdentifier(jj) - rpl->getRefPicIdentifier(jj - 1)) >= 0 && lastSign == false) || ((rpl->getRefPicIdentifier(jj) - rpl->getRefPicIdentifier(jj - 1)) < 0 && lastSign == true))) + { + isAllEntriesinRPLHasSameSignFlag = false; + } + } + } + //Check RPLL1. Skip it if it is already found out that this flag is not true for RPL0 or if RPL1 is the same as RPL0 + numberOfRPL = sps.getNumRPL1() - 1; + isFirstEntry = true; + lastSign = true; + for (uint32_t ii = 0; isAllEntriesinRPLHasSameSignFlag && !sps.getRPL1CopyFromRPL0Flag() && ii < numberOfRPL; ii++) + { + isFirstEntry = true; + const ReferencePictureList* rpl = rplList1->getReferencePictureList(ii); + for (uint32_t jj = 0; isAllEntriesinRPLHasSameSignFlag && jj < rpl->getNumberOfActivePictures(); jj++) + { + if (!rpl->isRefPicLongterm(jj) && isFirstEntry) + { + lastSign = (rpl->getRefPicIdentifier(jj) >= 0) ? true : false; + isFirstEntry = false; + } + else if (!rpl->isRefPicLongterm(jj) && (((rpl->getRefPicIdentifier(jj) - rpl->getRefPicIdentifier(jj - 1)) >= 0 && lastSign == false) || ((rpl->getRefPicIdentifier(jj) - rpl->getRefPicIdentifier(jj - 1)) < 0 && lastSign == true))) + { + isAllEntriesinRPLHasSameSignFlag = false; + } + } + } + sps.setAllActiveRplEntriesHasSameSignFlag(isAllEntriesinRPLHasSameSignFlag); +} + +void EncLib::getActiveRefPicListNumForPOC(const SPS *sps, int POCCurr, int GOPid, uint32_t *activeL0, uint32_t *activeL1) +{ + if (m_uiIntraPeriod < 0) //Only for RA + { + *activeL0 = *activeL1 = 0; + return; + } + uint32_t rpl0Idx = GOPid; + uint32_t rpl1Idx = GOPid; + + int fullListNum = m_iGOPSize; + int partialListNum = getRPLCandidateSize(0) - m_iGOPSize; + int extraNum = fullListNum; + if (m_uiIntraPeriod < 0) + { + if (POCCurr < 10) + { + rpl0Idx = POCCurr + m_iGOPSize - 1; + rpl1Idx = POCCurr + m_iGOPSize - 1; + } + else + { + rpl0Idx = (POCCurr%m_iGOPSize == 0) ? m_iGOPSize - 1 : POCCurr%m_iGOPSize - 1; + rpl1Idx = (POCCurr%m_iGOPSize == 0) ? m_iGOPSize - 1 : POCCurr%m_iGOPSize - 1; + } + extraNum = fullListNum + partialListNum; + } + for (; extraNum<fullListNum + partialListNum; extraNum++) + { + if (m_uiIntraPeriod > 0 && getDecodingRefreshType() > 0) + { + int POCIndex = POCCurr%m_uiIntraPeriod; + if (POCIndex == 0) + POCIndex = m_uiIntraPeriod; + if (POCIndex == m_RPLList0[extraNum].m_POC) + { + rpl0Idx = extraNum; + rpl1Idx = extraNum; + extraNum++; + } + } + } + + const ReferencePictureList *rpl0 = sps->getRPLList0()->getReferencePictureList(rpl0Idx); + *activeL0 = rpl0->getNumberOfActivePictures(); + const ReferencePictureList *rpl1 = sps->getRPLList1()->getReferencePictureList(rpl1Idx); + *activeL1 = rpl1->getNumberOfActivePictures(); +} + +void EncLib::selectReferencePictureList(Slice* slice, int POCCurr, int GOPid, int ltPoc) +{ + bool isEncodeLtRef = (POCCurr == ltPoc); + if (m_compositeRefEnabled && isEncodeLtRef) + { + POCCurr++; + } + + slice->setRPL0idx(GOPid); + slice->setRPL1idx(GOPid); + + int fullListNum = m_iGOPSize; + int partialListNum = getRPLCandidateSize(0) - m_iGOPSize; + int extraNum = fullListNum; + if (m_uiIntraPeriod < 0) + { + if (POCCurr < 10) + { + slice->setRPL0idx(POCCurr + m_iGOPSize - 1); + slice->setRPL1idx(POCCurr + m_iGOPSize - 1); + } + else + { + slice->setRPL0idx((POCCurr%m_iGOPSize == 0) ? m_iGOPSize - 1 : POCCurr%m_iGOPSize - 1); + slice->setRPL1idx((POCCurr%m_iGOPSize == 0) ? m_iGOPSize - 1 : POCCurr%m_iGOPSize - 1); + } + extraNum = fullListNum + partialListNum; + } + for (; extraNum < fullListNum + partialListNum; extraNum++) + { + if (m_uiIntraPeriod > 0 && getDecodingRefreshType() > 0) + { + int POCIndex = POCCurr%m_uiIntraPeriod; + if (POCIndex == 0) + POCIndex = m_uiIntraPeriod; + if (POCIndex == m_RPLList0[extraNum].m_POC) + { + slice->setRPL0idx(extraNum); + slice->setRPL1idx(extraNum); + extraNum++; + } + } + } + + const ReferencePictureList *rpl0 = (slice->getSPS()->getRPLList0()->getReferencePictureList(slice->getRPL0idx())); + const ReferencePictureList *rpl1 = (slice->getSPS()->getRPLList1()->getReferencePictureList(slice->getRPL1idx())); + slice->setRPL0(rpl0); + slice->setRPL1(rpl1); +} +#else //Function for initializing m_RPSList, a list of ReferencePictureSet, based on the GOPEntry objects read from the config file. void EncLib::xInitRPS(SPS &sps, bool isFieldCoding) { @@ -1851,6 +2045,7 @@ int EncLib::getReferencePictureSetIdxForSOP(int POCCurr, int GOPid ) return rpsIdx; } +#endif void EncLib::xInitPPSforTiles(PPS &pps) { diff --git a/source/Lib/EncoderLib/EncLib.h b/source/Lib/EncoderLib/EncLib.h index af63301620bf18dae818b059f090b66d4299520e..48faedbd98d9b43768ff33f268da0ae8fd2cb1ad 100644 --- a/source/Lib/EncoderLib/EncLib.h +++ b/source/Lib/EncoderLib/EncLib.h @@ -174,7 +174,11 @@ protected: void xInitHrdParameters(SPS &sps); ///< initialize HRDParameters parameters void xInitPPSforTiles (PPS &pps); +#if JVET_M0128 + void xInitRPL(SPS &sps, bool isFieldCoding); ///< initialize SPS from encoder options +#else void xInitRPS (SPS &sps, bool isFieldCoding); ///< initialize PPS from encoder options +#endif public: EncLib(); @@ -227,10 +231,15 @@ public: RateCtrl* getRateCtrl () { return &m_cRateCtrl; } +#if JVET_M0128 + void getActiveRefPicListNumForPOC(const SPS *sps, int POCCurr, int GOPid, uint32_t *activeL0, uint32_t *activeL1); + void selectReferencePictureList(Slice* slice, int POCCurr, int GOPid, int ltPoc); +#else void selectReferencePictureSet(Slice* slice, int POCCurr, int GOPid , int ltPoc ); int getReferencePictureSetIdxForSOP(int POCCurr, int GOPid ); +#endif #if JCTVC_Y0038_PARAMS void setParamSetChanged(int spsId, int ppsId); diff --git a/source/Lib/EncoderLib/EncSlice.cpp b/source/Lib/EncoderLib/EncSlice.cpp index b49240c0f3c5c9d762d20d3f1a20c2efbd3644d5..6aa643ba5f03bbc3cf3057c753c3d4c24aac2374 100644 --- a/source/Lib/EncoderLib/EncSlice.cpp +++ b/source/Lib/EncoderLib/EncSlice.cpp @@ -686,8 +686,13 @@ void EncSlice::initEncSlice(Picture* pcPic, const int pocLast, const int pocCurr #endif #endif rpcSlice->setUseChromaQpAdj( rpcSlice->getPPS()->getPpsRangeExtension().getChromaQpOffsetListEnabledFlag() ); +#if JVET_M0128 + rpcSlice->setNumRefIdx(REF_PIC_LIST_0, m_pcCfg->getRPLEntry(0, iGOPid).m_numRefPicsActive); + rpcSlice->setNumRefIdx(REF_PIC_LIST_1, m_pcCfg->getRPLEntry(1, iGOPid).m_numRefPicsActive); +#else rpcSlice->setNumRefIdx(REF_PIC_LIST_0,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive); rpcSlice->setNumRefIdx(REF_PIC_LIST_1,m_pcCfg->getGOPEntry(iGOPid).m_numRefPicsActive); +#endif if ( m_pcCfg->getDeblockingFilterMetric() ) { diff --git a/source/Lib/EncoderLib/SEIEncoder.cpp b/source/Lib/EncoderLib/SEIEncoder.cpp index bdd87e44bb26a794871fd948a8cd19291d7d0ce0..f88a0f2ed9c24c76555908a08f126b57f2781b0d 100644 --- a/source/Lib/EncoderLib/SEIEncoder.cpp +++ b/source/Lib/EncoderLib/SEIEncoder.cpp @@ -206,6 +206,7 @@ void SEIEncoder::initSEIToneMappingInfo(SEIToneMappingInfo *seiToneMappingInfo) void SEIEncoder::initSEISOPDescription(SEISOPDescription *sopDescriptionSEI, Slice *slice, int picInGOP, int lastIdr, int currGOPSize) { +#if !JVET_M0128 //TODO: check if this SEI will be in VVC CHECK(!(m_isInitialized), "Unspecified error"); CHECK(!(sopDescriptionSEI != NULL), "Unspecified error"); CHECK(!(slice != NULL), "Unspecified error"); @@ -232,6 +233,7 @@ void SEIEncoder::initSEISOPDescription(SEISOPDescription *sopDescriptionSEI, Sli } sopDescriptionSEI->m_numPicsInSopMinus1 = i - 1; +#endif } void SEIEncoder::initSEIBufferingPeriod(SEIBufferingPeriod *bufferingPeriodSEI, Slice *slice) diff --git a/source/Lib/EncoderLib/VLCWriter.cpp b/source/Lib/EncoderLib/VLCWriter.cpp index d64e8b6cfc620e0aaa81b9b64c3f4ecaa75713df..450ad9fadd53feb07d0290e84d4e3aedb0c6a1e4 100644 --- a/source/Lib/EncoderLib/VLCWriter.cpp +++ b/source/Lib/EncoderLib/VLCWriter.cpp @@ -157,6 +157,42 @@ void AUDWriter::codeAUD(OutputBitstream& bs, const int pictureType) xWriteRbspTrailingBits(); } +#if JVET_M0128 +void HLSWriter::xCodeRefPicList(const ReferencePictureList* rpl, bool isLongTermPresent, uint32_t ltLsbBitsCount) +{ + WRITE_UVLC(rpl->getNumberOfShorttermPictures() + rpl->getNumberOfLongtermPictures(), "num_ref_entries[ listIdx ][ rplsIdx ]"); + uint32_t numRefPic = rpl->getNumberOfShorttermPictures() + rpl->getNumberOfLongtermPictures(); + int prevDelta = MAX_INT; + int deltaValue = 0; + bool firstSTRP = true; + for (int ii = 0; ii < numRefPic; ii++) + { + if (rpl->getNumberOfLongtermPictures() > 0) + WRITE_FLAG(!rpl->isRefPicLongterm(ii), "st_ref_pic_flag[ listIdx ][ rplsIdx ][ i ]"); + if (!rpl->isRefPicLongterm(ii)) + { + if (firstSTRP) + { + firstSTRP = false; + deltaValue = prevDelta = rpl->getRefPicIdentifier(ii); + } + else + { + deltaValue = rpl->getRefPicIdentifier(ii) - prevDelta; + prevDelta = rpl->getRefPicIdentifier(ii); + } + unsigned int absDeltaValue = (deltaValue < 0) ? 0 - deltaValue : deltaValue; + WRITE_UVLC(absDeltaValue, "abs_delta_poc_st[ listIdx ][ rplsIdx ][ i ]"); + if (absDeltaValue > 0) + WRITE_FLAG((deltaValue < 0) ? 0 : 1, "strp_entry_sign_flag[ listIdx ][ rplsIdx ][ i ]"); //0 means negative delta POC : 1 means positive + } + else + { + WRITE_CODE(rpl->getRefPicIdentifier(ii), ltLsbBitsCount, "poc_lsb_lt[listIdx][rplsIdx][i]"); + } + } +} +#else void HLSWriter::xCodeShortTermRefPicSet( const ReferencePictureSet* rps, bool calledFromSliceHeader, int idx) { //int lastBits = getNumberOfWrittenBits(); @@ -209,6 +245,7 @@ void HLSWriter::xCodeShortTermRefPicSet( const ReferencePictureSet* rps, bool ca //DTRACE( g_trace_ctx, D_RPSINFO, "irps=%d (%2d bits) ", rps->getInterRPSPrediction(), getNumberOfWrittenBits() - lastBits ); rps->printDeltaPOC(); } +#endif void HLSWriter::codePPS( const PPS* pcPPS ) { @@ -223,6 +260,9 @@ void HLSWriter::codePPS( const PPS* pcPPS ) WRITE_FLAG( pcPPS->getCabacInitPresentFlag() ? 1 : 0, "cabac_init_present_flag" ); WRITE_UVLC( pcPPS->getNumRefIdxL0DefaultActive()-1, "num_ref_idx_l0_default_active_minus1"); WRITE_UVLC( pcPPS->getNumRefIdxL1DefaultActive()-1, "num_ref_idx_l1_default_active_minus1"); +#if JVET_M0128 + WRITE_FLAG(pcPPS->getRpl1IdxPresentFlag() ? 1 : 0, "rpl1IdxPresentFlag"); +#endif WRITE_SVLC( pcPPS->getPicInitQPMinus26(), "init_qp_minus26"); WRITE_FLAG( pcPPS->getConstrainedIntraPred() ? 1 : 0, "constrained_intra_pred_flag" ); @@ -444,7 +484,9 @@ void HLSWriter::codePPS( const PPS* pcPPS ) codeScalingList( pcPPS->getScalingList() ); } #endif +#if !JVET_M0128 WRITE_FLAG( pcPPS->getListsModificationPresentFlag(), "lists_modification_present_flag"); +#endif WRITE_UVLC( pcPPS->getLog2ParallelMergeLevelMinus2(), "log2_parallel_merge_level_minus2"); WRITE_FLAG( pcPPS->getSliceHeaderExtensionPresentFlag() ? 1 : 0, "slice_segment_header_extension_present_flag"); @@ -1055,6 +1097,35 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) } } CHECK( pcSPS->getMaxCUWidth() != pcSPS->getMaxCUHeight(), "Rectangular CTUs not supported" ); +#if JVET_M0128 + WRITE_FLAG(pcSPS->getLongTermRefsPresent() ? 1 : 0, "long_term_ref_pics_flag"); + WRITE_FLAG(pcSPS->getRPL1CopyFromRPL0Flag() ? 1 : 0, "rpl1_copy_from_rpl0_flag"); + + const RPLList* rplList0 = pcSPS->getRPLList0(); + const RPLList* rplList1 = pcSPS->getRPLList1(); + uint32_t numberOfRPL = pcSPS->getNumRPL0() - 1; + + //Write candidate for List0 + numberOfRPL = pcSPS->getNumRPL0() - 1; + WRITE_UVLC(numberOfRPL, "num_ref_pic_lists_in_sps[0]"); + for (int ii = 0; ii < numberOfRPL; ii++) + { + const ReferencePictureList* rpl = rplList0->getReferencePictureList(ii); + xCodeRefPicList(rpl, pcSPS->getLongTermRefsPresent(), pcSPS->getBitsForPOC()); + } + + //Write candidate for List1 + if (!pcSPS->getRPL1CopyFromRPL0Flag()) + { + numberOfRPL = pcSPS->getNumRPL1() - 1; + WRITE_UVLC(numberOfRPL, "num_ref_pic_lists_in_sps[1]"); + for (int ii = 0; ii < numberOfRPL; ii++) + { + const ReferencePictureList* rpl = rplList1->getReferencePictureList(ii); + xCodeRefPicList(rpl, pcSPS->getLongTermRefsPresent(), pcSPS->getBitsForPOC()); + } + } +#endif WRITE_FLAG(pcSPS->getUseDualITree(), "qtbtt_dual_tree_intra_flag"); WRITE_UVLC(g_aucLog2[pcSPS->getCTUSize()] - MIN_CU_LOG2, "log2_ctu_size_minus2"); WRITE_UVLC(pcSPS->getLog2MinCodingBlockSize() - 2, "log2_min_luma_coding_block_size_minus2"); @@ -1203,6 +1274,7 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) #endif // KJS: reference picture sets to be replaced +#if !JVET_M0128 const RPSList* rpsList = pcSPS->getRPSList(); WRITE_UVLC(rpsList->getNumberOfReferencePictureSets(), "num_short_term_ref_pic_sets" ); @@ -1221,6 +1293,7 @@ void HLSWriter::codeSPS( const SPS* pcSPS ) WRITE_FLAG( pcSPS->getUsedByCurrPicLtSPSFlag(k), "used_by_curr_pic_lt_sps_flag[i]"); } } +#endif #if HEVC_USE_INTRA_SMOOTHING_T32 || HEVC_USE_INTRA_SMOOTHING_T64 WRITE_FLAG( pcSPS->getUseStrongIntraSmoothing(), "strong_intra_smoothing_enable_flag" ); @@ -1535,6 +1608,92 @@ void HLSWriter::codeSliceHeader ( Slice* pcSlice ) WRITE_CODE(pcSlice->getPOC() & pocMask, pocBits, "slice_pic_order_cnt_lsb"); if( !pcSlice->getIdrPicFlag() ) { +#if JVET_M0128 + //Write L0 related syntax elements + if (pcSlice->getSPS()->getNumRPL0() > 0) + { + WRITE_FLAG(pcSlice->getRPL0idx() != -1 ? 1 : 0, "ref_pic_list_sps_flag[0]"); + } + if (pcSlice->getRPL0idx() != -1) + { + if (pcSlice->getSPS()->getNumRPL0() > 1) + { + int numBits = 0; + while ((1 << numBits) < pcSlice->getSPS()->getNumRPL0()) + { + numBits++; + } + WRITE_CODE(pcSlice->getRPL0idx(), numBits, "ref_pic_list_idx[0]"); + } + } + else + { //write local RPL0 + xCodeRefPicList(pcSlice->getRPL0(), pcSlice->getSPS()->getLongTermRefsPresent(), pcSlice->getSPS()->getBitsForPOC()); + } + //Deal POC Msb cycle signalling for LTRP + if (pcSlice->getRPL0()->getNumberOfLongtermPictures()) + { + for (int i = 0; i < pcSlice->getRPL0()->getNumberOfLongtermPictures() + pcSlice->getRPL0()->getNumberOfShorttermPictures(); i++) + { + if (pcSlice->getRPL0()->isRefPicLongterm(i)) + { + WRITE_FLAG(pcSlice->getLocalRPL0()->getDeltaPocMSBPresentFlag(i) ? 1 : 0, "delta_poc_msb_present_flag[i][j]"); + if (pcSlice->getLocalRPL0()->getDeltaPocMSBPresentFlag(i)) + { + WRITE_UVLC(pcSlice->getLocalRPL0()->getDeltaPocMSBCycleLT(i), "delta_poc_msb_cycle_lt[i][j]"); + } + } + } + } + + //Write L1 related syntax elements + if (!pcSlice->getPPS()->getRpl1IdxPresentFlag()) + { + CHECK(pcSlice->getRPL1idx() != pcSlice->getRPL0idx(), "RPL1Idx is not signalled but it is not the same as RPL0Idx"); + if (pcSlice->getRPL1idx() == -1) + { //write local RPL1 + xCodeRefPicList(pcSlice->getRPL1(), pcSlice->getSPS()->getLongTermRefsPresent(), pcSlice->getSPS()->getBitsForPOC()); + } + } + else + { + if (pcSlice->getSPS()->getNumRPL1() > 0) + { + WRITE_FLAG(pcSlice->getRPL1idx() != -1 ? 1 : 0, "ref_pic_list_sps_flag[1]"); + } + if (pcSlice->getRPL1idx() != -1) + { + if (pcSlice->getSPS()->getNumRPL1() > 1) + { + int numBits = 0; + while ((1 << numBits) < pcSlice->getSPS()->getNumRPL1()) + { + numBits++; + } + WRITE_CODE(pcSlice->getRPL1idx(), numBits, "ref_pic_list_idx[1]"); + } + } + else + { //write local RPL1 + xCodeRefPicList(pcSlice->getRPL1(), pcSlice->getSPS()->getLongTermRefsPresent(), pcSlice->getSPS()->getBitsForPOC()); + } + } + //Deal POC Msb cycle signalling for LTRP + if (pcSlice->getRPL1()->getNumberOfLongtermPictures()) + { + for (int i = 0; i < pcSlice->getRPL1()->getNumberOfLongtermPictures() + pcSlice->getRPL1()->getNumberOfShorttermPictures(); i++) + { + if (pcSlice->getRPL1()->isRefPicLongterm(i)) + { + WRITE_FLAG(pcSlice->getLocalRPL1()->getDeltaPocMSBPresentFlag(i) ? 1 : 0, "delta_poc_msb_present_flag[i][j]"); + if (pcSlice->getLocalRPL1()->getDeltaPocMSBPresentFlag(i)) + { + WRITE_UVLC(pcSlice->getLocalRPL1()->getDeltaPocMSBCycleLT(i), "delta_poc_msb_cycle_lt[i][j]"); + } + } + } + } +#else const ReferencePictureSet* rps = pcSlice->getRPS(); // check for bitstream restriction stating that: @@ -1651,6 +1810,7 @@ void HLSWriter::codeSliceHeader ( Slice* pcSlice ) } } } +#endif if( pcSlice->getSPS()->getSPSTemporalMVPEnabledFlag() ) { WRITE_FLAG( pcSlice->getEnableTMVPFlag() ? 1 : 0, "slice_temporal_mvp_enabled_flag" ); @@ -1738,6 +1898,7 @@ void HLSWriter::codeSliceHeader ( Slice* pcSlice ) pcSlice->setNumRefIdx( REF_PIC_LIST_1, 0 ); } +#if !JVET_M0128 if( pcSlice->getPPS()->getListsModificationPresentFlag() && pcSlice->getNumRpsCurrTempList() > 1 ) { RefPicListModification* refPicListModification = pcSlice->getRefPicListModification(); @@ -1784,6 +1945,7 @@ void HLSWriter::codeSliceHeader ( Slice* pcSlice ) } } } +#endif if( pcSlice->isInterB() ) { diff --git a/source/Lib/EncoderLib/VLCWriter.h b/source/Lib/EncoderLib/VLCWriter.h index 143e9882e0dede77b312369529faca2b904e826a..358fd9cdf50586c4f4f2206a60ec0c521951f409 100644 --- a/source/Lib/EncoderLib/VLCWriter.h +++ b/source/Lib/EncoderLib/VLCWriter.h @@ -113,7 +113,11 @@ public: virtual ~HLSWriter() {} private: +#if JVET_M0128 + void xCodeRefPicList(const ReferencePictureList* rpl, bool isLongTermPresent, uint32_t ltLsbBitsCount); +#else void xCodeShortTermRefPicSet ( const ReferencePictureSet* pcRPS, bool calledFromSliceHeader, int idx ); +#endif bool xFindMatchingLTRP ( Slice* pcSlice, uint32_t *ltrpsIndex, int ltrpPOC, bool usedFlag ); void xCodePredWeightTable ( Slice* pcSlice ); #if HEVC_USE_SCALING_LISTS