MCPcopy Create free account
hub / github.com/OpenShot/libopenshot / add_layer

Method add_layer

src/Timeline.cpp:640–742  ·  view source on GitHub ↗

Process a new layer of video or audio

Source from the content-addressed store, hash-verified

638
639// Process a new layer of video or audio
640void Timeline::add_layer(std::shared_ptr<Frame> new_frame, Clip* source_clip, int64_t clip_frame_number, bool is_top_clip, float max_volume)
641{
642 // Create timeline options (with details about this current frame request)
643 TimelineInfoStruct options{};
644 options.is_top_clip = is_top_clip;
645 options.is_before_clip_keyframes = true;
646
647 // Get the clip's frame, composited on top of the current timeline frame
648 std::shared_ptr<Frame> source_frame;
649 source_frame = GetOrCreateFrame(new_frame, source_clip, clip_frame_number, &options);
650
651 // No frame found... so bail
652 if (!source_frame)
653 return;
654
655 // Debug output
656 ZmqLogger::Instance()->AppendDebugMethod(
657 "Timeline::add_layer",
658 "new_frame->number", new_frame->number,
659 "clip_frame_number", clip_frame_number);
660
661 /* COPY AUDIO - with correct volume */
662 if (source_clip->Reader()->info.has_audio) {
663 // Debug output
664 ZmqLogger::Instance()->AppendDebugMethod(
665 "Timeline::add_layer (Copy Audio)",
666 "source_clip->Reader()->info.has_audio", source_clip->Reader()->info.has_audio,
667 "source_frame->GetAudioChannelsCount()", source_frame->GetAudioChannelsCount(),
668 "info.channels", info.channels,
669 "clip_frame_number", clip_frame_number);
670
671 if (source_frame->GetAudioChannelsCount() == info.channels && source_clip->has_audio.GetInt(clip_frame_number) != 0)
672 {
673 // Ensure timeline frame matches the source samples once per frame
674 if (new_frame->GetAudioSamplesCount() != source_frame->GetAudioSamplesCount()){
675 new_frame->ResizeAudio(info.channels, source_frame->GetAudioSamplesCount(), info.sample_rate, info.channel_layout);
676 }
677
678 // Apply transition-driven equal-power audio fades for clips covered by a Mask transition.
679 const auto transition_audio_gains = ResolveTransitionAudioGains(source_clip, new_frame->number, is_top_clip);
680
681 for (int channel = 0; channel < source_frame->GetAudioChannelsCount(); channel++)
682 {
683 // Get volume from previous frame and this frame
684 float previous_volume = source_clip->volume.GetValue(clip_frame_number - 1);
685 float volume = source_clip->volume.GetValue(clip_frame_number);
686 previous_volume *= transition_audio_gains.first;
687 volume *= transition_audio_gains.second;
688 int channel_filter = source_clip->channel_filter.GetInt(clip_frame_number); // optional channel to filter (if not -1)
689 int channel_mapping = source_clip->channel_mapping.GetInt(clip_frame_number); // optional channel to map this channel to (if not -1)
690
691 // Apply volume mixing strategy
692 if (source_clip->mixing == VOLUME_MIX_AVERAGE && max_volume > 1.0) {
693 // Don't allow this clip to exceed 100% (divide volume equally between all overlapping clips with volume
694 previous_volume = previous_volume / max_volume;
695 volume = volume / max_volume;
696 }
697 else if (source_clip->mixing == VOLUME_MIX_REDUCE && max_volume > 1.0) {

Callers

nothing calls this directly

Calls 12

AppendDebugMethodMethod · 0.80
GetAudioChannelsCountMethod · 0.80
GetIntMethod · 0.80
GetAudioSamplesCountMethod · 0.80
ResizeAudioMethod · 0.80
GetValueMethod · 0.80
ApplyGainRampMethod · 0.80
AddAudioMethod · 0.80
GetAudioSamplesMethod · 0.80
GetWidthMethod · 0.80
GetHeightMethod · 0.80
ReaderMethod · 0.45

Tested by

no test coverage detected