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:
Jonathan Thomas
2015-06-01 00:20:14 -07:00
parent 4b921b179e
commit b612f3339d
66 changed files with 1974 additions and 1390 deletions

View File

@@ -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;
}
}