2 * Copyright (c) 2021 Paul B Mahol
4 * This file is part of FFmpeg.
6 * FFmpeg is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * FFmpeg is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with FFmpeg; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 #include "config_components.h"
28 typedef struct LatencyContext
{
34 static av_cold
int init(AVFilterContext
*ctx
)
36 LatencyContext
*s
= ctx
->priv
;
38 s
->min_latency
= INT64_MAX
;
39 s
->max_latency
= INT64_MIN
;
44 static int activate(AVFilterContext
*ctx
)
46 LatencyContext
*s
= ctx
->priv
;
47 AVFilterLink
*inlink
= ctx
->inputs
[0];
48 FilterLink
*inl
= ff_filter_link(inlink
);
49 AVFilterLink
*outlink
= ctx
->outputs
[0];
51 FF_FILTER_FORWARD_STATUS_BACK(outlink
, inlink
);
53 if (!ctx
->is_disabled
&& ctx
->inputs
[0]->src
&&
54 ctx
->inputs
[0]->src
->nb_inputs
> 0) {
55 AVFilterLink
*prevlink
= ctx
->inputs
[0]->src
->inputs
[0];
56 FilterLink
*prevl
= ff_filter_link(prevlink
);
59 switch (prevlink
->type
) {
60 case AVMEDIA_TYPE_AUDIO
:
61 delta
= prevl
->sample_count_in
- inl
->sample_count_out
;
63 case AVMEDIA_TYPE_VIDEO
:
64 delta
= prevl
->frame_count_in
- inl
->frame_count_out
;
69 s
->min_latency
= FFMIN(s
->min_latency
, delta
);
70 s
->max_latency
= FFMAX(s
->max_latency
, delta
);
74 if (ff_inlink_queued_frames(inlink
)) {
75 AVFrame
*frame
= NULL
;
78 ret
= ff_inlink_consume_frame(inlink
, &frame
);
82 return ff_filter_frame(outlink
, frame
);
85 FF_FILTER_FORWARD_STATUS(inlink
, outlink
);
86 FF_FILTER_FORWARD_WANTED(outlink
, inlink
);
88 return FFERROR_NOT_READY
;
91 static av_cold
void uninit(AVFilterContext
*ctx
)
93 LatencyContext
*s
= ctx
->priv
;
95 if (s
->min_latency
!= INT64_MAX
)
96 av_log(ctx
, AV_LOG_INFO
, "Min latency: %"PRId64
"\n", s
->min_latency
);
97 if (s
->max_latency
!= INT64_MIN
)
98 av_log(ctx
, AV_LOG_INFO
, "Max latency: %"PRId64
"\n", s
->max_latency
);
101 #if CONFIG_LATENCY_FILTER
103 const FFFilter ff_vf_latency
= {
105 .p
.description
= NULL_IF_CONFIG_SMALL("Report video filtering latency."),
106 .p
.flags
= AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
|
107 AVFILTER_FLAG_METADATA_ONLY
,
108 .priv_size
= sizeof(LatencyContext
),
111 .activate
= activate
,
112 FILTER_INPUTS(ff_video_default_filterpad
),
113 FILTER_OUTPUTS(ff_video_default_filterpad
),
116 #endif // CONFIG_LATENCY_FILTER
118 #if CONFIG_ALATENCY_FILTER
120 const FFFilter ff_af_alatency
= {
121 .p
.name
= "alatency",
122 .p
.description
= NULL_IF_CONFIG_SMALL("Report audio filtering latency."),
123 .p
.flags
= AVFILTER_FLAG_SUPPORT_TIMELINE_INTERNAL
,
124 .priv_size
= sizeof(LatencyContext
),
127 .activate
= activate
,
128 FILTER_INPUTS(ff_audio_default_filterpad
),
129 FILTER_OUTPUTS(ff_audio_default_filterpad
),
131 #endif // CONFIG_ALATENCY_FILTER