@ -114,10 +114,12 @@ static FrameProgress *alloc_progress(void)
static VVCFrame * alloc_frame ( VVCContext * s , VVCFrameContext * fc )
static VVCFrame * alloc_frame ( VVCContext * s , VVCFrameContext * fc )
{
{
const VVCSPS * sps = fc - > ps . sps ;
const VVCPPS * pps = fc - > ps . pps ;
const VVCPPS * pps = fc - > ps . pps ;
for ( int i = 0 ; i < FF_ARRAY_ELEMS ( fc - > DPB ) ; i + + ) {
for ( int i = 0 ; i < FF_ARRAY_ELEMS ( fc - > DPB ) ; i + + ) {
int ret ;
int ret ;
VVCFrame * frame = & fc - > DPB [ i ] ;
VVCFrame * frame = & fc - > DPB [ i ] ;
VVCWindow * win = & frame - > scaling_win ;
if ( frame - > frame - > buf [ 0 ] )
if ( frame - > frame - > buf [ 0 ] )
continue ;
continue ;
@ -144,6 +146,13 @@ static VVCFrame *alloc_frame(VVCContext *s, VVCFrameContext *fc)
for ( int j = 0 ; j < frame - > ctb_count ; j + + )
for ( int j = 0 ; j < frame - > ctb_count ; j + + )
frame - > rpl_tab [ j ] = frame - > rpl ;
frame - > rpl_tab [ j ] = frame - > rpl ;
win - > left_offset = pps - > r - > pps_scaling_win_left_offset < < sps - > hshift [ CHROMA ] ;
win - > right_offset = pps - > r - > pps_scaling_win_right_offset < < sps - > hshift [ CHROMA ] ;
win - > top_offset = pps - > r - > pps_scaling_win_top_offset < < sps - > vshift [ CHROMA ] ;
win - > bottom_offset = pps - > r - > pps_scaling_win_bottom_offset < < sps - > vshift [ CHROMA ] ;
frame - > ref_width = pps - > r - > pps_pic_width_in_luma_samples - win - > left_offset - win - > right_offset ;
frame - > ref_height = pps - > r - > pps_pic_height_in_luma_samples - win - > bottom_offset - win - > top_offset ;
frame - > progress = alloc_progress ( ) ;
frame - > progress = alloc_progress ( ) ;
if ( ! frame - > progress )
if ( ! frame - > progress )
goto fail ;
goto fail ;
@ -353,6 +362,24 @@ static VVCFrame *generate_missing_ref(VVCContext *s, VVCFrameContext *fc, int po
return frame ;
return frame ;
}
}
# define CHECK_MAX(d) (frame->ref_##d * frame->sps->r->sps_pic_##d##_max_in_luma_samples >= ref->ref_##d * (frame->pps->r->pps_pic_##d##_in_luma_samples - max))
# define CHECK_SAMPLES(d) (frame->pps->r->pps_pic_##d##_in_luma_samples == ref->pps->r->pps_pic_##d##_in_luma_samples)
static int check_candidate_ref ( const VVCFrame * frame , const VVCRefPic * refp )
{
const VVCFrame * ref = refp - > ref ;
if ( refp - > is_scaled ) {
const int max = FFMAX ( 8 , frame - > sps - > min_cb_size_y ) ;
return frame - > ref_width * 2 > = ref - > ref_width & &
frame - > ref_height * 2 > = ref - > ref_height & &
frame - > ref_width < = ref - > ref_width * 8 & &
frame - > ref_height < = ref - > ref_height * 8 & &
CHECK_MAX ( width ) & & CHECK_MAX ( height ) ;
}
return CHECK_SAMPLES ( width ) & & CHECK_SAMPLES ( height ) ;
}
# define RPR_SCALE(f) (((ref->f << 14) + (fc->ref->f >> 1)) / fc->ref->f)
/* add a reference with the given poc to the list and mark it as used in DPB */
/* add a reference with the given poc to the list and mark it as used in DPB */
static int add_candidate_ref ( VVCContext * s , VVCFrameContext * fc , RefPicList * list ,
static int add_candidate_ref ( VVCContext * s , VVCFrameContext * fc , RefPicList * list ,
int poc , int ref_flag , uint8_t use_msb )
int poc , int ref_flag , uint8_t use_msb )
@ -372,6 +399,18 @@ static int add_candidate_ref(VVCContext *s, VVCFrameContext *fc, RefPicList *lis
refp - > poc = poc ;
refp - > poc = poc ;
refp - > ref = ref ;
refp - > ref = ref ;
refp - > is_lt = ref_flag & VVC_FRAME_FLAG_LONG_REF ;
refp - > is_lt = ref_flag & VVC_FRAME_FLAG_LONG_REF ;
refp - > is_scaled = ref - > sps - > r - > sps_num_subpics_minus1 ! = fc - > ref - > sps - > r - > sps_num_subpics_minus1 | |
memcmp ( & ref - > scaling_win , & fc - > ref - > scaling_win , sizeof ( ref - > scaling_win ) ) | |
ref - > pps - > r - > pps_pic_width_in_luma_samples ! = fc - > ref - > pps - > r - > pps_pic_width_in_luma_samples | |
ref - > pps - > r - > pps_pic_height_in_luma_samples ! = fc - > ref - > pps - > r - > pps_pic_height_in_luma_samples ;
if ( ! check_candidate_ref ( fc - > ref , refp ) )
return AVERROR_INVALIDDATA ;
if ( refp - > is_scaled ) {
refp - > scale [ 0 ] = RPR_SCALE ( ref_width ) ;
refp - > scale [ 1 ] = RPR_SCALE ( ref_height ) ;
}
list - > nb_refs + + ;
list - > nb_refs + + ;
mark_ref ( ref , ref_flag ) ;
mark_ref ( ref , ref_flag ) ;