@ -143,7 +143,6 @@ typedef struct LibplaceboInput {
pl_queue queue ;
pl_queue queue ;
enum pl_queue_status qstatus ;
enum pl_queue_status qstatus ;
struct pl_frame_mix mix ; ///< temporary storage
struct pl_frame_mix mix ; ///< temporary storage
AVFilterLink * link ;
AVFifo * out_pts ; ///< timestamps of wanted output frames
AVFifo * out_pts ; ///< timestamps of wanted output frames
int64_t status_pts ;
int64_t status_pts ;
int status ;
int status ;
@ -593,8 +592,7 @@ static void unlock_queue(void *priv, uint32_t qf, uint32_t qidx)
}
}
# endif
# endif
static int input_init ( AVFilterContext * avctx , AVFilterLink * link ,
static int input_init ( AVFilterContext * avctx , LibplaceboInput * input , int idx )
LibplaceboInput * input , int idx )
{
{
LibplaceboContext * s = avctx - > priv ;
LibplaceboContext * s = avctx - > priv ;
@ -603,7 +601,6 @@ static int input_init(AVFilterContext *avctx, AVFilterLink *link,
return AVERROR ( ENOMEM ) ;
return AVERROR ( ENOMEM ) ;
input - > queue = pl_queue_create ( s - > gpu ) ;
input - > queue = pl_queue_create ( s - > gpu ) ;
input - > renderer = pl_renderer_create ( s - > log , s - > gpu ) ;
input - > renderer = pl_renderer_create ( s - > log , s - > gpu ) ;
input - > link = link ;
input - > idx = idx ;
input - > idx = idx ;
return 0 ;
return 0 ;
@ -690,7 +687,7 @@ static int init_vulkan(AVFilterContext *avctx, const AVVulkanDeviceContext *hwct
if ( ! s - > inputs )
if ( ! s - > inputs )
return AVERROR ( ENOMEM ) ;
return AVERROR ( ENOMEM ) ;
for ( int i = 0 ; i < s - > nb_inputs ; i + + )
for ( int i = 0 ; i < s - > nb_inputs ; i + + )
RET ( input_init ( avctx , avctx - > inputs [ i ] , & s - > inputs [ i ] , i ) ) ;
RET ( input_init ( avctx , & s - > inputs [ i ] , i ) ) ;
/* fall through */
/* fall through */
fail :
fail :
@ -756,6 +753,7 @@ static void update_crops(AVFilterContext *ctx, LibplaceboInput *in,
{
{
FilterLink * outl = ff_filter_link ( ctx - > outputs [ 0 ] ) ;
FilterLink * outl = ff_filter_link ( ctx - > outputs [ 0 ] ) ;
LibplaceboContext * s = ctx - > priv ;
LibplaceboContext * s = ctx - > priv ;
const AVFilterLink * inlink = ctx - > inputs [ in - > idx ] ;
const AVFrame * ref = ref_frame ( & in - > mix ) ;
const AVFrame * ref = ref_frame ( & in - > mix ) ;
for ( int i = 0 ; i < in - > mix . num_frames ; i + + ) {
for ( int i = 0 ; i < in - > mix . num_frames ; i + + ) {
@ -763,15 +761,15 @@ static void update_crops(AVFilterContext *ctx, LibplaceboInput *in,
// own the entire pl_queue, and hence, the pointed-at frames.
// own the entire pl_queue, and hence, the pointed-at frames.
struct pl_frame * image = ( struct pl_frame * ) in - > mix . frames [ i ] ;
struct pl_frame * image = ( struct pl_frame * ) in - > mix . frames [ i ] ;
const AVFrame * src = pl_get_mapped_avframe ( image ) ;
const AVFrame * src = pl_get_mapped_avframe ( image ) ;
double image_pts = src - > pts * av_q2d ( in - > link - > time_base ) ;
double image_pts = src - > pts * av_q2d ( inlink - > time_base ) ;
/* Update dynamic variables */
/* Update dynamic variables */
s - > var_values [ VAR_IN_IDX ] = s - > var_values [ VAR_IDX ] = in - > idx ;
s - > var_values [ VAR_IN_IDX ] = s - > var_values [ VAR_IDX ] = in - > idx ;
s - > var_values [ VAR_IN_W ] = s - > var_values [ VAR_IW ] = in - > link - > w ;
s - > var_values [ VAR_IN_W ] = s - > var_values [ VAR_IW ] = inlink - > w ;
s - > var_values [ VAR_IN_H ] = s - > var_values [ VAR_IH ] = in - > link - > h ;
s - > var_values [ VAR_IN_H ] = s - > var_values [ VAR_IH ] = inlink - > h ;
s - > var_values [ VAR_A ] = ( double ) in - > link - > w / in - > link - > h ;
s - > var_values [ VAR_A ] = ( double ) inlink - > w / inlink - > h ;
s - > var_values [ VAR_SAR ] = in - > link - > sample_aspect_ratio . num ?
s - > var_values [ VAR_SAR ] = inlink - > sample_aspect_ratio . num ?
av_q2d ( in - > link - > sample_aspect_ratio ) : 1.0 ;
av_q2d ( inlink - > sample_aspect_ratio ) : 1.0 ;
s - > var_values [ VAR_IN_T ] = s - > var_values [ VAR_T ] = image_pts ;
s - > var_values [ VAR_IN_T ] = s - > var_values [ VAR_T ] = image_pts ;
s - > var_values [ VAR_OUT_T ] = s - > var_values [ VAR_OT ] = target_pts ;
s - > var_values [ VAR_OUT_T ] = s - > var_values [ VAR_OT ] = target_pts ;
s - > var_values [ VAR_N ] = outl - > frame_count_out ;
s - > var_values [ VAR_N ] = outl - > frame_count_out ;
@ -809,7 +807,7 @@ static void update_crops(AVFilterContext *ctx, LibplaceboInput *in,
target - > crop . y1 = target - > crop . y0 + s - > var_values [ VAR_POS_H ] ;
target - > crop . y1 = target - > crop . y0 + s - > var_values [ VAR_POS_H ] ;
if ( s - > normalize_sar ) {
if ( s - > normalize_sar ) {
float aspect = pl_rect2df_aspect ( & image - > crop ) ;
float aspect = pl_rect2df_aspect ( & image - > crop ) ;
aspect * = av_q2d ( in - > link - > sample_aspect_ratio ) ;
aspect * = av_q2d ( inlink - > sample_aspect_ratio ) ;
pl_rect2df_aspect_set ( & target - > crop , aspect , s - > pad_crop_ratio ) ;
pl_rect2df_aspect_set ( & target - > crop , aspect , s - > pad_crop_ratio ) ;
}
}
}
}
@ -899,7 +897,7 @@ static int output_frame(AVFilterContext *ctx, int64_t pts)
opts - > params . blend_params = NULL ;
opts - > params . blend_params = NULL ;
for ( int i = 0 ; i < s - > nb_inputs ; i + + ) {
for ( int i = 0 ; i < s - > nb_inputs ; i + + ) {
LibplaceboInput * in = & s - > inputs [ i ] ;
LibplaceboInput * in = & s - > inputs [ i ] ;
FilterLink * il = ff_filter_link ( in - > link ) ;
FilterLink * il = ff_filter_link ( ctx - > inputs [ in - > idx ] ) ;
FilterLink * ol = ff_filter_link ( outlink ) ;
FilterLink * ol = ff_filter_link ( outlink ) ;
int high_fps = av_cmp_q ( il - > frame_rate , ol - > frame_rate ) > = 0 ;
int high_fps = av_cmp_q ( il - > frame_rate , ol - > frame_rate ) > = 0 ;
if ( in - > qstatus ! = PL_QUEUE_OK )
if ( in - > qstatus ! = PL_QUEUE_OK )
@ -960,14 +958,15 @@ static int handle_input(AVFilterContext *ctx, LibplaceboInput *input)
int ret , status ;
int ret , status ;
LibplaceboContext * s = ctx - > priv ;
LibplaceboContext * s = ctx - > priv ;
AVFilterLink * outlink = ctx - > outputs [ 0 ] ;
AVFilterLink * outlink = ctx - > outputs [ 0 ] ;
AVFilterLink * inlink = ctx - > inputs [ input - > idx ] ;
AVFrame * in ;
AVFrame * in ;
int64_t pts ;
int64_t pts ;
while ( ( ret = ff_inlink_consume_frame ( input - > link , & in ) ) > 0 ) {
while ( ( ret = ff_inlink_consume_frame ( inlink , & in ) ) > 0 ) {
in - > opaque = s ;
in - > opaque = s ;
pl_queue_push ( input - > queue , & ( struct pl_source_frame ) {
pl_queue_push ( input - > queue , & ( struct pl_source_frame ) {
. pts = in - > pts * av_q2d ( input - > link - > time_base ) ,
. pts = in - > pts * av_q2d ( inlink - > time_base ) ,
. duration = in - > duration * av_q2d ( input - > link - > time_base ) ,
. duration = in - > duration * av_q2d ( inlink - > time_base ) ,
. first_field = pl_field_from_avframe ( in ) ,
. first_field = pl_field_from_avframe ( in ) ,
. frame_data = in ,
. frame_data = in ,
. map = map_frame ,
. map = map_frame ,
@ -977,7 +976,7 @@ static int handle_input(AVFilterContext *ctx, LibplaceboInput *input)
if ( ! s - > fps . num ) {
if ( ! s - > fps . num ) {
/* Internally queue an output frame for the same PTS */
/* Internally queue an output frame for the same PTS */
pts = av_rescale_q ( in - > pts , input - > link - > time_base , outlink - > time_base ) ;
pts = av_rescale_q ( in - > pts , inlink - > time_base , outlink - > time_base ) ;
av_fifo_write ( input - > out_pts , & pts , 1 ) ;
av_fifo_write ( input - > out_pts , & pts , 1 ) ;
}
}
}
}
@ -985,8 +984,8 @@ static int handle_input(AVFilterContext *ctx, LibplaceboInput *input)
if ( ret < 0 )
if ( ret < 0 )
return ret ;
return ret ;
if ( ! input - > status & & ff_inlink_acknowledge_status ( input - > link , & status , & pts ) ) {
if ( ! input - > status & & ff_inlink_acknowledge_status ( inlink , & status , & pts ) ) {
pts = av_rescale_q_rnd ( pts , input - > link - > time_base , outlink - > time_base ,
pts = av_rescale_q_rnd ( pts , inlink - > time_base , outlink - > time_base ,
AV_ROUND_UP ) ;
AV_ROUND_UP ) ;
pl_queue_push ( input - > queue , NULL ) ; /* Signal EOF to pl_queue */
pl_queue_push ( input - > queue , NULL ) ; /* Signal EOF to pl_queue */
input - > status = status ;
input - > status = status ;
@ -1035,7 +1034,7 @@ static int libplacebo_activate(AVFilterContext *ctx)
if ( av_fifo_peek ( in - > out_pts , & pts , 1 , 0 ) > = 0 ) {
if ( av_fifo_peek ( in - > out_pts , & pts , 1 , 0 ) > = 0 ) {
out_pts = FFMIN ( out_pts , pts ) ;
out_pts = FFMIN ( out_pts , pts ) ;
} else if ( ! in - > status ) {
} else if ( ! in - > status ) {
ff_inlink_request_frame ( in - > link ) ;
ff_inlink_request_frame ( ctx - > inputs [ in - > idx ] ) ;
retry = true ;
retry = true ;
}
}
}
}
@ -1061,7 +1060,7 @@ static int libplacebo_activate(AVFilterContext *ctx)
switch ( in - > qstatus ) {
switch ( in - > qstatus ) {
case PL_QUEUE_MORE :
case PL_QUEUE_MORE :
ff_inlink_request_frame ( in - > link ) ;
ff_inlink_request_frame ( ctx - > inputs [ in - > idx ] ) ;
retry = true ;
retry = true ;
break ;
break ;
case PL_QUEUE_OK :
case PL_QUEUE_OK :