Now correctly updates EOF timestamp.
Unified · Split
| @@ -34,6 +34,7 @@ · 33 unmodified lines | |||
| 34 | #include "libavutil/rational.h" | 34 | #include "libavutil/rational.h" |
| 35 | #include "audio.h" | 35 | #include "audio.h" |
| 36 | #include "avfilter.h" | 36 | #include "avfilter.h" |
| 37 | #include "filters.h" | ||
| 37 | #include "internal.h" | 38 | #include "internal.h" |
| 38 | #include "video.h" | 39 | #include "video.h" |
| 39 | 40 | ||
| @@ -104,22 +105,58 @@ static int config_output_props(AVFilterLink *outlink) · 64 unmodified lines | |||
| 104 | return 0; | 105 | return 0; |
| 105 | } | 106 | } |
| 106 | 107 | ||
| 107 | static int filter_frame(AVFilterLink *inlink, AVFrame *frame) | 108 | static int64_t rescale_pts(AVFilterLink *inlink, AVFilterLink *outlink, int64_t orig_pts) |
| 108 | { | 109 | { |
| 109 | AVFilterContext *ctx = inlink->dst; | 110 | AVFilterContext *ctx = inlink->dst; |
| 110 | AVFilterLink *outlink = ctx->outputs[0]; | 111 | int64_t new_pts = orig_pts; |
| 111 | 112 | ||
| 112 | if (av_cmp_q(inlink->time_base, outlink->time_base)) { | 113 | if (av_cmp_q(inlink->time_base, outlink->time_base)) { |
| 113 | int64_t orig_pts = frame->pts; | 114 | new_pts = av_rescale_q(orig_pts, inlink->time_base, outlink->time_base); |
| 114 | frame->pts = av_rescale_q(frame->pts, inlink->time_base, outlink->time_base); | ||
| 115 | av_log(ctx, AV_LOG_DEBUG, "tb:%d/%d pts:%"PRId64" -> tb:%d/%d pts:%"PRId64"\n", | 115 | av_log(ctx, AV_LOG_DEBUG, "tb:%d/%d pts:%"PRId64" -> tb:%d/%d pts:%"PRId64"\n", |
| 116 | inlink ->time_base.num, inlink ->time_base.den, orig_pts, | 116 | inlink ->time_base.num, inlink ->time_base.den, orig_pts, |
| 117 | outlink->time_base.num, outlink->time_base.den, frame->pts); | 117 | outlink->time_base.num, outlink->time_base.den, new_pts); |
| 118 | } | 118 | } |
| 119 | 119 | ||
| 120 | return new_pts; | ||
| 121 | } | ||
| 122 | |||
| 123 | static int filter_frame(AVFilterLink *inlink, AVFrame *frame) | ||
| 124 | { | ||
| 125 | AVFilterContext *ctx = inlink->dst; | ||
| 126 | AVFilterLink *outlink = ctx->outputs[0]; | ||
| 127 | |||
| 128 | frame->pts = rescale_pts(inlink, outlink, frame->pts); | ||
| 129 | |||
| 120 | return ff_filter_frame(outlink, frame); | 130 | return ff_filter_frame(outlink, frame); |
| 121 | } | 131 | } |
| 122 | 132 | ||
| 133 | static int activate(AVFilterContext *ctx) | ||
| 134 | { | ||
| 135 | AVFilterLink *inlink = ctx->inputs[0]; | ||
| 136 | AVFilterLink *outlink = ctx->outputs[0]; | ||
| 137 | AVFrame *in; | ||
| 138 | int status; | ||
| 139 | int64_t pts; | ||
| 140 | int ret; | ||
| 141 | |||
| 142 | FF_FILTER_FORWARD_STATUS_BACK(outlink, inlink); | ||
| 143 | |||
| 144 | ret = ff_inlink_consume_frame(inlink, &in); | ||
| 145 | if (ret < 0) | ||
| 146 | return ret; | ||
| 147 | if (ret > 0) | ||
| 148 | return filter_frame(inlink, in); | ||
| 149 | |||
| 150 | if (ff_inlink_acknowledge_status(inlink, &status, &pts)) { | ||
| 151 | ff_outlink_set_status(outlink, status, rescale_pts(inlink, outlink, pts)); | ||
| 152 | return 0; | ||
| 153 | } | ||
| 154 | |||
| 155 | FF_FILTER_FORWARD_WANTED(outlink, inlink); | ||
| 156 | |||
| 157 | return FFERROR_NOT_READY; | ||
| 158 | } | ||
| 159 | |||
| 123 | #if CONFIG_SETTB_FILTER | 160 | #if CONFIG_SETTB_FILTER |
| 124 | 161 | ||
| 125 | DEFINE_OPTIONS(settb, VIDEO); | 162 | DEFINE_OPTIONS(settb, VIDEO); |
| @@ -129,7 +166,6 @@ static const AVFilterPad avfilter_vf_settb_inputs[] = { · 3 unmodified lines | |||
| 129 | { | 166 | { |
| 130 | .name = "default", | 167 | .name = "default", |
| 131 | .type = AVMEDIA_TYPE_VIDEO, | 168 | .type = AVMEDIA_TYPE_VIDEO, |
| 132 | .filter_frame = filter_frame, | ||
| 133 | }, | 169 | }, |
| 134 | { NULL } | 170 | { NULL } |
| 135 | }; | 171 | }; |
| @@ -150,6 +186,7 @@ AVFilter ff_vf_settb = { · 14 unmodified lines | |||
| 150 | .priv_class = &settb_class, | 186 | .priv_class = &settb_class, |
| 151 | .inputs = avfilter_vf_settb_inputs, | 187 | .inputs = avfilter_vf_settb_inputs, |
| 152 | .outputs = avfilter_vf_settb_outputs, | 188 | .outputs = avfilter_vf_settb_outputs, |
| 189 | .activate = activate, | ||
| 153 | }; | 190 | }; |
| 154 | #endif /* CONFIG_SETTB_FILTER */ | 191 | #endif /* CONFIG_SETTB_FILTER */ |
| 155 | 192 | ||
| @@ -162,7 +199,6 @@ static const AVFilterPad avfilter_af_asettb_inputs[] = { · 6 unmodified lines | |||
| 162 | { | 199 | { |
| 163 | .name = "default", | 200 | .name = "default", |
| 164 | .type = AVMEDIA_TYPE_AUDIO, | 201 | .type = AVMEDIA_TYPE_AUDIO, |
| 165 | .filter_frame = filter_frame, | ||
| 166 | }, | 202 | }, |
| 167 | { NULL } | 203 | { NULL } |
| 168 | }; | 204 | }; |
| @@ -183,5 +219,6 @@ AVFilter ff_af_asettb = { · 14 unmodified lines | |||
| 183 | .inputs = avfilter_af_asettb_inputs, | 219 | .inputs = avfilter_af_asettb_inputs, |
| 184 | .outputs = avfilter_af_asettb_outputs, | 220 | .outputs = avfilter_af_asettb_outputs, |
| 185 | .priv_class = &asettb_class, | 221 | .priv_class = &asettb_class, |
| 222 | .activate = activate, | ||
| 186 | }; | 223 | }; |
| 187 | #endif /* CONFIG_ASETTB_FILTER */ | 224 | #endif /* CONFIG_ASETTB_FILTER */ |