Adding new dependency: libzmq (ZeroMQ). Adding a new debug logging class powered by sockets and ZeroMQ, to allow a threadsafe way to communicate debug messages to a client application (i.e. openshot-qt). Also, removing unneeded Sleep.h functions. There will be lots more code utilizing ZeroMQ soon.

This commit is contained in:
Jonathan Thomas
2016-04-04 23:09:18 -05:00
parent 6d2d342719
commit 723bd24e5c
22 changed files with 322 additions and 207 deletions
+24
View File
@@ -0,0 +1,24 @@
# - Try to find ZMQ
# Once done this will define
# ZMQ_FOUND - System has ZMQ
# ZMQ_INCLUDE_DIRS - The ZMQ include directories
# ZMQ_LIBRARIES - The libraries needed to use ZMQ
# ZMQ_DEFINITIONS - Compiler switches required for using ZMQ
find_path ( ZMQ_INCLUDE_DIR zmq.h
PATHS /usr/include/
/usr/local/include/
$ENV{ZMQDIR}/include/ )
find_library ( ZMQ_LIBRARY NAMES zmq
PATHS /usr/lib/
/usr/local/lib/
$ENV{ZMQDIR}/lib/ )
set ( ZMQ_LIBRARIES ${ZMQ_LIBRARY} )
set ( ZMQ_INCLUDE_DIRS ${ZMQ_INCLUDE_DIR} )
include ( FindPackageHandleStandardArgs )
# handle the QUIETLY and REQUIRED arguments and set ZMQ_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args ( ZMQ DEFAULT_MSG ZMQ_LIBRARY ZMQ_INCLUDE_DIR )
-2
View File
@@ -44,8 +44,6 @@
#include "Cache.h"
#include "Exceptions.h"
#include "Json.h"
#include "Sleep.h"
using namespace std;
-1
View File
@@ -44,7 +44,6 @@
#include "Cache.h"
#include "Exceptions.h"
#include "OpenMPUtilities.h"
#include "Sleep.h"
using namespace std;
-1
View File
@@ -50,7 +50,6 @@
#include "Cache.h"
#include "Exceptions.h"
#include "OpenMPUtilities.h"
#include "Sleep.h"
using namespace std;
-1
View File
@@ -60,7 +60,6 @@
#include "AudioBufferSource.h"
#include "AudioResampler.h"
#include "Fraction.h"
#include "Sleep.h"
using namespace std;
-1
View File
@@ -48,7 +48,6 @@
#include "Cache.h"
#include "Exceptions.h"
#include "OpenMPUtilities.h"
#include "Sleep.h"
using namespace std;
-1
View File
@@ -132,7 +132,6 @@
#include "Point.h"
#include "Profiles.h"
#include "QtImageReader.h"
#include "Sleep.h"
#include "Timeline.h"
#endif
+2 -10
View File
@@ -32,11 +32,13 @@
#include <iomanip>
#include <tr1/memory>
#include <stdlib.h>
#include <sstream>
#include "Cache.h"
#include "ChannelLayouts.h"
#include "Fraction.h"
#include "Frame.h"
#include "Json.h"
#include "ZmqLogger.h"
#include <QtCore/qstring.h>
#include <QGraphicsItem>
#include <QGraphicsScene>
@@ -97,12 +99,6 @@ namespace openshot
CriticalSection getFrameCriticalSection;
CriticalSection processingCriticalSection;
/// Debug JSON root
Json::Value debug_root;
/// Append debug information as JSON
void AppendDebugItem(Json::Value debug_item);
/// Append debug information as JSON
void AppendDebugMethod(string method_name, string arg1_name, float arg1_value,
string arg2_name, float arg2_value,
@@ -160,10 +156,6 @@ namespace openshot
/// Open the reader (and start consuming resources, such as images or video files)
virtual void Open() = 0;
/// Output debug information as JSON
string OutputDebugJSON();
};
}
-54
View File
@@ -1,54 +0,0 @@
/**
* @file
* @brief Header file for Sleep functions
* @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_SLEEP_H
#define OPENSHOT_SLEEP_H
#ifdef _WINDOWS
#include <windows.h>
// Define a Windows-compatible usleep method (which sleeps for X microseconds). Linux/Mac already have a method for this.
void usleep(__int64 usec)
{
HANDLE timer;
LARGE_INTEGER ft;
ft.QuadPart = -(10*usec); // Convert to 100 nanosecond interval, negative value indicates relative time
timer = CreateWaitableTimer(NULL, TRUE, NULL);
SetWaitableTimer(timer, &ft, 0, NULL, NULL, 0);
WaitForSingleObject(timer, INFINITE);
CloseHandle(timer);
}
#else
#include <unistd.h>
// Define a Linux/Mac compatible Sleep method (which sleeps for x seconds). Windows already has a method for this.
#define Sleep(x) usleep((x)*1000)
#endif
#endif
+26 -26
View File
@@ -44,34 +44,34 @@
#include <sstream>
using namespace std;
/// This struct holds version number information. Use the GetVersion() method to access the current version of libopenshot.
struct OpenShotVersion
namespace openshot
{
int major; /// Major version number
int minor; /// Minor version number
int build; /// Build number
int so; /// Shared Object Number (incremented when API or ABI changes)
/// This struct holds version number information. Use the GetVersion() method to access the current version of libopenshot.
struct OpenShotVersion {
int major; /// Major version number
int minor; /// Minor version number
int build; /// Build number
int so; /// Shared Object Number (incremented when API or ABI changes)
/// Get a string version of the version (i.e. "Major.Minor.Build")
string ToString() {
stringstream version_string;
version_string << major << "." << minor << "." << build;
return version_string.str();
/// Get a string version of the version (i.e. "Major.Minor.Build")
string ToString() {
stringstream version_string;
version_string << major << "." << minor << "." << build;
return version_string.str();
}
};
/// Get the current version number of libopenshot (major, minor, and build number)
static OpenShotVersion GetVersion() {
OpenShotVersion version;
// Set version info
version.major = OPENSHOT_VERSION_MAJOR;
version.minor = OPENSHOT_VERSION_MINOR;
version.build = OPENSHOT_VERSION_BUILD;
version.so = OPENSHOT_VERSION_SO;
return version;
}
};
/// Get the current version number of libopenshot (major, minor, and build number)
static OpenShotVersion GetVersion()
{
OpenShotVersion version;
// Set version info
version.major = OPENSHOT_VERSION_MAJOR;
version.minor = OPENSHOT_VERSION_MINOR;
version.build = OPENSHOT_VERSION_BUILD;
version.so = OPENSHOT_VERSION_SO;
return version;
}
#endif
+1 -9
View File
@@ -34,6 +34,7 @@
#include "Fraction.h"
#include "Frame.h"
#include "ReaderBase.h"
#include "ZmqLogger.h"
using namespace std;
@@ -85,12 +86,6 @@ namespace openshot
{
protected:
/// Debug JSON root
Json::Value debug_root;
/// Append debug information as JSON
void AppendDebugItem(Json::Value debug_item);
/// Append debug information as JSON
void AppendDebugMethod(string method_name, string arg1_name, float arg1_value,
string arg2_name, float arg2_value,
@@ -134,9 +129,6 @@ namespace openshot
/// Open the writer (and start initializing streams)
virtual void Open() = 0;
/// Output debug information as JSON
string OutputDebugJSON();
};
}
+88
View File
@@ -0,0 +1,88 @@
/**
* @file
* @brief Header file for ZeroMQ-based Logger 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_LOGGER_H
#define OPENSHOT_LOGGER_H
#include "JuceLibraryCode/JuceHeader.h"
#include <iostream>
#include <stdlib.h>
#include <string>
#include <sstream>
#include <zmq.hpp>
#include <unistd.h>
using namespace std;
namespace openshot {
/**
* @brief This abstract class is the base class, used by all readers in libopenshot.
*
* 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.
*/
class ZmqLogger {
private:
CriticalSection loggerCriticalSection;
string connection;
/// ZMQ Context
zmq::context_t *context;
/// ZMQ Socket
zmq::socket_t *publisher;
/// Default constructor
ZmqLogger(){}; // Don't allow user to create an instance of this singleton
/// Default copy method
ZmqLogger(ZmqLogger const&){}; // Don't allow the user to copy this instance
/// Default assignment operator
ZmqLogger & operator=(ZmqLogger const&){}; // Don't allow the user to assign this instance
/// Private variable to keep track of singleton instance
static ZmqLogger * m_pInstance;
public:
/// Create or get an instance of this logger singleton (invoke the class with this method)
static ZmqLogger * Instance();
/// Set or change connection info for logger (i.e. tcp://*:5556)
void Connection(string new_connection);
/// Log message to all subscribers of this logger (if any)
void Log(string message);
};
}
#endif
+9
View File
@@ -152,6 +152,13 @@ if (OPENMP_FOUND)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OpenMP_CXX_FLAGS} ")
endif(OPENMP_FOUND)
################### ZEROMQ #####################
# Find ZeroMQ library (used for socket communication & logging)
FIND_PACKAGE(ZMQ REQUIRED)
# Include FFmpeg headers (needed for compile)
include_directories(${ZMQ_INCLUDE_DIRS})
################### JSONCPP #####################
# Include jsoncpp headers (needed for JSON parsing)
include_directories("../thirdparty/jsoncpp/include")
@@ -191,6 +198,7 @@ SET ( OPENSHOT_SOURCE_FILES
Frame.cpp
FrameMapper.cpp
KeyFrame.cpp
ZmqLogger.cpp
PlayerBase.cpp
Point.cpp
Profiles.cpp
@@ -251,6 +259,7 @@ SET ( REQUIRED_LIBRARIES
${LIBOPENSHOT_AUDIO_LIBRARIES}
${QT_LIBRARIES}
${PROFILER}
${ZMQ_LIBRARIES}
)
IF (OPENMP_FOUND)
+1 -4
View File
@@ -257,9 +257,6 @@ void FFmpegReader::Close()
missing_video_frames.clear();
}
// Clear debug json
debug_root.clear();
// Close the video file
avformat_close_input(&pFormatCtx);
av_freep(&pFormatCtx);
@@ -526,7 +523,7 @@ tr1::shared_ptr<Frame> FFmpegReader::ReadStream(long int requested_frame)
// Wait if too many frames are being processed
while (processing_video_frames.size() + processing_audio_frames.size() >= minimum_packets)
usleep(50);
usleep(2500);
// Get the next packet (if any)
if (packet_error < 0)
+1 -1
View File
@@ -371,7 +371,7 @@ void FFmpegWriter::WriteFrame(tr1::shared_ptr<Frame> frame) throw(ErrorEncodingV
{
// YES, WRITING... so wait until it finishes, before writing again
while (is_writing)
Sleep(1); // sleep for 250 milliseconds
usleep(250000); // sleep for 250 milliseconds
// Write frames to video file
write_queued_frames();
+1 -1
View File
@@ -908,7 +908,7 @@ void Frame::Play()
while (transport1.isPlaying())
{
cout << "playing" << endl;
Sleep(1);
usleep(1000000);
}
cout << "DONE!!!" << endl;
+23 -47
View File
@@ -63,21 +63,6 @@ ReaderBase::ReaderBase()
debug = false;
}
// Output debug information as JSON
string ReaderBase::OutputDebugJSON()
{
// Return formatted string
return debug_root.toStyledString();
}
// Append debug information as JSON
void ReaderBase::AppendDebugItem(Json::Value debug_item)
{
// Append item to root array
debug_root.append(debug_item);
}
// Append debug information as JSON
void ReaderBase::AppendDebugMethod(string method_name, string arg1_name, float arg1_value,
string arg2_name, float arg2_value,
@@ -90,46 +75,37 @@ void ReaderBase::AppendDebugMethod(string method_name, string arg1_name, float a
// Don't do anything
return;
Json::Value debug_item;
debug_item["method"] = method_name;
// Output to standard output
#pragma omp critical (debug_output)
{
cout << fixed << setprecision(4);
cout << "Debug: Method: " << method_name << " (";
stringstream message;
message << fixed << setprecision(4);
message << method_name << " (";
// Add attributes to method JSON
if (arg1_name.length() > 0) {
debug_item[arg1_name] = arg1_value;
cout << arg1_name << "=" << arg1_value;
}
if (arg2_name.length() > 0) {
debug_item[arg2_name] = arg2_value;
cout << ", " << arg2_name << "=" << arg2_value;
}
if (arg3_name.length() > 0) {
debug_item[arg3_name] = arg3_value;
cout << ", " << arg3_name << "=" << arg3_value;
}
if (arg4_name.length() > 0) {
debug_item[arg4_name] = arg4_value;
cout << ", " << arg4_name << "=" << arg4_value;
}
if (arg5_name.length() > 0) {
debug_item[arg5_name] = arg5_value;
cout << ", " << arg5_name << "=" << arg5_value;
}
if (arg6_name.length() > 0) {
debug_item[arg6_name] = arg6_value;
cout << ", " << arg6_name << "=" << arg6_value;
}
if (arg1_name.length() > 0)
message << arg1_name << "=" << arg1_value;
if (arg2_name.length() > 0)
message << ", " << arg2_name << "=" << arg2_value;
if (arg3_name.length() > 0)
message << ", " << arg3_name << "=" << arg3_value;
if (arg4_name.length() > 0)
message << ", " << arg4_name << "=" << arg4_value;
if (arg5_name.length() > 0)
message << ", " << arg5_name << "=" << arg5_value;
if (arg6_name.length() > 0)
message << ", " << arg6_name << "=" << arg6_value;
// Output to standard output
cout << ")" << endl;
message << ")" << endl;
// Append method to root array
debug_root.append(debug_item);
// Send message through ZMQ
ZmqLogger::Instance()->Log(message.str());
}
}
+28 -48
View File
@@ -63,20 +63,6 @@ WriterBase::WriterBase()
debug = false;
}
// Output debug information as JSON
string WriterBase::OutputDebugJSON()
{
// Return formatted string
return debug_root.toStyledString();
}
// Append debug information as JSON
void WriterBase::AppendDebugItem(Json::Value debug_item)
{
// Append item to root array
debug_root.append(debug_item);
}
// Append debug information as JSON
void WriterBase::AppendDebugMethod(string method_name, string arg1_name, float arg1_value,
string arg2_name, float arg2_value,
@@ -89,44 +75,38 @@ void WriterBase::AppendDebugMethod(string method_name, string arg1_name, float a
// Don't do anything
return;
Json::Value debug_item;
debug_item["method"] = method_name;
// Output to standard output
cout << fixed << setprecision(4);
cout << "Debug: Method: " << method_name << " (";
#pragma omp critical (debug_output)
{
stringstream message;
message << fixed << setprecision(4);
message << method_name << " (";
// Add attributes to method JSON
if (arg1_name.length() > 0) {
debug_item[arg1_name] = arg1_value;
cout << arg1_name << "=" << arg1_value;
}
if (arg2_name.length() > 0) {
debug_item[arg2_name] = arg2_value;
cout << ", " << arg2_name << "=" << arg2_value;
}
if (arg3_name.length() > 0) {
debug_item[arg3_name] = arg3_value;
cout << ", " << arg3_name << "=" << arg3_value;
}
if (arg4_name.length() > 0) {
debug_item[arg4_name] = arg4_value;
cout << ", " << arg4_name << "=" << arg4_value;
}
if (arg5_name.length() > 0) {
debug_item[arg5_name] = arg5_value;
cout << ", " << arg5_name << "=" << arg5_value;
}
if (arg6_name.length() > 0) {
debug_item[arg6_name] = arg6_value;
cout << ", " << arg6_name << "=" << arg6_value;
}
// Add attributes to method JSON
if (arg1_name.length() > 0)
message << arg1_name << "=" << arg1_value;
// Output to standard output
cout << ")" << endl;
if (arg2_name.length() > 0)
message << ", " << arg2_name << "=" << arg2_value;
// Append method to root array
debug_root.append(debug_item);
if (arg3_name.length() > 0)
message << ", " << arg3_name << "=" << arg3_value;
if (arg4_name.length() > 0)
message << ", " << arg4_name << "=" << arg4_value;
if (arg5_name.length() > 0)
message << ", " << arg5_name << "=" << arg5_value;
if (arg6_name.length() > 0)
message << ", " << arg6_name << "=" << arg6_value;
// Output to standard output
message << ")" << endl;
// Send message through ZMQ
ZmqLogger::Instance()->Log(message.str());
}
}
// This method copy's the info struct of a reader, and sets the writer with the same info
+106
View File
@@ -0,0 +1,106 @@
/**
* @file
* @brief Source file for ZeroMQ-based Logger 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/ZmqLogger.h"
using namespace std;
using namespace openshot;
// Global reference to logger
ZmqLogger *ZmqLogger::m_pInstance = NULL;
// Create or Get an instance of the logger singleton
ZmqLogger *ZmqLogger::Instance()
{
if (!m_pInstance) {
// Create the actual instance of logger only once
m_pInstance = new ZmqLogger;
// init ZMQ variables
m_pInstance->context = NULL;
m_pInstance->publisher = NULL;
m_pInstance->connection = "";
// Default connection
m_pInstance->Connection("tcp://*:5556");
}
return m_pInstance;
}
// Set the connection for this logger
void ZmqLogger::Connection(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);
// Does anything need to happen?
if (new_connection == connection)
return;
else
// Set new connection
connection = new_connection;
if (context == NULL) {
// Create ZMQ Context
context = new zmq::context_t(1);
}
if (publisher != NULL) {
// Close an existing bound publisher socket
publisher->close();
publisher = NULL;
}
// Create new publisher instance
publisher = new zmq::socket_t(*context, ZMQ_PUB);
// Bind to the socket
try {
publisher->bind(connection.c_str());
} catch (zmq::error_t &e) {
cout << "ZmqLogger::Connection - Error binding to " << connection << ". Switching to an available port." << endl;
connection = "tcp://*:*";
publisher->bind(connection.c_str());
}
// Sleeping to allow connection to wake up (0.25 seconds)
usleep(250000);
}
void ZmqLogger::Log(string message)
{
// Create a scoped lock, allowing only a single thread to run the following code at one time
const GenericScopedLock<CriticalSection> lock(loggerCriticalSection);
// Send example message
zmq::message_t reply (message.length());
memcpy (reply.data(), message.c_str(), message.length());
publisher->send(reply);
}
+3
View File
@@ -82,6 +82,7 @@
#include "../../../include/KeyFrame.h"
#include "../../../include/RendererBase.h"
#include "../../../include/Timeline.h"
#include "../../../include/ZmqLogger.h"
%}
@@ -145,6 +146,8 @@
%include "../../../include/KeyFrame.h"
%include "../../../include/RendererBase.h"
%include "../../../include/Timeline.h"
%include "../../../include/ZmqLogger.h"
#ifdef USE_IMAGEMAGICK
%include "../../../include/ImageReader.h"
%include "../../../include/ImageWriter.h"

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