Apply effects to the source frame (if any)
| 552 | |
| 553 | // Apply effects to the source frame (if any) |
| 554 | std::shared_ptr<Frame> Timeline::apply_effects(std::shared_ptr<Frame> frame, int64_t timeline_frame_number, int layer, TimelineInfoStruct* options) |
| 555 | { |
| 556 | // Debug output |
| 557 | ZmqLogger::Instance()->AppendDebugMethod( |
| 558 | "Timeline::apply_effects", |
| 559 | "frame->number", frame->number, |
| 560 | "timeline_frame_number", timeline_frame_number, |
| 561 | "layer", layer); |
| 562 | |
| 563 | // Find Effects at this position and layer |
| 564 | for (auto effect : effects) |
| 565 | { |
| 566 | // Does clip intersect the current requested time |
| 567 | const double fpsD = info.fps.ToDouble(); |
| 568 | int64_t effect_start_position = static_cast<int64_t>(std::llround(effect->Position() * fpsD)) + 1; |
| 569 | int64_t effect_end_position = static_cast<int64_t>(std::llround((effect->Position() + effect->Duration()) * fpsD)); |
| 570 | |
| 571 | bool does_effect_intersect = (effect_start_position <= timeline_frame_number && effect_end_position >= timeline_frame_number && effect->Layer() == layer); |
| 572 | |
| 573 | // Clip is visible |
| 574 | if (does_effect_intersect) |
| 575 | { |
| 576 | // Determine the frame needed for this clip (based on the position on the timeline) |
| 577 | int64_t effect_start_frame = static_cast<int64_t>(std::llround(effect->Start() * fpsD)) + 1; |
| 578 | int64_t effect_frame_number = timeline_frame_number - effect_start_position + effect_start_frame; |
| 579 | |
| 580 | if (!options->is_top_clip) |
| 581 | continue; // skip effect, if overlapped/covered by another clip on same layer |
| 582 | |
| 583 | if (options->is_before_clip_keyframes != effect->info.apply_before_clip) |
| 584 | continue; // skip effect, if this filter does not match |
| 585 | |
| 586 | // Debug output |
| 587 | ZmqLogger::Instance()->AppendDebugMethod( |
| 588 | "Timeline::apply_effects (Process Effect)", |
| 589 | "effect_frame_number", effect_frame_number, |
| 590 | "does_effect_intersect", does_effect_intersect); |
| 591 | |
| 592 | // Apply the effect to this frame |
| 593 | frame = effect->ProcessFrame(frame, effect_frame_number); |
| 594 | } |
| 595 | |
| 596 | } // end effect loop |
| 597 | |
| 598 | // Return modified frame |
| 599 | return frame; |
| 600 | } |
| 601 | |
| 602 | // Get or generate a blank frame |
| 603 | std::shared_ptr<Frame> Timeline::GetOrCreateFrame(std::shared_ptr<Frame> background_frame, Clip* clip, int64_t number, openshot::TimelineInfoStruct* options) |
nothing calls this directly
no test coverage detected