Merge branch 'opencv' into keyframe-refactor

This commit is contained in:
Brenno
2020-11-09 21:48:53 -03:00
26 changed files with 814 additions and 122 deletions

1
.gitignore vendored
View File

@@ -9,4 +9,3 @@
tags
*~
.vscode/

View File

@@ -35,7 +35,7 @@ if (POLICY CMP0057)
endif()
############### PROFILING #################
#set(PROFILER "/usr/lib/libprofiler.so.0.3.2")
#set(PROFILER "/usr/lib//usr/lib/libprofiler.so.0.4.5")
#set(PROFILER "/usr/lib/libtcmalloc.so.4")
if(CMAKE_VERSION VERSION_LESS 3.3)
@@ -125,6 +125,7 @@ set(EFFECTS_SOURCES
effects/Bars.cpp
effects/Blur.cpp
effects/Brightness.cpp
effects/Caption.cpp
effects/ChromaKey.cpp
effects/ColorShift.cpp
effects/Crop.cpp
@@ -400,8 +401,8 @@ endif()
find_package( OpenCV 4 )
if (OpenCV_FOUND)
message("\nCOMPILING WITH OPENCV\n")
set(CMAKE_SWIG_FLAGS "-DUSE_OPENCV=1")
add_definitions( -DUSE_OPENCV=1 )
list(APPEND CMAKE_SWIG_FLAGS -DUSE_OPENCV=1)
target_compile_definitions(openshot PUBLIC USE_OPENCV=1)
else()
message("\nOPENCV NOT FOUND, SOME FUNCTIONALITIES WILL BE DISABLED\n")
endif()

View File

@@ -32,7 +32,6 @@
using namespace openshot;
CVObjectDetection::CVObjectDetection(std::string processInfoJson, ProcessingController &processingController)
: processingController(&processingController), processingDevice("CPU"){
SetJson(processInfoJson);
@@ -56,6 +55,12 @@ void CVObjectDetection::detectObjectsClip(openshot::Clip &video, size_t _start,
video.Open();
if(error){
return;
}
processingController->SetError(false, "");
// Load names of classes
std::ifstream ifs(classesFile.c_str());
std::string line;
@@ -377,17 +382,36 @@ void CVObjectDetection::SetJsonValue(const Json::Value root) {
if (!root["protobuf_data_path"].isNull()){
protobuf_data_path = (root["protobuf_data_path"].asString());
}
if (!root["processing_device"].isNull()){
processingDevice = (root["processing_device"].asString());
if (!root["processing-device"].isNull()){
processingDevice = (root["processing-device"].asString());
}
if (!root["model_configuration"].isNull()){
modelConfiguration = (root["model_configuration"].asString());
if (!root["model-config"].isNull()){
modelConfiguration = (root["model-config"].asString());
std::ifstream infile(modelConfiguration);
if(!infile.good()){
processingController->SetError(true, "Incorrect path to model config file");
error = true;
}
}
if (!root["model_weights"].isNull()){
modelWeights= (root["model_weights"].asString());
if (!root["model-weights"].isNull()){
modelWeights= (root["model-weights"].asString());
std::ifstream infile(modelWeights);
if(!infile.good()){
processingController->SetError(true, "Incorrect path to model weight file");
error = true;
}
}
if (!root["classes_file"].isNull()){
classesFile = (root["classes_file"].asString());
if (!root["class-names"].isNull()){
classesFile = (root["class-names"].asString());
std::ifstream infile(classesFile);
if(!infile.good()){
processingController->SetError(true, "Incorrect path to class name file");
error = true;
}
}
}

View File

@@ -91,6 +91,8 @@ namespace openshot
size_t start;
size_t end;
bool error = false;
/// Will handle a Thread safely comutication between ClipProcessingJobs and the processing effect classes
ProcessingController *processingController;

View File

@@ -42,6 +42,11 @@ CVStabilization::CVStabilization(std::string processInfoJson, ProcessingControll
// Process clip and store necessary stabilization data
void CVStabilization::stabilizeClip(openshot::Clip& video, size_t _start, size_t _end, bool process_interval){
if(error){
return;
}
processingController->SetError(false, "");
start = _start; end = _end;
// Compute max and average transformation parameters
avr_dx=0; avr_dy=0; avr_da=0; max_dx=0; max_dy=0; max_da=0;
@@ -364,8 +369,8 @@ void CVStabilization::SetJsonValue(const Json::Value root) {
if (!root["protobuf_data_path"].isNull()){
protobuf_data_path = (root["protobuf_data_path"].asString());
}
if (!root["smoothing_window"].isNull()){
smoothingWindow = (root["smoothing_window"].asInt());
if (!root["smoothing-window"].isNull()){
smoothingWindow = (root["smoothing-window"].asInt());
}
}

View File

@@ -101,6 +101,7 @@ class CVStabilization {
std::string protobuf_data_path;
uint progress;
bool error = false;
/// Will handle a Thread safely comutication between ClipProcessingJobs and the processing effect classes
ProcessingController *processingController;

View File

@@ -65,7 +65,6 @@ cv::Ptr<cv::Tracker> CVTracker::selectTracker(std::string trackerType){
void CVTracker::trackClip(openshot::Clip& video, size_t _start, size_t _end, bool process_interval){
video.Open();
if(!json_interval){
start = _start; end = _end;
@@ -79,7 +78,12 @@ void CVTracker::trackClip(openshot::Clip& video, size_t _start, size_t _end, boo
start = start + video.Start() * video.Reader()->info.fps.ToInt();
end = video.End() * video.Reader()->info.fps.ToInt();
}
if(error){
return;
}
processingController->SetError(false, "");
bool trackerInit = false;
size_t frame;
@@ -92,7 +96,6 @@ void CVTracker::trackClip(openshot::Clip& video, size_t _start, size_t _end, boo
return;
}
std::cout<<"Frame: "<<frame<<"\n";
size_t frame_number = frame;
// Get current frame
std::shared_ptr<openshot::Frame> f = video.GetFrame(frame_number);
@@ -271,33 +274,39 @@ void CVTracker::SetJsonValue(const Json::Value root) {
if (!root["protobuf_data_path"].isNull()){
protobuf_data_path = (root["protobuf_data_path"].asString());
}
if (!root["tracker_type"].isNull()){
trackerType = (root["tracker_type"].asString());
if (!root["tracker-type"].isNull()){
trackerType = (root["tracker-type"].asString());
}
if (!root["bbox"].isNull()){
double x = root["bbox"]["x"].asDouble();
double y = root["bbox"]["y"].asDouble();
double w = root["bbox"]["w"].asDouble();
double h = root["bbox"]["h"].asDouble();
if (!root["region"].isNull()){
double x = root["region"]["x"].asDouble();
double y = root["region"]["y"].asDouble();
double w = root["region"]["width"].asDouble();
double h = root["region"]["height"].asDouble();
cv::Rect2d prev_bbox(x,y,w,h);
bbox = prev_bbox;
}
if (!root["first_frame"].isNull()){
start = root["first_frame"].asInt64();
else{
processingController->SetError(true, "No initial bounding box selected");
error = true;
}
if (!root["region"]["first-frame"].isNull()){
start = root["region"]["first-frame"].asInt64();
json_interval = true;
}
else{
processingController->SetError(true, "No first-frame");
error = true;
}
}
/*
||||||||||||||||||||||||||||||||||||||||||||||||||
ONLY FOR MAKE TEST
||||||||||||||||||||||||||||||||||||||||||||||||||
*/
// Load protobuf data file
bool CVTracker::_LoadTrackedData(){
// Create tracker message

View File

@@ -103,10 +103,12 @@ namespace openshot
/// Will handle a Thread safely comutication between ClipProcessingJobs and the processing effect classes
ProcessingController *processingController;
bool json_interval;
size_t start;
size_t end;
bool error = false;
// Initialize the tracker
bool initTracker(cv::Mat &frame, size_t frameId);

View File

@@ -5,7 +5,8 @@ ClipProcessingJobs::ClipProcessingJobs(std::string processingType, std::string p
processingType(processingType), processInfoJson(processInfoJson){
}
void ClipProcessingJobs::processClip(Clip& clip){
void ClipProcessingJobs::processClip(Clip& clip, std::string json){
processInfoJson = json;
// Process clip and save processed data
if(processingType == "Stabilizer"){
@@ -83,11 +84,13 @@ void ClipProcessingJobs::stabilizeClip(Clip& clip, ProcessingController& control
}
}
// Get processing progress while iterating on the clip
int ClipProcessingJobs::GetProgress(){
return (int)processingController.GetProgress();
}
// Check if processing finished
bool ClipProcessingJobs::IsDone(){
if(processingController.GetFinished()){
@@ -96,6 +99,17 @@ bool ClipProcessingJobs::IsDone(){
return processingController.GetFinished();
}
// stop preprocessing before finishing it
void ClipProcessingJobs::CancelProcessing(){
processingController.CancelProcessing();
}
// check if there is an error with the config
bool ClipProcessingJobs::GetError(){
return processingController.GetError();
}
// get the error message
std::string ClipProcessingJobs::GetErrorMessage(){
return processingController.GetErrorMessage();
}

View File

@@ -75,11 +75,14 @@ class ClipProcessingJobs{
// Constructor
ClipProcessingJobs(std::string processingType, std::string processInfoJson);
// Process clip accordingly to processingType
void processClip(Clip& clip);
void processClip(Clip& clip, std::string json);
// Thread related variables and methods
int GetProgress();
bool IsDone();
void CancelProcessing();
bool GetError();
std::string GetErrorMessage();
};

View File

@@ -52,6 +52,9 @@ EffectBase* EffectInfo::CreateEffect(std::string effect_type) {
else if (effect_type == "Brightness")
return new Brightness();
else if (effect_type == "Caption")
return new Caption();
else if (effect_type == "ChromaKey")
return new ChromaKey();
@@ -109,6 +112,7 @@ Json::Value EffectInfo::JsonValue() {
root.append(Bars().JsonInfo());
root.append(Blur().JsonInfo());
root.append(Brightness().JsonInfo());
root.append(Caption().JsonInfo());
root.append(ChromaKey().JsonInfo());
root.append(ColorShift().JsonInfo());
root.append(Crop().JsonInfo());

View File

@@ -35,6 +35,7 @@
#include "effects/Bars.h"
#include "effects/Blur.h"
#include "effects/Brightness.h"
#include "effects/Caption.h"
#include "effects/ChromaKey.h"
#include "effects/ColorShift.h"
#include "effects/Crop.h"

View File

@@ -968,14 +968,14 @@ cv::Mat Frame::GetImageCV()
std::shared_ptr<QImage> Frame::Mat2Qimage(cv::Mat img){
cv::cvtColor(img, img, cv::COLOR_BGR2RGB);
QImage qimg((uchar*) img.data, img.cols, img.rows, img.step, QImage::Format_RGBA8888_Premultiplied);
QImage qimg((uchar*) img.data, img.cols, img.rows, img.step, QImage::Format_RGB888);
std::shared_ptr<QImage> imgIn = std::make_shared<QImage>(qimg.copy());
// Always convert to RGBA8888 (if different)
if (imgIn->format() != QImage::Format_RGBA8888_Premultiplied)
*imgIn = imgIn->convertToFormat(QImage::Format_RGBA8888_Premultiplied);
return imgIn;
}

View File

@@ -41,10 +41,13 @@ class ProcessingController{
uint processingProgress;
bool processingFinished;
bool stopProcessing;
bool error = true;
std::string error_message;
std::mutex mtxProgress;
std::mutex mtxFinished;
std::mutex mtxStop;
std::mutex mtxerror;
public:
@@ -87,6 +90,24 @@ class ProcessingController{
return s;
}
void SetError(bool err, std::string message){
std::lock_guard<std::mutex> lck (mtxerror);
error = err;
error_message = message;
}
bool GetError(){
std::lock_guard<std::mutex> lck (mtxerror);
bool e = error;
return e;
}
std::string GetErrorMessage(){
std::lock_guard<std::mutex> lck (mtxerror);
std::string message = error_message;
return message;
}
};
#endif

View File

@@ -195,10 +195,10 @@ namespace openshot
// Stop video/audio playback
void PlayerPrivate::stopPlayback(int timeOutMilliseconds)
{
if (isThreadRunning()) stopThread(timeOutMilliseconds);
if (audioPlayback->isThreadRunning() && reader->info.has_audio) audioPlayback->stopThread(timeOutMilliseconds);
if (videoCache->isThreadRunning() && reader->info.has_video) videoCache->stopThread(timeOutMilliseconds);
if (videoPlayback->isThreadRunning() && reader->info.has_video) videoPlayback->stopThread(timeOutMilliseconds);
if (isThreadRunning()) stopThread(timeOutMilliseconds);
}
}

View File

@@ -93,43 +93,43 @@ namespace openshot
while (!threadShouldExit() && is_playing) {
// Cache frames before the other threads need them
// Cache frames up to the max frames. Reset to current position
// if cache gets too far away from display frame. Cache frames
// even when player is paused (i.e. speed 0).
while ((position - current_display_frame) < max_frames)
{
// Only cache up till the max_frames amount... then sleep
try
// Cache frames before the other threads need them
// Cache frames up to the max frames. Reset to current position
// if cache gets too far away from display frame. Cache frames
// even when player is paused (i.e. speed 0).
while (((position - current_display_frame) < max_frames) && is_playing)
{
if (reader) {
ZmqLogger::Instance()->AppendDebugMethod("VideoCacheThread::run (cache frame)", "position", position, "current_display_frame", current_display_frame, "max_frames", max_frames, "needed_frames", (position - current_display_frame));
// Only cache up till the max_frames amount... then sleep
try
{
if (reader) {
ZmqLogger::Instance()->AppendDebugMethod("VideoCacheThread::run (cache frame)", "position", position, "current_display_frame", current_display_frame, "max_frames", max_frames, "needed_frames", (position - current_display_frame));
// Force the frame to be generated
if (reader->GetCache()->GetSmallestFrame()) {
int64_t smallest_cached_frame = reader->GetCache()->GetSmallestFrame()->number;
if (smallest_cached_frame > current_display_frame) {
// Cache position has gotten too far away from current display frame.
// Reset the position to the current display frame.
position = current_display_frame;
// Force the frame to be generated
if (reader->GetCache()->GetSmallestFrame()) {
int64_t smallest_cached_frame = reader->GetCache()->GetSmallestFrame()->number;
if (smallest_cached_frame > current_display_frame) {
// Cache position has gotten too far away from current display frame.
// Reset the position to the current display frame.
position = current_display_frame;
}
}
reader->GetFrame(position);
}
reader->GetFrame(position);
}
catch (const OutOfBoundsFrame & e)
{
// Ignore out of bounds frame exceptions
}
}
catch (const OutOfBoundsFrame & e)
{
// Ignore out of bounds frame exceptions
// Increment frame number
position++;
}
// Increment frame number
position++;
}
// Sleep for 1 frame length
std::this_thread::sleep_for(frame_duration);
}
// Sleep for 1 frame length
std::this_thread::sleep_for(frame_duration);
}
return;
}

View File

@@ -34,14 +34,14 @@ using namespace std;
using namespace openshot;
// Global reference to logger
// Global reference to Settings
Settings *Settings::m_pInstance = NULL;
// Create or Get an instance of the logger singleton
// Create or Get an instance of the settings singleton
Settings *Settings::Instance()
{
if (!m_pInstance) {
// Create the actual instance of logger only once
// Create the actual instance of Settings only once
m_pInstance = new Settings;
m_pInstance->HARDWARE_DECODER = 0;
m_pInstance->HIGH_QUALITY_SCALING = false;
@@ -53,6 +53,7 @@ Settings *Settings::Instance()
m_pInstance->HW_DE_DEVICE_SET = 0;
m_pInstance->HW_EN_DEVICE_SET = 0;
m_pInstance->PLAYBACK_AUDIO_DEVICE_NAME = "";
m_pInstance->DEBUG_TO_STDERR = false;
}
return m_pInstance;

View File

@@ -127,6 +127,9 @@ namespace openshot {
/// The current install path of OpenShot (needs to be set when using Timeline(path), since certain
/// paths depend on the location of OpenShot transitions and files)
std::string PATH_OPENSHOT_INSTALL = "";
/// Whether to dump ZeroMQ debug messages to stderr
bool DEBUG_TO_STDERR = false;
/// Create or get an instance of this logger singleton (invoke the class with this method)
static Settings * Instance();

View File

@@ -34,8 +34,8 @@
#include "ResvgQt.h"
#endif
using namespace std;
using namespace openshot;
#include <sstream>
#include <iostream>
#include <iomanip>
@@ -70,7 +70,6 @@ ZmqLogger *ZmqLogger::Instance()
// This can only happen 1 time or it will crash
ResvgRenderer::initLog();
#endif
}
return m_pInstance;
@@ -80,7 +79,7 @@ ZmqLogger *ZmqLogger::Instance()
void ZmqLogger::Connection(std::string new_connection)
{
// Create a scoped lock, allowing only a single thread to run the following code at one time
const GenericScopedLock<CriticalSection> lock(loggerCriticalSection);
const juce::GenericScopedLock<juce::CriticalSection> lock(loggerCriticalSection);
// Does anything need to happen?
if (new_connection == connection)
@@ -124,7 +123,7 @@ void ZmqLogger::Log(std::string message)
return;
// Create a scoped lock, allowing only a single thread to run the following code at one time
const GenericScopedLock<CriticalSection> lock(loggerCriticalSection);
const juce::GenericScopedLock<juce::CriticalSection> lock(loggerCriticalSection);
// Send message over socket (ZeroMQ)
zmq::message_t reply (message.length());
@@ -195,19 +194,20 @@ void ZmqLogger::AppendDebugMethod(std::string method_name,
std::string arg5_name, float arg5_value,
std::string arg6_name, float arg6_value)
{
if (!enabled)
if (!enabled && !openshot::Settings::Instance()->DEBUG_TO_STDERR)
// Don't do anything
return;
{
// Create a scoped lock, allowing only a single thread to run the following code at one time
const GenericScopedLock<CriticalSection> lock(loggerCriticalSection);
const juce::GenericScopedLock<juce::CriticalSection> lock(loggerCriticalSection);
std::stringstream message;
message << std::fixed << std::setprecision(4);
// Construct message
message << method_name << " (";
// Add attributes to method JSON
if (arg1_name.length() > 0)
message << arg1_name << "=" << arg1_value;
@@ -226,10 +226,16 @@ void ZmqLogger::AppendDebugMethod(std::string method_name,
if (arg6_name.length() > 0)
message << ", " << arg6_name << "=" << arg6_value;
// Output to standard output
message << ")" << endl;
message << ")" << std::endl;
// Send message through ZMQ
Log(message.str());
if (openshot::Settings::Instance()->DEBUG_TO_STDERR) {
// Print message to stderr
std::clog << message.str();
}
if (enabled) {
// Send message through ZMQ
Log(message.str());
}
}
}

View File

@@ -43,6 +43,7 @@
#include <zmq.hpp>
#include <unistd.h>
#include "JuceHeader.h"
#include "Settings.h"
namespace openshot {
@@ -70,17 +71,17 @@ namespace openshot {
zmq::socket_t *publisher;
/// Default constructor
ZmqLogger(){}; // Don't allow user to create an instance of this singleton
ZmqLogger(){}; // Don't allow user to create an instance of this singleton
#if __GNUC__ >=7
/// Default copy method
ZmqLogger(ZmqLogger const&) = delete; // Don't allow the user to assign this instance
ZmqLogger(ZmqLogger const&) = delete; // Don't allow the user to assign this instance
/// Default assignment operator
ZmqLogger & operator=(ZmqLogger const&) = delete; // Don't allow the user to assign this instance
#else
/// Default copy method
ZmqLogger(ZmqLogger const&) {}; // Don't allow the user to assign this instance
ZmqLogger(ZmqLogger const&) {}; // Don't allow the user to assign this instance
/// Default assignment operator
ZmqLogger & operator=(ZmqLogger const&); // Don't allow the user to assign this instance
@@ -94,13 +95,15 @@ namespace openshot {
static ZmqLogger * Instance();
/// Append debug information
void AppendDebugMethod(std::string method_name,
std::string arg1_name="", float arg1_value=-1.0,
std::string arg2_name="", float arg2_value=-1.0,
std::string arg3_name="", float arg3_value=-1.0,
std::string arg4_name="", float arg4_value=-1.0,
std::string arg5_name="", float arg5_value=-1.0,
std::string arg6_name="", float arg6_value=-1.0);
void AppendDebugMethod(
std::string method_name,
std::string arg1_name="", float arg1_value=-1.0,
std::string arg2_name="", float arg2_value=-1.0,
std::string arg3_name="", float arg3_value=-1.0,
std::string arg4_name="", float arg4_value=-1.0,
std::string arg5_name="", float arg5_value=-1.0,
std::string arg6_name="", float arg6_value=-1.0
);
/// Close logger (sockets and/or files)
void Close();

Some files were not shown because too many files have changed in this diff Show More