Adding new settings class to be used for changing realtime settings used by libopenshot, such as scaling mode for preview vs final render, or hardware decode, etc...

This commit is contained in:
Jonathan Thomas
2019-01-09 16:50:40 -06:00
parent e0ec603965
commit 13bd272ead
14 changed files with 245 additions and 36 deletions

View File

@@ -44,6 +44,7 @@
#include "CacheMemory.h"
#include "Exceptions.h"
#include "OpenMPUtilities.h"
#include "Settings.h"
using namespace std;
@@ -105,7 +106,6 @@ namespace openshot
bool check_interlace;
bool check_fps;
bool has_missing_frames;
bool use_omp_threads;
CacheMemory working_cache;
CacheMemory missing_frames;

View File

@@ -51,6 +51,7 @@
#include "Exceptions.h"
#include "OpenMPUtilities.h"
#include "ZmqLogger.h"
#include "Settings.h"
using namespace std;

View File

@@ -37,20 +37,6 @@
#define OPEN_MP_NUM_PROCESSORS (min(omp_get_num_procs(), 6))
#define FF_NUM_PROCESSORS (min(omp_get_num_procs(), 12))
using namespace std;
namespace openshot {
// Check if OS2_OMP_THREADS environment variable is present, and return
// if multiple threads should be used with OMP
static bool IsOMPEnabled() {
char* OS2_OMP_THREADS = getenv("OS2_OMP_THREADS");
if (OS2_OMP_THREADS != NULL && strcmp(OS2_OMP_THREADS, "0") == 0)
return false;
else
return true;
}
}
#endif

View File

@@ -134,5 +134,6 @@
#include "Profiles.h"
#include "QtImageReader.h"
#include "Timeline.h"
#include "Settings.h"
#endif

97
include/Settings.h Normal file
View File

@@ -0,0 +1,97 @@
/**
* @file
* @brief Header file for global Settings class
* @author Jonathan Thomas <jonathan@openshot.org>
*
* @section LICENSE
*
* Copyright (c) 2008-2014 OpenShot Studios, LLC
* <http://www.openshotstudios.com/>. This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
* world. For more information visit <http://www.openshot.org/>.
*
* OpenShot Library (libopenshot) is free software: you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* OpenShot Library (libopenshot) is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef OPENSHOT_SETTINGS_H
#define OPENSHOT_SETTINGS_H
#include "JuceLibraryCode/JuceHeader.h"
#include <iostream>
#include <iomanip>
#include <fstream>
#include <stdlib.h>
#include <string>
#include <sstream>
#include <stdio.h>
#include <time.h>
#include <zmq.hpp>
#include <unistd.h>
using namespace std;
namespace openshot {
/**
* @brief This class is contains settings used by libopenshot (and can be safely toggled at any point)
*
* Settings class is used primarily to toggle scale settings between preview and rendering, and adjust
* other runtime related settings.
*/
class Settings {
private:
/// Default constructor
Settings(){}; // Don't allow user to create an instance of this singleton
#if __GNUC__ >=7
/// Default copy method
Settings(Settings const&) = delete; // Don't allow the user to assign this instance
/// Default assignment operator
Settings & operator=(Settings const&) = delete; // Don't allow the user to assign this instance
#else
/// Default copy method
Settings(Settings const&) {}; // Don't allow the user to assign this instance
/// Default assignment operator
Settings & operator=(Settings const&); // Don't allow the user to assign this instance
#endif
/// Private variable to keep track of singleton instance
static Settings * m_pInstance;
public:
/// Use video card for faster video decoding (if supported)
bool HARDWARE_DECODE = false;
/// Use video card for faster video encoding (if supported)
bool HARDWARE_ENCODE = false;
/// Scale mode used in FFmpeg decoding and encoding (used as an optimization for faster previews)
bool HIGH_QUALITY_SCALING = false;
/// Wait for OpenMP task to finish before continuing (used to limit threads on slower systems)
bool WAIT_FOR_VIDEO_PROCESSING_TASK = false;
/// Create or get an instance of this logger singleton (invoke the class with this method)
static Settings * Instance();
};
}
#endif

View File

@@ -47,11 +47,10 @@ using namespace std;
namespace openshot {
/**
* @brief This abstract class is the base class, used by all readers in libopenshot.
* @brief This class is used for logging and sending those logs over a ZemoMQ socket to a listener
*
* Readers are types of classes that read video, audio, and image files, and
* return openshot::Frame objects. The only requirements for a 'reader', are to
* derive from this base class, implement the GetFrame method, and call the InitFileInfo() method.
* OpenShot desktop editor listens to this port, to receive libopenshot debug output. It both logs to
* a file and sends the stdout over a socket.
*/
class ZmqLogger {
private:

View File

@@ -244,6 +244,7 @@ SET ( OPENSHOT_SOURCE_FILES
Profiles.cpp
QtImageReader.cpp
QtPlayer.cpp
Settings.cpp
Timeline.cpp
# Qt Video Player

View File

@@ -38,7 +38,7 @@ FFmpegReader::FFmpegReader(string path)
check_fps(false), enable_seek(true), is_open(false), seek_audio_frame_found(0), seek_video_frame_found(0),
prev_samples(0), prev_pts(0), pts_total(0), pts_counter(0), is_duration_known(false), largest_frame_processed(0),
current_video_frame(0), has_missing_frames(false), num_packets_since_video_frame(0), num_checks_since_final(0),
packet(NULL), use_omp_threads(true) {
packet(NULL) {
// Initialize FFMpeg, and register all formats and codecs
AV_REGISTER_ALL
@@ -60,7 +60,7 @@ FFmpegReader::FFmpegReader(string path, bool inspect_reader)
check_fps(false), enable_seek(true), is_open(false), seek_audio_frame_found(0), seek_video_frame_found(0),
prev_samples(0), prev_pts(0), pts_total(0), pts_counter(0), is_duration_known(false), largest_frame_processed(0),
current_video_frame(0), has_missing_frames(false), num_packets_since_video_frame(0), num_checks_since_final(0),
packet(NULL), use_omp_threads(true) {
packet(NULL) {
// Initialize FFMpeg, and register all formats and codecs
AV_REGISTER_ALL
@@ -229,9 +229,6 @@ void FFmpegReader::Open()
missing_frames.SetMaxBytesFromInfo(OPEN_MP_NUM_PROCESSORS * 2, info.width, info.height, info.sample_rate, info.channels);
final_cache.SetMaxBytesFromInfo(OPEN_MP_NUM_PROCESSORS * 2, info.width, info.height, info.sample_rate, info.channels);
// Initialize OMP threading support
use_omp_threads = openshot::IsOMPEnabled();
// Mark as "open"
is_open = true;
}
@@ -613,7 +610,7 @@ std::shared_ptr<Frame> FFmpegReader::ReadStream(int64_t requested_frame)
// Process Video Packet
ProcessVideoPacket(requested_frame);
if (!use_omp_threads) {
if (openshot::Settings::Instance()->WAIT_FOR_VIDEO_PROCESSING_TASK) {
// Wait on each OMP task to complete before moving on to the next one. This slows
// down processing considerably, but might be more stable on some systems.
#pragma omp taskwait
@@ -628,16 +625,16 @@ std::shared_ptr<Frame> FFmpegReader::ReadStream(int64_t requested_frame)
num_packets_since_video_frame++;
// Check the status of a seek (if any)
if (is_seeking)
#pragma omp critical (openshot_seek)
check_seek = CheckSeek(false);
else
check_seek = false;
if (is_seeking)
#pragma omp critical (openshot_seek)
check_seek = CheckSeek(false);
else
check_seek = false;
if (check_seek) {
// Jump to the next iteration of this loop
continue;
}
if (check_seek) {
// Jump to the next iteration of this loop
continue;
}
// Update PTS / Frame Offset (if any)
UpdatePTSOffset(false);
@@ -919,8 +916,12 @@ void FFmpegReader::ProcessVideoPacket(int64_t requested_frame)
// Copy picture data from one AVFrame (or AVPicture) to another one.
AV_COPY_PICTURE_DATA(pFrameRGB, buffer, PIX_FMT_RGBA, width, height);
int scale_mode = SWS_FAST_BILINEAR;
if (openshot::Settings::Instance()->HIGH_QUALITY_SCALING) {
scale_mode = SWS_LANCZOS;
}
SwsContext *img_convert_ctx = sws_getContext(info.width, info.height, AV_GET_CODEC_PIXEL_FORMAT(pStream, pCodecCtx), width,
height, PIX_FMT_RGBA, SWS_LANCZOS, NULL, NULL, NULL);
height, PIX_FMT_RGBA, scale_mode, NULL, NULL, NULL);
// Resize / Convert to RGB
sws_scale(img_convert_ctx, my_frame->data, my_frame->linesize, 0,

View File

@@ -1748,11 +1748,16 @@ void FFmpegWriter::OutputStreamInfo()
// Init a collection of software rescalers (thread safe)
void FFmpegWriter::InitScalers(int source_width, int source_height)
{
int scale_mode = SWS_FAST_BILINEAR;
if (openshot::Settings::Instance()->HIGH_QUALITY_SCALING) {
scale_mode = SWS_LANCZOS;
}
// Init software rescalers vector (many of them, one for each thread)
for (int x = 0; x < num_of_rescalers; x++)
{
// Init the software scaler from FFMpeg
img_convert_ctx = sws_getContext(source_width, source_height, PIX_FMT_RGBA, info.width, info.height, AV_GET_CODEC_PIXEL_FORMAT(video_st, video_st->codec), SWS_LANCZOS, NULL, NULL, NULL);
img_convert_ctx = sws_getContext(source_width, source_height, PIX_FMT_RGBA, info.width, info.height, AV_GET_CODEC_PIXEL_FORMAT(video_st, video_st->codec), scale_mode, NULL, NULL, NULL);
// Add rescaler to vector
image_rescalers.push_back(img_convert_ctx);

50
src/Settings.cpp Normal file
View File

@@ -0,0 +1,50 @@
/**
* @file
* @brief Source file for global Settings class
* @author Jonathan Thomas <jonathan@openshot.org>
*
* @section LICENSE
*
* Copyright (c) 2008-2014 OpenShot Studios, LLC
* <http://www.openshotstudios.com/>. This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
* world. For more information visit <http://www.openshot.org/>.
*
* OpenShot Library (libopenshot) is free software: you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* OpenShot Library (libopenshot) is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "../include/Settings.h"
using namespace std;
using namespace openshot;
// Global reference to logger
Settings *Settings::m_pInstance = NULL;
// Create or Get an instance of the logger singleton
Settings *Settings::Instance()
{
if (!m_pInstance) {
// Create the actual instance of logger only once
m_pInstance = new Settings;
m_pInstance->HARDWARE_DECODE = false;
m_pInstance->HARDWARE_ENCODE = false;
m_pInstance->HIGH_QUALITY_SCALING = false;
m_pInstance->WAIT_FOR_VIDEO_PROCESSING_TASK = false;
}
return m_pInstance;
}

View File

@@ -84,6 +84,7 @@
#include "../../../include/QtPlayer.h"
#include "../../../include/KeyFrame.h"
#include "../../../include/RendererBase.h"
#include "../../../include/Settings.h"
#include "../../../include/Timeline.h"
#include "../../../include/ZmqLogger.h"
@@ -150,6 +151,7 @@
%include "../../../include/QtPlayer.h"
%include "../../../include/KeyFrame.h"
%include "../../../include/RendererBase.h"
%include "../../../include/Settings.h"
%include "../../../include/Timeline.h"
%include "../../../include/ZmqLogger.h"

View File

@@ -88,6 +88,7 @@ namespace std {
#include "../../../include/QtPlayer.h"
#include "../../../include/KeyFrame.h"
#include "../../../include/RendererBase.h"
#include "../../../include/Settings.h"
#include "../../../include/Timeline.h"
#include "../../../include/ZmqLogger.h"
@@ -143,6 +144,7 @@ namespace std {
%include "../../../include/QtPlayer.h"
%include "../../../include/KeyFrame.h"
%include "../../../include/RendererBase.h"
%include "../../../include/Settings.h"
%include "../../../include/Timeline.h"
%include "../../../include/ZmqLogger.h"

View File

@@ -172,6 +172,7 @@ IF (NOT DISABLE_TESTS)
FrameMapper_Tests.cpp
KeyFrame_Tests.cpp
Point_Tests.cpp
Settings_Tests.cpp
Timeline_Tests.cpp )
################ TESTER EXECUTABLE #################

63
tests/Settings_Tests.cpp Normal file
View File

@@ -0,0 +1,63 @@
/**
* @file
* @brief Unit tests for openshot::Color
* @author Jonathan Thomas <jonathan@openshot.org>
*
* @section LICENSE
*
* Copyright (c) 2008-2014 OpenShot Studios, LLC
* <http://www.openshotstudios.com/>. This file is part of
* OpenShot Library (libopenshot), an open-source project dedicated to
* delivering high quality video editing and animation solutions to the
* world. For more information visit <http://www.openshot.org/>.
*
* OpenShot Library (libopenshot) is free software: you can redistribute it
* and/or modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* OpenShot Library (libopenshot) is distributed in the hope that it will be
* useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with OpenShot Library. If not, see <http://www.gnu.org/licenses/>.
*/
#include "UnitTest++.h"
#include "../include/OpenShot.h"
using namespace std;
using namespace openshot;
TEST(Settings_Default_Constructor)
{
// Create an empty color
Settings *s = Settings::Instance();
CHECK_EQUAL(false, s->HARDWARE_DECODE);
CHECK_EQUAL(false, s->HARDWARE_ENCODE);
CHECK_EQUAL(false, s->HIGH_QUALITY_SCALING);
CHECK_EQUAL(false, s->WAIT_FOR_VIDEO_PROCESSING_TASK);
}
TEST(Settings_Change_Settings)
{
// Create an empty color
Settings *s = Settings::Instance();
s->HARDWARE_DECODE = true;
s->HARDWARE_ENCODE = true;
s->HIGH_QUALITY_SCALING = true;
s->WAIT_FOR_VIDEO_PROCESSING_TASK = true;
CHECK_EQUAL(true, s->HARDWARE_DECODE);
CHECK_EQUAL(true, s->HARDWARE_ENCODE);
CHECK_EQUAL(true, s->HIGH_QUALITY_SCALING);
CHECK_EQUAL(true, s->WAIT_FOR_VIDEO_PROCESSING_TASK);
CHECK_EQUAL(true, s->HARDWARE_DECODE);
CHECK_EQUAL(true, s->HARDWARE_ENCODE);
CHECK_EQUAL(true, Settings::Instance()->HIGH_QUALITY_SCALING);
CHECK_EQUAL(true, Settings::Instance()->WAIT_FOR_VIDEO_PROCESSING_TASK);
}