You've already forked libopenshot
mirror of
https://github.com/OpenShot/libopenshot.git
synced 2026-03-02 08:53:52 -08:00
Replaced ImagMagick with QImage on almost all key methods and classes. Reprogrammed all effects and the entire rendering pipeline to use QImage and QTransforms, primarily for increases in speed and stability. libopenshot is more than 10X faster on many of the most CPU heavy tasks. This was a huge change, and still has a few minor issues relating to BlackMagick Decklink and Text rendering.... which should be resolved very soon.
Also, much work has been done on memory management / leak detection, and optimizations with multi-threading... including a new thread cacher class used by the video playback (which is smoother than ever).
This commit is contained in:
192
src/KeyFrame.cpp
192
src/KeyFrame.cpp
@@ -300,7 +300,6 @@ Json::Value Keyframe::JsonValue() {
|
||||
Point existing_point = Points[x];
|
||||
root["Points"].append(existing_point.JsonValue());
|
||||
}
|
||||
//root["Auto_Handle_Percentage"] = Auto_Handle_Percentage;
|
||||
|
||||
// return JsonValue
|
||||
return root;
|
||||
@@ -487,6 +486,7 @@ void Keyframe::PrintPoints() {
|
||||
if (needs_update)
|
||||
Process();
|
||||
|
||||
cout << fixed << setprecision(4);
|
||||
for (vector<Point>::iterator it = Points.begin(); it != Points.end(); it++) {
|
||||
Point p = *it;
|
||||
cout << p.co.X << "\t" << p.co.Y << endl;
|
||||
@@ -498,6 +498,7 @@ void Keyframe::PrintValues() {
|
||||
if (needs_update)
|
||||
Process();
|
||||
|
||||
cout << fixed << setprecision(4);
|
||||
cout << "Frame Number (X)\tValue (Y)\tIs Increasing\tRepeat Numerator\tRepeat Denominator\tDelta (Y Difference)" << endl;
|
||||
|
||||
for (vector<Coordinate>::iterator it = Values.begin() + 1; it != Values.end(); it++) {
|
||||
@@ -507,102 +508,103 @@ void Keyframe::PrintValues() {
|
||||
}
|
||||
|
||||
void Keyframe::Process() {
|
||||
// only process if needed
|
||||
if (!needs_update)
|
||||
return;
|
||||
else
|
||||
|
||||
#pragma omp critical (keyframe_process)
|
||||
{
|
||||
// only process if needed
|
||||
if (needs_update && Points.size() > 0)
|
||||
{
|
||||
|
||||
// Clear all values
|
||||
Values.clear();
|
||||
|
||||
// fill in all values between 1 and 1st point's co.X
|
||||
Point p1 = Points[0];
|
||||
if (Points.size() > 1)
|
||||
// Fill in previous X values (before 1st point)
|
||||
for (int x = 0; x < p1.co.X; x++)
|
||||
Values.push_back(Coordinate(Values.size(), p1.co.Y));
|
||||
else
|
||||
// Add a single value (since we only have 1 point)
|
||||
Values.push_back(Coordinate(Values.size(), p1.co.Y));
|
||||
|
||||
// Loop through each pair of points (1 less than the max points). Each
|
||||
// pair of points is used to process a segment of the keyframe.
|
||||
Point p2(0, 0);
|
||||
for (int x = 0; x < Points.size() - 1; x++) {
|
||||
p1 = Points[x];
|
||||
p2 = Points[x + 1];
|
||||
|
||||
// process segment p1,p2
|
||||
ProcessSegment(x, p1, p2);
|
||||
}
|
||||
|
||||
// Loop through each Value, and set the direction of the coordinate. This is used
|
||||
// when time mapping, to determine what direction the audio waveforms play.
|
||||
bool increasing = true;
|
||||
int repeat_count = 1;
|
||||
int last_value = 0;
|
||||
for (vector<Coordinate>::iterator it = Values.begin() + 1; it != Values.end(); it++) {
|
||||
int current_value = int(round((*it).Y));
|
||||
int next_value = int(round((*it).Y));
|
||||
int prev_value = int(round((*it).Y));
|
||||
if (it + 1 != Values.end())
|
||||
next_value = int(round((*(it + 1)).Y));
|
||||
if (it - 1 >= Values.begin())
|
||||
prev_value = int(round((*(it - 1)).Y));
|
||||
|
||||
// Loop forward and look for the next unique value (to determine direction)
|
||||
for (vector<Coordinate>::iterator direction_it = it + 1; direction_it != Values.end(); direction_it++) {
|
||||
int next = int(round((*direction_it).Y));
|
||||
|
||||
// Detect direction
|
||||
if (current_value < next)
|
||||
{
|
||||
increasing = true;
|
||||
break;
|
||||
}
|
||||
else if (current_value > next)
|
||||
{
|
||||
increasing = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Set direction
|
||||
(*it).IsIncreasing(increasing);
|
||||
|
||||
// Detect repeated Y value
|
||||
if (current_value == last_value)
|
||||
// repeated, so increment count
|
||||
repeat_count++;
|
||||
else
|
||||
// reset repeat counter
|
||||
repeat_count = 1;
|
||||
|
||||
// Detect how many 'more' times it's repeated
|
||||
int additional_repeats = 0;
|
||||
for (vector<Coordinate>::iterator repeat_it = it + 1; repeat_it != Values.end(); repeat_it++) {
|
||||
int next = int(round((*repeat_it).Y));
|
||||
if (next == current_value)
|
||||
// repeated, so increment count
|
||||
additional_repeats++;
|
||||
else
|
||||
break; // stop looping
|
||||
}
|
||||
|
||||
// Set repeat fraction
|
||||
(*it).Repeat(Fraction(repeat_count, repeat_count + additional_repeats));
|
||||
|
||||
// Set delta (i.e. different from previous unique Y value)
|
||||
(*it).Delta(current_value - last_value);
|
||||
|
||||
// track the last value
|
||||
last_value = current_value;
|
||||
}
|
||||
}
|
||||
|
||||
// reset flag
|
||||
needs_update = false;
|
||||
|
||||
// do not process if no points are found
|
||||
if (Points.size() == 0)
|
||||
return;
|
||||
|
||||
// Clear all values
|
||||
Values.clear();
|
||||
|
||||
// fill in all values between 1 and 1st point's co.X
|
||||
Point p1 = Points[0];
|
||||
if (Points.size() > 1)
|
||||
// Fill in previous X values (before 1st point)
|
||||
for (int x = 0; x < p1.co.X; x++)
|
||||
Values.push_back(Coordinate(Values.size(), p1.co.Y));
|
||||
else
|
||||
// Add a single value (since we only have 1 point)
|
||||
Values.push_back(Coordinate(Values.size(), p1.co.Y));
|
||||
|
||||
// Loop through each pair of points (1 less than the max points). Each
|
||||
// pair of points is used to process a segment of the keyframe.
|
||||
Point p2(0, 0);
|
||||
for (int x = 0; x < Points.size() - 1; x++) {
|
||||
p1 = Points[x];
|
||||
p2 = Points[x + 1];
|
||||
|
||||
// process segment p1,p2
|
||||
ProcessSegment(x, p1, p2);
|
||||
}
|
||||
|
||||
// Loop through each Value, and set the direction of the coordinate. This is used
|
||||
// when time mapping, to determine what direction the audio waveforms play.
|
||||
bool increasing = true;
|
||||
int repeat_count = 1;
|
||||
int last_value = 0;
|
||||
for (vector<Coordinate>::iterator it = Values.begin() + 1; it != Values.end(); it++) {
|
||||
int current_value = int(round((*it).Y));
|
||||
int next_value = int(round((*it).Y));
|
||||
int prev_value = int(round((*it).Y));
|
||||
if (it + 1 != Values.end())
|
||||
next_value = int(round((*(it + 1)).Y));
|
||||
if (it - 1 >= Values.begin())
|
||||
prev_value = int(round((*(it - 1)).Y));
|
||||
|
||||
// Loop forward and look for the next unique value (to determine direction)
|
||||
for (vector<Coordinate>::iterator direction_it = it + 1; direction_it != Values.end(); direction_it++) {
|
||||
int next = int(round((*direction_it).Y));
|
||||
|
||||
// Detect direction
|
||||
if (current_value < next)
|
||||
{
|
||||
increasing = true;
|
||||
break;
|
||||
}
|
||||
else if (current_value > next)
|
||||
{
|
||||
increasing = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Set direction
|
||||
(*it).IsIncreasing(increasing);
|
||||
|
||||
// Detect repeated Y value
|
||||
if (current_value == last_value)
|
||||
// repeated, so increment count
|
||||
repeat_count++;
|
||||
else
|
||||
// reset repeat counter
|
||||
repeat_count = 1;
|
||||
|
||||
// Detect how many 'more' times it's repeated
|
||||
int additional_repeats = 0;
|
||||
for (vector<Coordinate>::iterator repeat_it = it + 1; repeat_it != Values.end(); repeat_it++) {
|
||||
int next = int(round((*repeat_it).Y));
|
||||
if (next == current_value)
|
||||
// repeated, so increment count
|
||||
additional_repeats++;
|
||||
else
|
||||
break; // stop looping
|
||||
}
|
||||
|
||||
// Set repeat fraction
|
||||
(*it).Repeat(Fraction(repeat_count, repeat_count + additional_repeats));
|
||||
|
||||
// Set delta (i.e. different from previous unique Y value)
|
||||
(*it).Delta(current_value - last_value);
|
||||
|
||||
// track the last value
|
||||
last_value = current_value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user