You've already forked libopenshot
mirror of
https://github.com/OpenShot/libopenshot.git
synced 2026-03-02 08:53:52 -08:00
Fixed a bug with cropping logic on Clip (disabled it temporarily). I need to replace the Crop functionality with a more robust cropping tool. Also, updated Timeline to use the MaxWidth/MaxHeight settings when calling the clip (since those are set when the screen is resized).
This commit is contained in:
committed by
FeRD (Frank Dana)
parent
eb328f1190
commit
6da4e8fded
@@ -116,10 +116,10 @@ namespace openshot {
|
||||
int64_t adjust_frame_number_minimum(int64_t frame_number);
|
||||
|
||||
/// Apply effects to the source frame (if any)
|
||||
std::shared_ptr<openshot::Frame> apply_effects(std::shared_ptr<openshot::Frame> frame);
|
||||
void apply_effects(std::shared_ptr<openshot::Frame> frame);
|
||||
|
||||
/// Apply keyframes to the source frame (if any)
|
||||
std::shared_ptr<openshot::Frame> apply_keyframes(std::shared_ptr<openshot::Frame> frame, int width, int height);
|
||||
void apply_keyframes(std::shared_ptr<openshot::Frame> frame, int width, int height);
|
||||
|
||||
/// Get file extension
|
||||
std::string get_file_extension(std::string path);
|
||||
@@ -146,6 +146,9 @@ namespace openshot {
|
||||
void reverse_buffer(juce::AudioSampleBuffer* buffer);
|
||||
|
||||
public:
|
||||
/// Final cache object used to hold final frames
|
||||
CacheMemory final_cache;
|
||||
|
||||
openshot::GravityType gravity; ///< The gravity of a clip determines where it snaps to its parent
|
||||
openshot::ScaleType scale; ///< The scale determines how a clip should be resized to fit its parent
|
||||
openshot::AnchorType anchor; ///< The anchor determines what parent a clip should snap to
|
||||
@@ -168,7 +171,7 @@ namespace openshot {
|
||||
|
||||
|
||||
/// Get the cache object used by this reader (always returns NULL for this object)
|
||||
CacheMemory* GetCache() override { return NULL; };
|
||||
CacheMemory* GetCache() override { return &final_cache; };
|
||||
|
||||
/// Determine if reader is open or closed
|
||||
bool IsOpen() override { return is_open; };
|
||||
|
||||
39
src/Clip.cpp
39
src/Clip.cpp
@@ -107,6 +107,9 @@ void Clip::init_settings()
|
||||
// Init audio and video overrides
|
||||
has_audio = Keyframe(-1.0);
|
||||
has_video = Keyframe(-1.0);
|
||||
|
||||
// Initialize Clip cache
|
||||
final_cache.SetMaxBytesFromInfo(OPEN_MP_NUM_PROCESSORS * 2, info.width, info.height, info.sample_rate, info.channels);
|
||||
}
|
||||
|
||||
// Init reader's rotation (if any)
|
||||
@@ -352,6 +355,16 @@ std::shared_ptr<Frame> Clip::GetFrame(int64_t requested_frame, int width, int he
|
||||
// Adjust out of bounds frame number
|
||||
requested_frame = adjust_frame_number_minimum(requested_frame);
|
||||
|
||||
// Check the cache for this frame
|
||||
std::shared_ptr<Frame> cached_frame = final_cache.GetFrame(requested_frame);
|
||||
if (cached_frame) {
|
||||
// Debug output
|
||||
ZmqLogger::Instance()->AppendDebugMethod("Clip::GetFrame", "returned cached frame", requested_frame);
|
||||
|
||||
// Return the cached frame
|
||||
return cached_frame;
|
||||
}
|
||||
|
||||
// Adjust has_video and has_audio overrides
|
||||
int enabled_audio = has_audio.GetInt(requested_frame);
|
||||
if (enabled_audio == -1 && reader && reader->info.has_audio)
|
||||
@@ -406,6 +419,9 @@ std::shared_ptr<Frame> Clip::GetFrame(int64_t requested_frame, int width, int he
|
||||
// Apply keyframe / transforms
|
||||
apply_keyframes(frame, width, height);
|
||||
|
||||
// Cache frame
|
||||
final_cache.Add(frame);
|
||||
|
||||
// Return processed 'frame'
|
||||
return frame;
|
||||
}
|
||||
@@ -889,6 +905,9 @@ void Clip::SetJsonValue(const Json::Value root) {
|
||||
// Set parent data
|
||||
ClipBase::SetJsonValue(root);
|
||||
|
||||
// Clear cache
|
||||
final_cache.Clear();
|
||||
|
||||
// Set data from Json (if key is found)
|
||||
if (!root["gravity"].isNull())
|
||||
gravity = (GravityType) root["gravity"].asInt();
|
||||
@@ -1077,16 +1096,22 @@ void Clip::AddEffect(EffectBase* effect)
|
||||
|
||||
// Sort effects
|
||||
sort_effects();
|
||||
|
||||
// Clear cache
|
||||
final_cache.Clear();
|
||||
}
|
||||
|
||||
// Remove an effect from the clip
|
||||
void Clip::RemoveEffect(EffectBase* effect)
|
||||
{
|
||||
effects.remove(effect);
|
||||
|
||||
// Clear cache
|
||||
final_cache.Clear();
|
||||
}
|
||||
|
||||
// Apply effects to the source frame (if any)
|
||||
std::shared_ptr<Frame> Clip::apply_effects(std::shared_ptr<Frame> frame)
|
||||
void Clip::apply_effects(std::shared_ptr<Frame> frame)
|
||||
{
|
||||
// Find Effects at this position and layer
|
||||
for (auto effect : effects)
|
||||
@@ -1095,9 +1120,6 @@ std::shared_ptr<Frame> Clip::apply_effects(std::shared_ptr<Frame> frame)
|
||||
frame = effect->GetFrame(frame, frame->number);
|
||||
|
||||
} // end effect loop
|
||||
|
||||
// Return modified frame
|
||||
return frame;
|
||||
}
|
||||
|
||||
// Compare 2 floating point numbers for equality
|
||||
@@ -1108,7 +1130,7 @@ bool Clip::isEqual(double a, double b)
|
||||
|
||||
|
||||
// Apply keyframes to the source frame (if any)
|
||||
std::shared_ptr<Frame> Clip::apply_keyframes(std::shared_ptr<Frame> frame, int width, int height)
|
||||
void Clip::apply_keyframes(std::shared_ptr<Frame> frame, int width, int height)
|
||||
{
|
||||
// Get actual frame image data
|
||||
std::shared_ptr<QImage> source_image = frame->GetImage();
|
||||
@@ -1330,7 +1352,7 @@ std::shared_ptr<Frame> Clip::apply_keyframes(std::shared_ptr<Frame> frame, int w
|
||||
|
||||
/* COMPOSITE SOURCE IMAGE (LAYER) ONTO FINAL IMAGE */
|
||||
std::shared_ptr<QImage> new_image;
|
||||
new_image = std::shared_ptr<QImage>(new QImage(*source_image));
|
||||
new_image = std::shared_ptr<QImage>(new QImage(QSize(width, height), source_image->format()));
|
||||
new_image->fill(QColor(QString::fromStdString("#00000000")));
|
||||
|
||||
// Load timeline's new frame image into a QPainter
|
||||
@@ -1343,7 +1365,7 @@ std::shared_ptr<Frame> Clip::apply_keyframes(std::shared_ptr<Frame> frame, int w
|
||||
|
||||
// Composite a new layer onto the image
|
||||
painter.setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||
painter.drawImage(0, 0, *source_image, crop_x_value * source_image->width(), crop_y_value * source_image->height(), crop_w_value * source_image->width(), crop_h_value * source_image->height());
|
||||
painter.drawImage(0, 0, *source_image);
|
||||
|
||||
// Draw frame #'s on top of image (if needed)
|
||||
if (display != FRAME_DISPLAY_NONE) {
|
||||
@@ -1376,7 +1398,4 @@ std::shared_ptr<Frame> Clip::apply_keyframes(std::shared_ptr<Frame> frame, int w
|
||||
|
||||
// Add new QImage to frame
|
||||
frame->AddImage(new_image);
|
||||
|
||||
// Return modified frame
|
||||
return frame;
|
||||
}
|
||||
|
||||
@@ -441,7 +441,7 @@ std::shared_ptr<Frame> Timeline::GetOrCreateFrame(Clip* clip, int64_t number)
|
||||
|
||||
// Attempt to get a frame (but this could fail if a reader has just been closed)
|
||||
#pragma omp critical (T_GetOtCreateFrame)
|
||||
new_frame = std::shared_ptr<Frame>(clip->GetFrame(number, info.width, info.height, samples_in_frame));
|
||||
new_frame = std::shared_ptr<Frame>(clip->GetFrame(number, Settings::Instance()->MAX_WIDTH, Settings::Instance()->MAX_HEIGHT, samples_in_frame));
|
||||
|
||||
// Return real frame
|
||||
return new_frame;
|
||||
@@ -740,7 +740,7 @@ std::shared_ptr<Frame> Timeline::GetFrame(int64_t requested_frame)
|
||||
int samples_in_frame = Frame::GetSamplesPerFrame(frame_number, info.fps, info.sample_rate, info.channels);
|
||||
|
||||
// Cache clip object
|
||||
clip->GetFrame(clip_frame_number, info.width, info.height, samples_in_frame);
|
||||
clip->GetFrame(clip_frame_number, Settings::Instance()->MAX_WIDTH, Settings::Instance()->MAX_HEIGHT, samples_in_frame);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user