Showing the changes to libavfilter/framesync2.c (1 of 2 files). Show all
Unified · Split
| @@ -46,6 +46,8 @@ enum { · 45 unmodified lines | ||
| 46 | 46 | STATE_EOF, |
| 47 | 47 | }; |
| 48 | 48 | |
| 49 | +static int consume_from_fifos(FFFrameSync *fs); | |
| 50 | + | |
| 49 | 51 | int ff_framesync2_init(FFFrameSync *fs, AVFilterContext *parent, unsigned nb_in) |
| 50 | 52 | { |
| 51 | 53 | /* For filters with several outputs, we will not be able to assume which |
| @@ -127,30 +129,20 @@ int ff_framesync2_configure(FFFrameSync *fs) · 75 unmodified lines | ||
| 127 | 129 | return 0; |
| 128 | 130 | } |
| 129 | 131 | |
| 130 | −static void framesync_advance(FFFrameSync *fs) | |
| 132 | +static int framesync_advance(FFFrameSync *fs) | |
| 131 | 133 | { |
| 132 | − int latest; | |
| 133 | 134 | unsigned i; |
| 134 | 135 | int64_t pts; |
| 136 | + int ret; | |
| 135 | 137 | |
| 136 | − if (fs->eof) | |
| 137 | − return; | |
| 138 | − while (!fs->frame_ready) { | |
| 139 | − latest = -1; | |
| 140 | − for (i = 0; i < fs->nb_in; i++) { | |
| 141 | − if (!fs->in[i].have_next) { | |
| 142 | − if (latest < 0 || fs->in[i].pts < fs->in[latest].pts) | |
| 143 | − latest = i; | |
| 144 | − } | |
| 145 | − } | |
| 146 | − if (latest >= 0) { | |
| 147 | − fs->in_request = latest; | |
| 148 | − break; | |
| 149 | − } | |
| 138 | + while (!(fs->frame_ready || fs->eof)) { | |
| 139 | + ret = consume_from_fifos(fs); | |
| 140 | + if (ret <= 0) | |
| 141 | + return ret; | |
| 150 | 142 | |
| 151 | − pts = fs->in[0].pts_next; | |
| 152 | − for (i = 1; i < fs->nb_in; i++) | |
| 153 | − if (fs->in[i].pts_next < pts) | |
| 143 | + pts = INT64_MAX; | |
| 144 | + for (i = 0; i < fs->nb_in; i++) | |
| 145 | + if (fs->in[i].have_next && fs->in[i].pts_next < pts) | |
| 154 | 146 | pts = fs->in[i].pts_next; |
| 155 | 147 | if (pts == INT64_MAX) { |
| 156 | 148 | framesync_eof(fs); |
| @@ -181,6 +173,7 @@ static void framesync_advance(FFFrameSync *fs) · 24 unmodified lines | ||
| 181 | 173 | fs->frame_ready = 0; |
| 182 | 174 | fs->pts = pts; |
| 183 | 175 | } |
| 176 | + return 0; | |
| 184 | 177 | } |
| 185 | 178 | |
| 186 | 179 | static int64_t framesync_pts_extrapolate(FFFrameSync *fs, unsigned in, |
| @@ -264,7 +257,7 @@ void ff_framesync2_uninit(FFFrameSync *fs) · 77 unmodified lines | ||
| 264 | 257 | av_freep(&fs->in); |
| 265 | 258 | } |
| 266 | 259 | |
| 267 | −int ff_framesync2_activate(FFFrameSync *fs) | |
| 260 | +static int consume_from_fifos(FFFrameSync *fs) | |
| 268 | 261 | { |
| 269 | 262 | AVFilterContext *ctx = fs->parent; |
| 270 | 263 | AVFrame *frame = NULL; |
| @@ -300,8 +293,16 @@ int ff_framesync2_activate(FFFrameSync *fs) · 29 unmodified lines | ||
| 300 | 293 | ff_inlink_request_frame(ctx->inputs[i]); |
| 301 | 294 | return 0; |
| 302 | 295 | } |
| 296 | + return 1; | |
| 297 | +} | |
| 303 | 298 | |
| 304 | − framesync_advance(fs); | |
| 299 | +int ff_framesync2_activate(FFFrameSync *fs) | |
| 300 | +{ | |
| 301 | + int ret; | |
| 302 | + | |
| 303 | + ret = framesync_advance(fs); | |
| 304 | + if (ret < 0) | |
| 305 | + return ret; | |
| 305 | 306 | if (fs->eof || !fs->frame_ready) |
| 306 | 307 | return 0; |
| 307 | 308 | ret = fs->on_event(fs); |
| @@ -311,3 +312,59 @@ int ff_framesync2_activate(FFFrameSync *fs) · 3 unmodified lines | ||
| 311 | 312 | |
| 312 | 313 | return 0; |
| 313 | 314 | } |
| 315 | + | |
| 316 | +int ff_framesync2_init_dualinput(FFFrameSync *fs, AVFilterContext *parent) | |
| 317 | +{ | |
| 318 | + int ret; | |
| 319 | + | |
| 320 | + ret = ff_framesync2_init(fs, parent, 2); | |
| 321 | + if (ret < 0) | |
| 322 | + return ret; | |
| 323 | + fs->in[0].time_base = parent->inputs[0]->time_base; | |
| 324 | + fs->in[1].time_base = parent->inputs[1]->time_base; | |
| 325 | + fs->in[0].sync = 2; | |
| 326 | + fs->in[0].before = EXT_STOP; | |
| 327 | + fs->in[0].after = EXT_INFINITY; | |
| 328 | + fs->in[1].sync = 1; | |
| 329 | + fs->in[1].before = EXT_NULL; | |
| 330 | + fs->in[1].after = EXT_INFINITY; | |
| 331 | + return 0; | |
| 332 | +} | |
| 333 | + | |
| 334 | +int ff_framesync2_dualinput_get(FFFrameSync *fs, AVFrame **f0, AVFrame **f1) | |
| 335 | +{ | |
| 336 | + AVFilterContext *ctx = fs->parent; | |
| 337 | + AVFrame *mainpic = NULL, *secondpic = NULL; | |
| 338 | + int ret = 0; | |
| 339 | + | |
| 340 | + if ((ret = ff_framesync2_get_frame(fs, 0, &mainpic, 1)) < 0 || | |
| 341 | + (ret = ff_framesync2_get_frame(fs, 1, &secondpic, 0)) < 0) { | |
| 342 | + av_frame_free(&mainpic); | |
| 343 | + return ret; | |
| 344 | + } | |
| 345 | + if (ret < 0) | |
| 346 | + return ret; | |
| 347 | + av_assert0(mainpic); | |
| 348 | + mainpic->pts = av_rescale_q(fs->pts, fs->time_base, ctx->outputs[0]->time_base); | |
| 349 | + if (ctx->is_disabled) | |
| 350 | + secondpic = NULL; | |
| 351 | + *f0 = mainpic; | |
| 352 | + *f1 = secondpic; | |
| 353 | + return 0; | |
| 354 | +} | |
| 355 | + | |
| 356 | +int ff_framesync2_dualinput_get_writable(FFFrameSync *fs, AVFrame **f0, AVFrame **f1) | |
| 357 | +{ | |
| 358 | + int ret; | |
| 359 | + | |
| 360 | + ret = ff_framesync2_dualinput_get(fs, f0, f1); | |
| 361 | + if (ret < 0) | |
| 362 | + return ret; | |
| 363 | + ret = ff_inlink_make_frame_writable(fs->parent->inputs[0], f0); | |
| 364 | + if (ret < 0) { | |
| 365 | + av_frame_free(f0); | |
| 366 | + av_frame_free(f1); | |
| 367 | + return ret; | |
| 368 | + } | |
| 369 | + return 0; | |
| 370 | +} | |