Get or generate a blank frame
| 735 | |
| 736 | // Get or generate a blank frame |
| 737 | std::shared_ptr<Frame> Clip::GetOrCreateFrame(int64_t number, bool enable_time) |
| 738 | { |
| 739 | try { |
| 740 | // Init to requested frame |
| 741 | int64_t clip_frame_number = adjust_frame_number_minimum(number); |
| 742 | bool is_increasing = true; |
| 743 | |
| 744 | // Adjust for time-mapping (if any) |
| 745 | if (enable_time && time.GetLength() > 1) { |
| 746 | is_increasing = time.IsIncreasing(clip_frame_number + 1); |
| 747 | const int64_t time_frame_number = adjust_frame_number_minimum(time.GetLong(clip_frame_number)); |
| 748 | if (auto *fm = dynamic_cast<FrameMapper*>(reader)) { |
| 749 | // Inform FrameMapper which direction this mapper frame is being requested |
| 750 | fm->SetDirectionHint(is_increasing); |
| 751 | } |
| 752 | clip_frame_number = time_frame_number; |
| 753 | } |
| 754 | |
| 755 | // Debug output |
| 756 | ZmqLogger::Instance()->AppendDebugMethod( |
| 757 | "Clip::GetOrCreateFrame (from reader)", |
| 758 | "number", number, "clip_frame_number", clip_frame_number); |
| 759 | |
| 760 | // Attempt to get a frame (but this could fail if a reader has just been closed) |
| 761 | auto reader_frame = reader->GetFrame(clip_frame_number); |
| 762 | if (reader_frame) { |
| 763 | // Override frame # (due to time-mapping might change it) |
| 764 | reader_frame->number = number; |
| 765 | reader_frame->SetAudioDirection(is_increasing); |
| 766 | |
| 767 | // Return real frame |
| 768 | // Create a new copy of reader frame |
| 769 | // This allows a clip to modify the pixels and audio of this frame without |
| 770 | // changing the underlying reader's frame data |
| 771 | auto reader_copy = std::make_shared<Frame>(*reader_frame.get()); |
| 772 | if (has_video.GetInt(number) == 0) { |
| 773 | // No video, so add transparent pixels |
| 774 | reader_copy->AddColor(QColor(Qt::transparent)); |
| 775 | } |
| 776 | if (has_audio.GetInt(number) == 0 || number > reader->info.video_length) { |
| 777 | // No audio, so include silence (also, mute audio if past end of reader) |
| 778 | reader_copy->AddAudioSilence(reader_copy->GetAudioSamplesCount()); |
| 779 | } |
| 780 | return reader_copy; |
| 781 | } |
| 782 | |
| 783 | } catch (const ReaderClosed & e) { |
| 784 | // ... |
| 785 | } catch (const OutOfBoundsFrame & e) { |
| 786 | // ... |
| 787 | } |
| 788 | |
| 789 | // Estimate # of samples needed for this frame |
| 790 | int estimated_samples_in_frame = Frame::GetSamplesPerFrame(number, reader->info.fps, reader->info.sample_rate, reader->info.channels); |
| 791 | |
| 792 | // Debug output |
| 793 | ZmqLogger::Instance()->AppendDebugMethod( |
| 794 | "Clip::GetOrCreateFrame (create blank)", |
nothing calls this directly
no test coverage detected