1
0
Fork 0
mirror of https://github.com/fastogt/fastocloud.git synced 2025-03-09 23:18:50 +00:00

Release 1.4.4

This commit is contained in:
Topilski 2024-10-28 09:05:14 +03:00
commit 310132c21d
363 changed files with 32789 additions and 0 deletions

189
src/CMakeLists.txt Normal file
View file

@ -0,0 +1,189 @@
OPTION(MACHINE_LEARNING "ML plugins" OFF)
OPTION(AMAZON_KINESIS "AWS KVS plugins" OFF)
MESSAGE(STATUS "MACHINE_LEARNING: ${MACHINE_LEARNING}")
MESSAGE(STATUS "AMAZON_KINESIS: ${AMAZON_KINESIS}")
# projects globals names
SET(STREAMER_NAME streamer CACHE STRING "Stream process name")
SET(STREAMER_COMMON ${STREAMER_NAME}_common)
SET(SOURCE_ROOT ${CMAKE_SOURCE_DIR}/src)
# for sources only absolute paths
SET(BASE_HEADERS
${CMAKE_SOURCE_DIR}/src/base/types.h
${CMAKE_SOURCE_DIR}/src/base/utils.h
${CMAKE_SOURCE_DIR}/src/base/stream_config.h
${CMAKE_SOURCE_DIR}/src/base/stream_config_parse.h
${CMAKE_SOURCE_DIR}/src/base/constants.h
${CMAKE_SOURCE_DIR}/src/base/platform_macros.h
${CMAKE_SOURCE_DIR}/src/base/gst_constants.h
${CMAKE_SOURCE_DIR}/src/base/config_fields.h
${CMAKE_SOURCE_DIR}/src/base/channel_stats.h
${CMAKE_SOURCE_DIR}/src/base/stream_info.h
${CMAKE_SOURCE_DIR}/src/base/stream_struct.h
)
SET(BASE_SOURCES
${CMAKE_SOURCE_DIR}/src/base/types.cpp
${CMAKE_SOURCE_DIR}/src/base/utils.cpp
${CMAKE_SOURCE_DIR}/src/base/stream_config.cpp
${CMAKE_SOURCE_DIR}/src/base/stream_config_parse.cpp
${CMAKE_SOURCE_DIR}/src/base/constants.cpp
${CMAKE_SOURCE_DIR}/src/base/gst_constants.cpp
${CMAKE_SOURCE_DIR}/src/base/config_fields.cpp
${CMAKE_SOURCE_DIR}/src/base/channel_stats.cpp
${CMAKE_SOURCE_DIR}/src/base/stream_info.cpp
${CMAKE_SOURCE_DIR}/src/base/stream_struct.cpp
)
SET(STREAM_COMMANDS_INFO_HEADERS
${CMAKE_SOURCE_DIR}/src/stream_commands/commands.h
${CMAKE_SOURCE_DIR}/src/stream_commands/commands_factory.h
${CMAKE_SOURCE_DIR}/src/stream_commands/commands_info/stop_info.h
${CMAKE_SOURCE_DIR}/src/stream_commands/commands_info/restart_info.h
${CMAKE_SOURCE_DIR}/src/stream_commands/commands_info/changed_sources_info.h
${CMAKE_SOURCE_DIR}/src/stream_commands/commands_info/statistic_info.h
${CMAKE_SOURCE_DIR}/src/stream_commands/commands_info/details/channel_stats_info.h
)
SET(STREAM_COMMANDS_INFO_SOURCES
${CMAKE_SOURCE_DIR}/src/stream_commands/commands.cpp
${CMAKE_SOURCE_DIR}/src/stream_commands/commands_factory.cpp
${CMAKE_SOURCE_DIR}/src/stream_commands/commands_info/stop_info.cpp
${CMAKE_SOURCE_DIR}/src/stream_commands/commands_info/restart_info.cpp
${CMAKE_SOURCE_DIR}/src/stream_commands/commands_info/changed_sources_info.cpp
${CMAKE_SOURCE_DIR}/src/stream_commands/commands_info/statistic_info.cpp
${CMAKE_SOURCE_DIR}/src/stream_commands/commands_info/details/channel_stats_info.cpp
)
SET(LINK_GENERATOR_HEADERS
${CMAKE_SOURCE_DIR}/src/base/link_generator/ilink_generator.h
${CMAKE_SOURCE_DIR}/src/base/link_generator/pyfastostream.h
)
SET(LINK_GENERATOR_SOURCES
${CMAKE_SOURCE_DIR}/src/base/link_generator/ilink_generator.cpp
${CMAKE_SOURCE_DIR}/src/base/link_generator/pyfastostream.cpp
)
FIND_PACKAGE(Common REQUIRED)
FIND_PACKAGE(FastoTvCPP REQUIRED)
FIND_PACKAGE(JSON-C REQUIRED)
# options
IF(MACHINE_LEARNING)
FIND_PACKAGE(FastoML REQUIRED)
IF (NOT FASTOML_FOUND)
MESSAGE(SEND_ERROR "Please install ${PROJECT_COMPANYNAME} gstreamer machine learning framework.")
ENDIF(NOT FASTOML_FOUND)
ADD_DEFINITIONS(-DMACHINE_LEARNING)
SET(BASE_HEADERS ${BASE_HEADERS}
${CMAKE_SOURCE_DIR}/src/base/machine_learning/deep_learning.h
${CMAKE_SOURCE_DIR}/src/base/machine_learning/deep_learning_overlay.h
)
SET(BASE_SOURCES ${BASE_SOURCES}
${CMAKE_SOURCE_DIR}/src/base/machine_learning/deep_learning.cpp
${CMAKE_SOURCE_DIR}/src/base/machine_learning/deep_learning_overlay.cpp
)
ENDIF(MACHINE_LEARNING)
IF(AMAZON_KINESIS)
ADD_DEFINITIONS(-DAMAZON_KINESIS)
SET(BASE_HEADERS ${BASE_HEADERS}
${CMAKE_SOURCE_DIR}/src/base/amazon_kinesis/amazon_kinesis.h
)
SET(BASE_SOURCES ${BASE_SOURCES}
${CMAKE_SOURCE_DIR}/src/base/amazon_kinesis/amazon_kinesis.cpp
)
ENDIF(AMAZON_KINESIS)
IF(OS_WINDOWS)
SET(PLATFORM_HEADER)
SET(PLATFORM_SOURCES)
SET(PLATFORM_LIBRARIES)
ELSEIF(OS_LINUX)
SET(PLATFORM_HEADER)
SET(PLATFORM_SOURCES)
SET(PLATFORM_LIBRARIES)
ELSEIF(OS_POSIX)
SET(PLATFORM_HEADER)
SET(PLATFORM_SOURCES)
SET(PLATFORM_LIBRARIES)
ENDIF(OS_WINDOWS)
IF(USE_PTHREAD)
IF(NOT OS_ANDROID)
SET(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} pthread)
ENDIF(NOT OS_ANDROID)
ENDIF(USE_PTHREAD)
ADD_SUBDIRECTORY(utils)
# common iptv lib
SET(STREAMER_COMMON_SOURCES
${STREAM_COMMANDS_INFO_HEADERS} ${STREAM_COMMANDS_INFO_SOURCES}
${BASE_HEADERS} ${BASE_SOURCES}
${LINK_GENERATOR_HEADERS} ${LINK_GENERATOR_SOURCES}
)
SET(STREAMER_COMMON_LIBRARIES
${STREAMER_COMMON_LIBRARIES}
${JSONC_LIBRARIES} utils
${COMMON_BASE_LIBRARY}
${FASTOTV_CPP_LIBRARIES}
${ZLIB_LIBRARIES}
)
SET(PRIVATE_INCLUDE_DIRECTORIES_COMMON
${PRIVATE_INCLUDE_DIRECTORIES_COMMON}
${CMAKE_SOURCE_DIR}/src
${FASTOTV_CPP_INCLUDE_DIRS}
${COMMON_INCLUDE_DIRS}
)
ADD_LIBRARY(${STREAMER_COMMON} STATIC ${STREAMER_COMMON_SOURCES})
TARGET_INCLUDE_DIRECTORIES(${STREAMER_COMMON} PRIVATE ${PRIVATE_INCLUDE_DIRECTORIES_COMMON})
TARGET_LINK_LIBRARIES(${STREAMER_COMMON} ${STREAMER_COMMON_LIBRARIES})
SET(STREAMER_CORE ${STREAMER_NAME}_core)
IF(BUILD_SERVER)
ADD_SUBDIRECTORY(server)
ENDIF(BUILD_SERVER)
IF(BUILD_STREAM)
ADD_SUBDIRECTORY(stream)
ENDIF(BUILD_STREAM)
INSTALL(FILES ${CMAKE_SOURCE_DIR}/LICENSE DESTINATION . COMPONENT LICENSE RENAME LICENSE OPTIONAL)
INSTALL(FILES ${CMAKE_SOURCE_DIR}/COPYRIGHT DESTINATION . COMPONENT LICENSE RENAME COPYRIGHT OPTIONAL)
INSTALL(FILES ${PROJECT_CHANGELOG_FILE} DESTINATION . COMPONENT LICENSE RENAME CHANGELOG OPTIONAL)
IF (DEVELOPER_CHECK_STYLE)
SET(CHECK_SOURCES ${STREAMER_COMMON_SOURCES})
REGISTER_CHECK_STYLE_TARGET(check_style_${STREAMER_COMMON} "${CHECK_SOURCES}")
REGISTER_CHECK_INCLUDES_TARGET(${STREAMER_COMMON})
ENDIF(DEVELOPER_CHECK_STYLE)
IF(DEVELOPER_ENABLE_TESTS)
FIND_PACKAGE(GTest REQUIRED)
## Unit tests
SET(PRIVATE_INCLUDE_DIRECTORIES_UNIT_TESTS
${PRIVATE_INCLUDE_DIRECTORIES_UNIT_TESTS}
${CMAKE_SOURCE_DIR}/src
)
SET(UNIT_TESTS_LIBS
${GTEST_BOTH_LIBRARIES}
${STREAMER_COMMON}
${PLATFORM_LIBRARIES})
SET(UNIT_TESTS unit_tests)
ADD_EXECUTABLE(${UNIT_TESTS}
${CMAKE_SOURCE_DIR}/tests/unit_test_output_uri.cpp
${CMAKE_SOURCE_DIR}/tests/unit_test_input_uri.cpp
${CMAKE_SOURCE_DIR}/tests/unit_test_types.cpp
)
TARGET_INCLUDE_DIRECTORIES(${UNIT_TESTS} PRIVATE ${PRIVATE_INCLUDE_DIRECTORIES_UNIT_TESTS} ${JSONC_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(${UNIT_TESTS} ${UNIT_TESTS_LIBS})
ADD_TEST_TARGET(${UNIT_TESTS})
SET_PROPERTY(TARGET ${UNIT_TESTS} PROPERTY FOLDER "Unit tests")
ENDIF(DEVELOPER_ENABLE_TESTS)

View file

@ -0,0 +1,99 @@
/* Copyright (C) 2014-2019 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/amazon_kinesis/amazon_kinesis.h"
#include <json-c/json_object.h>
#include <json-c/json_tokener.h>
#include <json-c/linkhash.h>
#define AMAZON_KINESIS_STREAM_NAME_FIELD "stream_name"
#define AMAZON_KINESIS_SECRET_KEY_FIELD "secret_key"
#define AMAZON_KINESIS_ACCESS_KEY_FIELD "access_key"
namespace fastocloud {
namespace amazon_kinesis {
AmazonKinesis::AmazonKinesis() : AmazonKinesis(std::string(), std::string(), std::string()) {}
AmazonKinesis::AmazonKinesis(const std::string& stream_name,
const std::string& secret_key,
const std::string& access_key)
: stream_name_(stream_name), secret_key_(secret_key), access_key_(access_key) {}
bool AmazonKinesis::Equals(const AmazonKinesis& aws) const {
return aws.stream_name_ == stream_name_ && aws.secret_key_ == secret_key_ && aws.access_key_ == access_key_;
}
common::Optional<AmazonKinesis> AmazonKinesis::MakeAmazonKinesis(common::HashValue* hash) {
if (!hash) {
return common::Optional<AmazonKinesis>();
}
AmazonKinesis res;
common::Value* stream_name_field = hash->Find(AMAZON_KINESIS_STREAM_NAME_FIELD);
std::string stream_name;
if (stream_name_field && stream_name_field->GetAsBasicString(&stream_name)) {
res.stream_name_ = stream_name;
}
common::Value* secret_key_field = hash->Find(AMAZON_KINESIS_SECRET_KEY_FIELD);
std::string secret_key;
if (secret_key_field && secret_key_field->GetAsBasicString(&secret_key)) {
res.secret_key_ = secret_key;
}
common::Value* access_key_field = hash->Find(AMAZON_KINESIS_ACCESS_KEY_FIELD);
std::string access_key;
if (access_key_field && access_key_field->GetAsBasicString(&access_key)) {
res.access_key_ = access_key;
}
return res;
}
common::Error AmazonKinesis::DoDeSerialize(json_object* serialized) {
AmazonKinesis res;
json_object* jstream_name = nullptr;
json_bool jstream_name_exists =
json_object_object_get_ex(serialized, AMAZON_KINESIS_STREAM_NAME_FIELD, &jstream_name);
if (jstream_name_exists) {
res.stream_name_ = json_object_get_string(jstream_name);
}
json_object* jsecret_key = nullptr;
json_bool jsecret_key_exists = json_object_object_get_ex(serialized, AMAZON_KINESIS_SECRET_KEY_FIELD, &jsecret_key);
if (jsecret_key_exists) {
res.secret_key_ = json_object_get_string(jsecret_key);
}
json_object* jaccess_key = nullptr;
json_bool jaccess_key_exists = json_object_object_get_ex(serialized, AMAZON_KINESIS_ACCESS_KEY_FIELD, &jaccess_key);
if (jaccess_key_exists) {
res.access_key_ = json_object_get_string(jaccess_key);
}
*this = res;
return common::Error();
}
common::Error AmazonKinesis::SerializeFields(json_object* out) const {
json_object_object_add(out, AMAZON_KINESIS_STREAM_NAME_FIELD, json_object_new_string(stream_name_.c_str()));
json_object_object_add(out, AMAZON_KINESIS_SECRET_KEY_FIELD, json_object_new_string(secret_key_.c_str()));
json_object_object_add(out, AMAZON_KINESIS_ACCESS_KEY_FIELD, json_object_new_string(access_key_.c_str()));
return common::Error();
}
} // namespace amazon_kinesis
} // namespace fastocloud

View file

@ -0,0 +1,45 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <string>
#include <common/serializer/json_serializer.h>
#include <common/value.h>
namespace fastocloud {
namespace amazon_kinesis {
class AmazonKinesis : public common::serializer::JsonSerializer<AmazonKinesis> {
public:
AmazonKinesis();
AmazonKinesis(const std::string& stream_name, const std::string& secret_key, const std::string& access_key);
bool Equals(const AmazonKinesis& aws) const;
static common::Optional<AmazonKinesis> MakeAmazonKinesis(common::HashValue* hash);
protected:
common::Error DoDeSerialize(json_object* serialized) override;
common::Error SerializeFields(json_object* out) const override;
private:
std::string stream_name_;
std::string secret_key_;
std::string access_key_;
};
} // namespace amazon_kinesis
} // namespace fastocloud

View file

@ -0,0 +1,92 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/channel_stats.h"
#include <common/time.h>
namespace fastocloud {
ChannelStats::ChannelStats() : ChannelStats(0) {}
ChannelStats::ChannelStats(fastotv::channel_id_t cid)
: id_(cid),
last_update_time_(0),
total_bytes_(0),
prev_total_bytes_(0),
bytes_per_second_(0),
desire_bytes_per_second_() {}
fastotv::channel_id_t ChannelStats::GetID() const {
return id_;
}
fastotv::timestamp_t ChannelStats::GetLastUpdateTime() const {
return last_update_time_;
}
void ChannelStats::SetLastUpdateTime(fastotv::timestamp_t t) {
last_update_time_ = t;
}
size_t ChannelStats::GetTotalBytes() const {
return total_bytes_;
}
size_t ChannelStats::GetPrevTotalBytes() const {
return prev_total_bytes_;
}
void ChannelStats::SetPrevTotalBytes(size_t bytes) {
prev_total_bytes_ = bytes;
}
size_t ChannelStats::GetDiffTotalBytes() const {
return total_bytes_ - prev_total_bytes_;
}
void ChannelStats::UpdateBps(size_t sec) {
if (!sec) {
return;
}
bytes_per_second_ = GetDiffTotalBytes() / sec;
}
size_t ChannelStats::GetBps() const {
return bytes_per_second_;
}
void ChannelStats::SetBps(size_t bps) {
bytes_per_second_ = bps;
}
void ChannelStats::UpdateCheckPoint() {
prev_total_bytes_ = total_bytes_;
}
void ChannelStats::SetTotalBytes(size_t bytes) {
total_bytes_ = bytes;
last_update_time_ = common::time::current_utc_mstime();
}
void ChannelStats::SetDesireBytesPerSecond(const common::media::DesireBytesPerSec& bps) {
desire_bytes_per_second_ = bps;
}
common::media::DesireBytesPerSec ChannelStats::GetDesireBytesPerSecond() const {
return desire_bytes_per_second_;
}
} // namespace fastocloud

61
src/base/channel_stats.h Normal file
View file

@ -0,0 +1,61 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <common/media/bandwidth_estimation.h>
#include <fastotv/types.h>
namespace fastocloud {
class ChannelStats { // only compile time size fields
public:
ChannelStats();
explicit ChannelStats(fastotv::channel_id_t cid);
fastotv::channel_id_t GetID() const;
fastotv::timestamp_t GetLastUpdateTime() const;
void SetLastUpdateTime(fastotv::timestamp_t t);
size_t GetTotalBytes() const;
void SetTotalBytes(size_t bytes);
size_t GetPrevTotalBytes() const;
void SetPrevTotalBytes(size_t bytes);
size_t GetDiffTotalBytes() const;
void UpdateBps(size_t sec);
size_t GetBps() const;
void SetBps(size_t bps);
void UpdateCheckPoint();
void SetDesireBytesPerSecond(const common::media::DesireBytesPerSec& bps);
common::media::DesireBytesPerSec GetDesireBytesPerSecond() const;
private:
fastotv::channel_id_t id_;
fastotv::timestamp_t last_update_time_; // up_time
size_t total_bytes_; // received bytes
size_t prev_total_bytes_; // checkpoint received bytes
size_t bytes_per_second_; // bps
common::media::DesireBytesPerSec desire_bytes_per_second_;
};
} // namespace fastocloud

View file

@ -0,0 +1,15 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/config_fields.h"

65
src/base/config_fields.h Normal file
View file

@ -0,0 +1,65 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#define FEEDBACK_DIR_FIELD "feedback_directory" // required
#define DATA_DIR_FIELD "data_directory"
#define LOG_LEVEL_FIELD "log_level"
#define ID_FIELD "id" // required
#define TYPE_FIELD "type" // required
#define PYFASTOSTREAM_PATH_FIELD "pyfastostream_path"
#define AUTO_EXIT_TIME_FIELD "auto_exit_time"
#define INPUT_FIELD "input" // required
#define OUTPUT_FIELD "output"
#define HAVE_VIDEO_FIELD "have_video"
#define HAVE_AUDIO_FIELD "have_audio"
#define HAVE_SUBTITLE_FIELD "have_subtitle"
#define DEINTERLACE_FIELD "deinterlace"
#define FRAME_RATE_FIELD "frame_rate"
#define AUDIO_CHANNELS_FIELD "audio_channels"
#define VOLUME_FIELD "volume"
#define VIDEO_PARSER_FIELD "video_parser"
#define AUDIO_PARSER_FIELD "audio_parser"
#define VIDEO_CODEC_FIELD "video_codec"
#define AUDIO_CODEC_FIELD "audio_codec"
#define AUDIO_SELECT_FIELD "audio_select"
#define TIMESHIFT_DIR_FIELD "timeshift_dir" // requeired in timeshift mode
#define TIMESHIFT_CHUNK_LIFE_TIME_FIELD "timeshift_chunk_life_time"
#define TIMESHIFT_DELAY_FIELD "timeshift_delay"
#define TIMESHIFT_CHUNK_DURATION_FIELD "timeshift_chunk_duration"
#define CLEANUP_TS_FIELD "cleanup_ts"
#define LOGO_FIELD "logo"
#define RSVG_LOGO_FIELD "rsvg_logo"
#define LOOP_FIELD "loop"
#define RESTART_ATTEMPTS_FIELD "restart_attempts"
#define DELAY_TIME_FIELD "delay_time"
#define SIZE_FIELD "size"
#define VIDEO_BIT_RATE_FIELD "video_bitrate"
#define AUDIO_BIT_RATE_FIELD "audio_bitrate"
#define ASPECT_RATIO_FIELD "aspect_ratio"
#define RELAY_AUDIO_FIELD "relay_audio"
#define RELAY_VIDEO_FIELD "relay_video"
#define DECKLINK_VIDEO_MODE_FIELD "decklink_video_mode"
#if defined(MACHINE_LEARNING)
#define DEEP_LEARNING_FIELD "deep_learning"
#define DEEP_LEARNING_OVERLAY_FIELD "deep_learning_overlay"
#endif
#if defined(AMAZON_KINESIS)
#define AMAZON_KINESIS_FIELD "amazon_kinesis"
#endif

15
src/base/constants.cpp Normal file
View file

@ -0,0 +1,15 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/constants.h"

33
src/base/constants.h Normal file
View file

@ -0,0 +1,33 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <signal.h>
#define DEFAULT_VOLUME 1.0
#define DEFAULT_DECKLINK_VIDEO_MODE 1
#define DEFAULT_TIMESHIFT_CHUNK_DURATION 120
#define DEFAULT_CHUNK_LIFE_TIME 12 * 3600
#define DEFAULT_LOOP false
#define TEST_URL "test"
#define DISPLAY_URL "display"
#define FAKE_URL "fake"
#define LOGS_FILE_NAME "logs"
#define KILL_STREAM_SIGNAL SIGTERM

View file

@ -0,0 +1,27 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/gst_constants.h"
const std::array<const char*, SUPPORTED_VIDEO_PARSERS_COUNT> kSupportedVideoParsers = {
{TS_PARSE, H264_PARSE, H265_PARSE}};
const std::array<const char*, SUPPORTED_AUDIO_PARSERS_COUNT> kSupportedAudioParsers = {
{MPEG_AUDIO_PARSE, AAC_PARSE, AC3_PARSE, RAW_AUDIO_PARSE}};
const std::array<const char*, SUPPORTED_VIDEO_ENCODERS_COUNT> kSupportedVideoEncoders = {
{EAVC_ENC, OPEN_H264_ENC, X264_ENC, NV_H264_ENC, NV_H265_ENC, VAAPI_H264_ENC, VAAPI_MPEG2_ENC, MFX_H264_ENC,
X265_ENC, MSDK_H264_ENC}};
const std::array<const char*, SUPPORTED_AUDIO_ENCODERS_COUNT> kSupportedAudioEncoders = {
{LAME_MP3_ENC, FAAC, VOAAC_ENC}};

157
src/base/gst_constants.h Normal file
View file

@ -0,0 +1,157 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <array>
#define DECODEBIN "decodebin"
#define FAKE_SINK "fakesink"
#define TEST_SINK "testsink"
#define VIDEO_TEST_SRC "videotestsrc"
#define AUDIO_TEST_SRC "audiotestsrc"
#define DISPLAY_SRC "ximagesrc"
#define VIDEO_SCREEN_SINK "autovideosink"
#define AUDIO_SCREEN_SINK "autoaudiosink"
#define QUEUE "queue"
#define QUEUE2 "queue2"
#define H264_PARSE "h264parse"
#define H265_PARSE "h265parse"
#define MPEG_VIDEO_PARSE "mpegvideoparse"
#define AAC_PARSE "aacparse"
#define AC3_PARSE "ac3parse"
#define MPEG_AUDIO_PARSE "mpegaudioparse"
#define RAW_AUDIO_PARSE "rawaudioparse"
#define TEE "tee"
#define MP4_MUX "mp4mux"
#define QT_MUX "qtmux"
#define FLV_MUX "flvmux"
#define MPEGTS_MUX "mpegtsmux"
#define FILE_SINK "filesink"
#define RTP_MUX "rtpmux"
#define RTP_MPEG2_PAY "rtpmp2tpay"
#define RTP_H264_PAY "rtph264pay"
#define RTP_H265_PAY "rtph265pay"
#define RTP_AAC_PAY "rtpmp4apay"
#define RTP_AC3_PAY "rtpac3pay"
#define RTP_MPEG2_DEPAY "rtpmp2tdepay"
#define RTP_H264_DEPAY "rtph264depay"
#define RTP_H265_DEPAY "rtph265depay"
#define RTP_AAC_DEPAY "rtpmp4adepay"
#define RTP_AC3_DEPAY "rtpac3depay"
#define V4L2_SRC "v4l2src"
#define SPLIT_MUX_SINK "splitmuxsink"
#define ALSA_SRC "alsasrc"
#define MULTIFILE_SRC "multifilesrc"
#define APP_SRC "appsrc"
#define FILE_SRC "filesrc"
#define IMAGE_FREEZE "imagefreeze"
#define CAPS_FILTER "capsfilter"
#define AUDIO_CONVERT "audioconvert"
#define RG_VOLUME "rgvolume"
#define VOLUME "volume"
#define FAAC "faac"
#define VOAAC_ENC "voaacenc"
#define AUDIO_RESAMPLE "audioresample"
#define LAME_MP3_ENC "lamemp3enc"
#define VIDEO_CONVERT "videoconvert"
#define AV_DEINTERLACE "avdeinterlace"
#define DEINTERLACE "deinterlace"
#define ASPECT_RATIO "aspectratiocrop"
#define UDP_SINK "udpsink"
#define TCP_SERVER_SINK "tcpserversink"
#define RTMP_SINK "rtmpsink"
#define HLS_SINK "hlssink"
#define SOUP_HTTP_SRC "souphttpsrc"
#define DVB_SRC "dvbsrc"
#define VIDEO_SCALE "videoscale"
#define VIDEO_RATE "videorate"
#define MULTIFILE_SINK "multifilesink"
#define KVS_SINK "kvssink"
#define NV_H264_ENC "nvh264enc"
#define NV_H265_ENC "nvh265enc"
#define MSDK_H264_ENC "msdkh264enc"
#define X264_ENC "x264enc"
#define X265_ENC "x265enc"
#define MPEG2_ENC "mpeg2enc"
#define EAVC_ENC "eavcenc"
#define OPEN_H264_ENC "openh264enc"
#define UDP_SRC "udpsrc"
#define RTMP_SRC "rtmpsrc"
#define RTSP_SRC "rtspsrc"
#define TCP_SERVER_SRC "tcpserversrc"
#define VAAPI_H264_ENC "vaapih264enc"
#define VAAPI_MPEG2_ENC "vaapimpeg2enc"
#define VAAPI_DECODEBIN "vaapidecodebin"
#define VAAPI_POST_PROC "vaapipostproc"
#define GDK_PIXBUF_OVERLAY "gdkpixbufoverlay"
#define RSVG_OVERLAY "rsvgoverlay"
#define VIDEO_BOX "videobox"
#define VIDEO_MIXER "videomixer"
#define AUDIO_MIXER "audiomixer"
#define INTERLEAVE "interleave"
#define DEINTERLEAVE "deinterleave"
#define TEXT_OVERLAY "textoverlay"
#define VIDEO_CROP "videocrop"
#define SPECTRUM "spectrum"
#define LEVEL "level"
#define HLS_DEMUX "hlsdemux"
#define VIDEO_DECK_SINK "decklinkvideosink"
#define AUDIO_DECK_SINK "decklinkaudiosink"
#define INTERLACE "interlace"
#define AUTO_VIDEO_CONVERT "autovideoconvert"
#define TS_PARSE "tsparse"
#define AVDEC_H264 "avdec_h264"
#define TS_DEMUX "tsdemux"
#define AVDEC_AC3 "avdec_ac3"
#define AVDEC_AC3_FIXED "avdec_ac3_fixed"
#define AVDEC_AAC "avdec_aac"
#define AVDEC_AAC_FIXED "avdec_aac_fixed"
#define SOUP_HTTP_CLIENT_SINK "souphttpclientsink"
#define MFX_H264_ENC "mfxh264enc"
#define MFX_VPP "mfxvpp"
#define MFX_H264_DEC "mfxh264dec"
#define SRT_SRC "srtsrc"
#define SRT_SINK "srtsink"
// deep learning
#define TINY_YOLOV2 "tinyyolov2"
#define TINY_YOLOV3 "tinyyolov3"
#define DETECTION_OVERLAY "detectionoverlay"
#define SUPPORTED_VIDEO_PARSERS_COUNT 3
#define SUPPORTED_AUDIO_PARSERS_COUNT 4
extern const std::array<const char*, SUPPORTED_VIDEO_PARSERS_COUNT> kSupportedVideoParsers;
extern const std::array<const char*, SUPPORTED_AUDIO_PARSERS_COUNT> kSupportedAudioParsers;
#define SUPPORTED_VIDEO_ENCODERS_COUNT 10
#define SUPPORTED_AUDIO_ENCODERS_COUNT 3
extern const std::array<const char*, SUPPORTED_VIDEO_ENCODERS_COUNT> kSupportedVideoEncoders;
extern const std::array<const char*, SUPPORTED_AUDIO_ENCODERS_COUNT> kSupportedAudioEncoders;

View file

@ -0,0 +1,23 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/link_generator/ilink_generator.h"
namespace fastocloud {
namespace link_generator {
ILinkGenerator::~ILinkGenerator() {}
} // namespace link_generator
} // namespace fastocloud

View file

@ -0,0 +1,29 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <fastotv/types/input_uri.h>
namespace fastocloud {
namespace link_generator {
class ILinkGenerator {
public:
virtual bool Generate(const fastotv::InputUri& src, fastotv::InputUri* out) const WARN_UNUSED_RESULT = 0;
virtual ~ILinkGenerator();
};
} // namespace link_generator
} // namespace fastocloud

View file

@ -0,0 +1,126 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/link_generator/pyfastostream.h"
#include <string>
#include <common/sprintf.h>
#include "base/platform_macros.h"
#include "base/utils.h"
namespace {
static const char* kStreams[9] = {"best", "1080p60", "720p60", "720p", "480p", "360p", "240p", "144p", "worst"};
bool GetTrueUrl(const std::string& path,
const common::uri::GURL& url,
const fastotv::PyFastoStream& link,
common::uri::GURL* generated_url,
size_t rec = 0) {
if (rec >= SIZEOFMASS(kStreams)) {
return false;
}
if (!generated_url) {
return false;
}
std::string cmd_line = path + " --url";
const auto http = link.GetHttp();
if (http) {
cmd_line += " --http-proxy=" + http->spec();
}
const auto https = link.GetHttps();
if (https) {
cmd_line += " --https-proxy=" + https->spec();
}
std::string raw_url = url.spec();
common::Optional<std::string> audio_master;
if (url.SchemeIsFile() && url.has_query()) {
audio_master = fastocloud::GetAudioMasterUrlFromQuery(url.query());
if (audio_master) {
raw_url = *audio_master;
}
}
cmd_line += common::MemSPrintf(" \'%s\' --quality %s --prefer %d", raw_url, kStreams[rec], link.GetPrefer());
FILE* fp = popen(cmd_line.c_str(), "r");
if (!fp) {
return false;
}
char true_url[1024] = {0};
char* res = fgets(true_url, sizeof(true_url) - 1, fp);
int closed = pclose(fp);
if (WIFEXITED(closed)) {
if (WEXITSTATUS(closed) == EXIT_FAILURE) {
return GetTrueUrl(path, url, link, generated_url, ++rec);
}
}
if (!res) {
return false;
}
size_t ln = strlen(true_url) - 1;
if (true_url[ln] == '\n') {
true_url[ln] = 0;
}
if (audio_master) {
*generated_url = common::uri::GURL("file://" + url.path() + "?audio=" + true_url);
return true;
}
*generated_url = common::uri::GURL(true_url);
return true;
}
} // namespace
namespace fastocloud {
namespace link_generator {
PyFastoPyFastoStreamGenerator::PyFastoPyFastoStreamGenerator(
const common::file_system::ascii_file_string_path& script_path)
: script_path_(script_path) {}
bool PyFastoPyFastoStreamGenerator::Generate(const fastotv::InputUri& src, fastotv::InputUri* out) const {
if (!out) {
return false;
}
const auto str = src.GetPyFastoStream();
if (!str) {
return false;
}
if (!script_path_.IsValid()) {
return false;
}
common::uri::GURL gen;
if (!GetTrueUrl(script_path_.GetPath(), src.GetUrl(), *str, &gen)) {
return false;
}
*out = src;
out->SetUrl(gen);
return true;
}
} // namespace link_generator
} // namespace fastocloud

View file

@ -0,0 +1,36 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <common/file_system/path.h>
#include "base/link_generator/ilink_generator.h"
namespace fastocloud {
namespace link_generator {
class PyFastoPyFastoStreamGenerator : public ILinkGenerator {
public:
typedef common::Optional<common::uri::GURL> http_proxy_t;
explicit PyFastoPyFastoStreamGenerator(const common::file_system::ascii_file_string_path& script_path);
bool Generate(const fastotv::InputUri& src, fastotv::InputUri* out) const override WARN_UNUSED_RESULT;
private:
const common::file_system::ascii_file_string_path script_path_;
};
} // namespace link_generator
} // namespace fastocloud

View file

@ -0,0 +1,158 @@
/* Copyright (C) 2014-2019 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/machine_learning/deep_learning.h"
#include <json-c/json_object.h>
#include <json-c/json_tokener.h>
#include <json-c/linkhash.h>
#include <common/sprintf.h>
#define DEEP_LEARNING_BACKEND_FIELD "backend"
#define DEEP_LEARNING_MODEL_PATH_FIELD "model_path"
#define DEEP_LEARNING_PROPERTIES_FIELD "properties"
namespace fastocloud {
namespace machine_learning {
DeepLearning::DeepLearning() : backend_(fastoml::TENSORFLOW), model_path_(), properties_() {}
DeepLearning::DeepLearning(fastoml::SupportedBackends backend, const file_path_t& model_path, const properties_t& prop)
: backend_(backend), model_path_(model_path), properties_(prop) {}
DeepLearning::file_path_t DeepLearning::GetModelPath() const {
return model_path_;
}
void DeepLearning::SetModelPath(const file_path_t& path) {
model_path_ = path;
}
DeepLearning::properties_t DeepLearning::GetProperties() const {
return properties_;
}
void DeepLearning::SetProperties(const properties_t& prop) {
properties_ = prop;
}
fastoml::SupportedBackends DeepLearning::GetBackend() const {
return backend_;
}
void DeepLearning::SetBackend(fastoml::SupportedBackends backend) {
backend_ = backend;
}
bool DeepLearning::Equals(const DeepLearning& learn) const {
return learn.backend_ == backend_ && learn.model_path_ == model_path_;
}
common::Optional<DeepLearning> DeepLearning::MakeDeepLearning(common::HashValue* hash) {
if (!hash) {
return common::Optional<DeepLearning>();
}
DeepLearning res;
common::Value* learning_backend_field = hash->Find(DEEP_LEARNING_BACKEND_FIELD);
int backend;
if (!learning_backend_field || !learning_backend_field->GetAsInteger(&backend)) {
return common::Optional<DeepLearning>();
}
res.SetBackend(static_cast<fastoml::SupportedBackends>(backend));
std::string model_path_str;
common::Value* model_path_field = hash->Find(DEEP_LEARNING_MODEL_PATH_FIELD);
if (!model_path_field || !model_path_field->GetAsBasicString(&model_path_str)) {
return common::Optional<DeepLearning>();
}
res.SetModelPath(file_path_t(model_path_str));
common::Value* properties_field = hash->Find(DEEP_LEARNING_PROPERTIES_FIELD);
common::ArrayValue* arr = nullptr;
if (properties_field && properties_field->GetAsList(&arr)) {
properties_t properties;
for (size_t i = 0; i < arr->GetSize(); ++i) {
common::Value* prop = nullptr;
if (arr->Get(i, &prop)) {
common::HashValue* hprop = nullptr;
if (prop->GetAsHash(&hprop)) {
for (auto it = hprop->begin(); it != hprop->end(); ++it) {
std::string value_str;
if (it->second->GetAsBasicString(&value_str)) {
BackendProperty pr = {it->first.as_string(), value_str};
properties.push_back(pr);
}
}
}
}
}
res.SetProperties(properties);
}
return res;
}
common::Error DeepLearning::DoDeSerialize(json_object* serialized) {
DeepLearning res;
json_object* jbackend = nullptr;
json_bool jbackend_exists = json_object_object_get_ex(serialized, DEEP_LEARNING_BACKEND_FIELD, &jbackend);
if (!jbackend_exists) {
return common::make_error_inval();
}
res.SetBackend(static_cast<fastoml::SupportedBackends>(json_object_get_int(jbackend)));
json_object* jmodel_path = nullptr;
json_bool jmodel_path_exists = json_object_object_get_ex(serialized, DEEP_LEARNING_MODEL_PATH_FIELD, &jmodel_path);
if (!jmodel_path_exists) {
return common::make_error_inval();
}
res.SetModelPath(file_path_t(json_object_get_string(jmodel_path)));
json_object* jproperties = nullptr;
json_bool jproperties_exists = json_object_object_get_ex(serialized, DEEP_LEARNING_PROPERTIES_FIELD, &jproperties);
if (jproperties_exists) {
properties_t properties;
size_t len = json_object_array_length(jproperties);
// [{"input_layer" : "1234"}, {"output_layer" : "321"}]
for (size_t i = 0; i < len; ++i) {
json_object* jproperty = json_object_array_get_idx(jproperties, i);
json_object_object_foreach(jproperty, key, val) { properties.push_back({key, json_object_get_string(val)}); }
}
res.SetProperties(properties);
}
*this = res;
return common::Error();
}
common::Error DeepLearning::SerializeFields(json_object* out) const {
json_object_object_add(out, DEEP_LEARNING_BACKEND_FIELD, json_object_new_int64(backend_));
const std::string model_path_str = model_path_.GetPath();
json_object_object_add(out, DEEP_LEARNING_MODEL_PATH_FIELD, json_object_new_string(model_path_str.c_str()));
json_object* jproperties = json_object_new_array();
for (size_t i = 0; i < properties_.size(); ++i) {
json_object* jproperty = json_object_new_object();
json_object_object_add(jproperty, properties_[i].property.c_str(),
json_object_new_string(properties_[i].value.c_str()));
json_object_array_add(jproperties, jproperty);
}
json_object_object_add(out, DEEP_LEARNING_PROPERTIES_FIELD, jproperties);
return common::Error();
}
} // namespace machine_learning
} // namespace fastocloud

View file

@ -0,0 +1,68 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <string>
#include <vector>
#include <common/file_system/path.h>
#include <common/serializer/json_serializer.h>
#include <common/value.h>
#include <fastoml/types.h>
namespace fastocloud {
namespace machine_learning {
struct BackendProperty {
std::string property;
std::string value;
};
class DeepLearning : public common::serializer::JsonSerializer<DeepLearning> {
public:
typedef common::file_system::ascii_file_string_path file_path_t;
typedef std::vector<BackendProperty> properties_t;
DeepLearning();
DeepLearning(fastoml::SupportedBackends backend,
const file_path_t& model_path,
const properties_t& prop = properties_t());
bool Equals(const DeepLearning& learn) const;
properties_t GetProperties() const;
void SetProperties(const properties_t& prop);
fastoml::SupportedBackends GetBackend() const;
void SetBackend(fastoml::SupportedBackends backend);
file_path_t GetModelPath() const;
void SetModelPath(const file_path_t& path);
static common::Optional<DeepLearning> MakeDeepLearning(common::HashValue* hash);
protected:
common::Error DoDeSerialize(json_object* serialized) override;
common::Error SerializeFields(json_object* out) const override;
private:
fastoml::SupportedBackends backend_;
file_path_t model_path_;
properties_t properties_;
};
} // namespace machine_learning
} // namespace fastocloud

View file

@ -0,0 +1,78 @@
/* Copyright (C) 2014-2019 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/machine_learning/deep_learning_overlay.h"
#include <json-c/json_object.h>
#include <json-c/json_tokener.h>
#include <common/sprintf.h>
#define DEEP_LEARNING_LABELS_PATH_FIELD "labels_path"
namespace fastocloud {
namespace machine_learning {
DeepLearningOverlay::DeepLearningOverlay() : labels_path_() {}
DeepLearningOverlay::DeepLearningOverlay(const file_path_t& labels_path) : labels_path_(labels_path) {}
DeepLearningOverlay::file_path_t DeepLearningOverlay::GetLabelsPath() const {
return labels_path_;
}
void DeepLearningOverlay::SetLabelsPath(const file_path_t& path) {
labels_path_ = path;
}
bool DeepLearningOverlay::Equals(const DeepLearningOverlay& learn) const {
return learn.labels_path_ == labels_path_;
}
common::Optional<DeepLearningOverlay> DeepLearningOverlay::MakeDeepLearningOverlay(common::HashValue* hash) {
if (!hash) {
return common::Optional<DeepLearningOverlay>();
}
DeepLearningOverlay res;
common::Value* paths_field = hash->Find(DEEP_LEARNING_LABELS_PATH_FIELD);
std::string paths;
if (!paths_field || !paths_field->GetAsBasicString(&paths)) {
return common::Optional<DeepLearningOverlay>();
}
res.SetLabelsPath(file_path_t(paths));
return res;
}
common::Error DeepLearningOverlay::DoDeSerialize(json_object* serialized) {
DeepLearningOverlay res;
json_object* jlabels_path = nullptr;
json_bool jlabels_path_exists = json_object_object_get_ex(serialized, DEEP_LEARNING_LABELS_PATH_FIELD, &jlabels_path);
if (!jlabels_path_exists) {
return common::make_error_inval();
}
res.SetLabelsPath(file_path_t(json_object_get_string(jlabels_path)));
*this = res;
return common::Error();
}
common::Error DeepLearningOverlay::SerializeFields(json_object* out) const {
const std::string labels_path_str = labels_path_.GetPath();
json_object_object_add(out, DEEP_LEARNING_LABELS_PATH_FIELD, json_object_new_string(labels_path_str.c_str()));
return common::Error();
}
} // namespace machine_learning
} // namespace fastocloud

View file

@ -0,0 +1,52 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <string>
#include <vector>
#include <common/file_system/path.h>
#include <common/serializer/json_serializer.h>
#include <common/value.h>
#include <fastoml/types.h>
namespace fastocloud {
namespace machine_learning {
class DeepLearningOverlay : public common::serializer::JsonSerializer<DeepLearningOverlay> {
public:
typedef common::file_system::ascii_file_string_path file_path_t;
DeepLearningOverlay();
explicit DeepLearningOverlay(const file_path_t& labels_path);
bool Equals(const DeepLearningOverlay& learn) const;
file_path_t GetLabelsPath() const;
void SetLabelsPath(const file_path_t& path);
static common::Optional<DeepLearningOverlay> MakeDeepLearningOverlay(common::HashValue* hash);
protected:
common::Error DoDeSerialize(json_object* serialized) override;
common::Error SerializeFields(json_object* out) const override;
private:
file_path_t labels_path_;
};
} // namespace machine_learning
} // namespace fastocloud

View file

@ -0,0 +1,27 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#if defined(OS_WIN)
#ifndef WIFEXITED
#define WIFEXITED(S) (((S)&0xff) == 0)
#endif
#ifndef WEXITSTATUS
#define WEXITSTATUS(S) (((S)&0xff00) >> 8)
#endif
#endif

370
src/base/stream_config.cpp Normal file
View file

@ -0,0 +1,370 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/stream_config.h"
#include <string>
#include "base/config_fields.h"
#include "base/utils.h"
#include <json-c/json_object.h>
#include <json-c/json_tokener.h>
#include <common/convert2string.h>
#include <common/file_system/file_system.h>
namespace fastocloud {
namespace {
bool ConvertFromString(common::ArrayValue* output_urls, fastocloud::output_t* out) {
if (!output_urls || !out) {
return false;
}
fastocloud::output_t output;
for (size_t i = 0; i < output_urls->GetSize(); ++i) {
common::Value* url = nullptr;
common::HashValue* url_hash = nullptr;
if (output_urls->Get(i, &url) && url->GetAsHash(&url_hash)) {
const auto murl = fastotv::OutputUri::Make(url_hash);
if (murl) {
output.push_back(*murl);
}
}
}
*out = output;
return true;
}
bool ConvertFromString(common::ArrayValue* input_urls, fastocloud::input_t* out) {
if (!input_urls || !out) {
return false;
}
fastocloud::input_t input;
for (size_t i = 0; i < input_urls->GetSize(); ++i) {
common::Value* url = nullptr;
common::HashValue* url_hash = nullptr;
if (input_urls->Get(i, &url) && url->GetAsHash(&url_hash)) {
const auto murl = fastotv::InputUri::Make(url_hash);
if (murl) {
input.push_back(*murl);
}
}
}
*out = input;
return true;
}
} // namespace
common::Optional<input_t> ReadInput(const StreamConfig& config) {
if (!config) {
return common::Optional<input_t>();
}
common::Value* input_field = config->Find(INPUT_FIELD);
common::ArrayValue* input_hash = nullptr;
if (!input_field || !input_field->GetAsList(&input_hash)) {
return common::Optional<input_t>();
}
input_t linput;
if (!ConvertFromString(input_hash, &linput)) {
return common::Optional<input_t>();
}
return common::Optional<input_t>(linput);
}
common::Optional<output_t> ReadOutput(const StreamConfig& config) {
if (!config) {
return common::Optional<output_t>();
}
common::Value* output_field = config->Find(OUTPUT_FIELD);
common::ArrayValue* output_hash = nullptr;
if (!output_field || !output_field->GetAsList(&output_hash)) {
return common::Optional<output_t>();
}
output_t loutput;
if (!ConvertFromString(output_hash, &loutput)) {
return common::Optional<output_t>();
}
return common::Optional<output_t>(loutput);
}
common::Optional<fastotv::stream_id_t> GetSid(const StreamConfig& config) {
if (!config) {
return common::Optional<fastotv::stream_id_t>();
}
common::Value* id_field = config->Find(ID_FIELD);
fastotv::stream_id_t lsid;
if (id_field && id_field->GetAsBasicString(&lsid)) {
return common::Optional<fastotv::stream_id_t>(lsid);
}
return common::Optional<fastotv::stream_id_t>();
}
common::Optional<fastotv::StreamTTL> GetTTL(const StreamConfig& config) {
if (!config) {
return common::Optional<fastotv::StreamTTL>();
}
common::HashValue* ttl_hash = nullptr;
common::Value* frame_field = config->Find(AUTO_EXIT_TIME_FIELD);
if (frame_field && frame_field->GetAsHash(&ttl_hash)) {
return fastotv::StreamTTL::Make(ttl_hash);
}
return common::Optional<fastotv::StreamTTL>();
}
common::ErrnoError MakeStreamInfo(const StreamConfig& config,
bool check_folders,
StreamInfo* sha,
std::string* feedback_dir,
std::string* data_dir,
common::logging::LOG_LEVEL* logs_level) {
if (!sha || !data_dir || !feedback_dir || !logs_level) {
return common::make_errno_error_inval();
}
auto sid = GetSid(config);
if (!sid) {
return common::make_errno_error("Define " ID_FIELD " variable and make it valid", EAGAIN);
}
StreamInfo lsha;
lsha.id = *sid;
int64_t type;
common::Value* type_field = config->Find(TYPE_FIELD);
if (!type_field || !type_field->GetAsInteger64(&type)) {
return common::make_errno_error("Define " TYPE_FIELD " variable and make it valid", EAGAIN);
}
lsha.type = static_cast<fastotv::StreamType>(type);
if (lsha.type == fastotv::PROXY || lsha.type == fastotv::VOD_PROXY) {
return common::make_errno_error("Proxy streams not handled for now", EINVAL);
}
std::string lfeedback_dir;
common::Value* feedback_field = config->Find(FEEDBACK_DIR_FIELD);
if (!feedback_field || !feedback_field->GetAsBasicString(&lfeedback_dir)) {
return common::make_errno_error("Define " FEEDBACK_DIR_FIELD " variable and make it valid", EAGAIN);
}
std::string ldata_dir;
common::Value* data_field = config->Find(DATA_DIR_FIELD);
if (!data_field || !data_field->GetAsBasicString(&ldata_dir)) {
return common::make_errno_error("Define " DATA_DIR_FIELD " variable and make it valid", EAGAIN);
}
int64_t llogs_level;
common::Value* log_level_field = config->Find(LOG_LEVEL_FIELD);
if (!log_level_field || !log_level_field->GetAsInteger64(&llogs_level)) {
llogs_level = common::logging::LOG_LEVEL_DEBUG;
}
common::ErrnoError errn = CreateAndCheckDir(lfeedback_dir);
if (errn) {
return errn;
}
errn = CreateAndCheckDir(ldata_dir);
if (errn) {
return errn;
}
const auto input = ReadInput(config);
if (!input) {
return common::make_errno_error("Define " INPUT_FIELD " variable and make it valid", EAGAIN);
}
lsha.input = *input;
if (check_folders) {
bool is_timeshift_rec = type == fastotv::TIMESHIFT_RECORDER; // no outputs
if (is_timeshift_rec || type == fastotv::CATCHUP) {
std::string timeshift_dir;
common::Value* timeshift_dir_field = config->Find(TIMESHIFT_DIR_FIELD);
if (!timeshift_dir_field || !timeshift_dir_field->GetAsBasicString(&timeshift_dir)) {
return common::make_errno_error("Define " TIMESHIFT_DIR_FIELD " variable and make it valid", EAGAIN);
}
errn = CreateAndCheckDir(timeshift_dir);
if (errn) {
return errn;
}
}
if (!is_timeshift_rec) {
const auto output = ReadOutput(config);
if (!output) {
return common::make_errno_error("Define " OUTPUT_FIELD " variable and make it valid", EAGAIN);
}
for (const auto& out_uri : *output) {
auto ouri = out_uri.GetUrl();
if (ouri.SchemeIsHTTPOrHTTPS()) {
if (out_uri.IsHls()) {
const auto http_root = out_uri.GetHttpRoot();
if (!http_root) {
return common::make_errno_error_inval();
}
const std::string http_root_str = http_root->GetPath();
common::ErrnoError errn = CreateAndCheckDir(http_root_str);
if (errn) {
return errn;
}
}
} else if (ouri.SchemeIsFile()) {
const auto file_path = common::file_system::ascii_file_string_path(ouri.path());
if (!file_path.IsValid()) {
return common::make_errno_error_inval();
}
const std::string file_root_str = file_path.GetDirectory();
common::ErrnoError errn = CreateAndCheckDir(file_root_str);
if (errn) {
return errn;
}
}
lsha.output.push_back(out_uri);
}
}
}
*logs_level = static_cast<common::logging::LOG_LEVEL>(llogs_level);
*feedback_dir = lfeedback_dir;
*data_dir = ldata_dir;
*sha = lsha;
return common::ErrnoError();
}
common::ErrnoError CleanStream(const StreamConfig& config) {
auto sid = GetSid(config);
if (!sid) {
return common::make_errno_error("Define " ID_FIELD " variable and make it valid", EAGAIN);
}
StreamInfo lsha;
lsha.id = *sid;
int64_t type;
common::Value* type_field = config->Find(TYPE_FIELD);
if (!type_field || !type_field->GetAsInteger64(&type)) {
return common::make_errno_error("Define " TYPE_FIELD " variable and make it valid", EAGAIN);
}
lsha.type = static_cast<fastotv::StreamType>(type);
if (lsha.type == fastotv::PROXY || lsha.type == fastotv::VOD_PROXY) {
return common::make_errno_error("Proxy streams not handled for now", EINVAL);
}
std::string lfeedback_dir;
common::Value* feedback_field = config->Find(FEEDBACK_DIR_FIELD);
if (!feedback_field || !feedback_field->GetAsBasicString(&lfeedback_dir)) {
return common::make_errno_error("Define " FEEDBACK_DIR_FIELD " variable and make it valid", EAGAIN);
}
std::string ldata_dir;
common::Value* data_field = config->Find(DATA_DIR_FIELD);
if (!data_field || !data_field->GetAsBasicString(&ldata_dir)) {
return common::make_errno_error("Define " DATA_DIR_FIELD " variable and make it valid", EAGAIN);
}
int64_t llogs_level;
common::Value* log_level_field = config->Find(LOG_LEVEL_FIELD);
if (!log_level_field || !log_level_field->GetAsInteger64(&llogs_level)) {
llogs_level = common::logging::LOG_LEVEL_DEBUG;
}
common::ErrnoError errn = common::file_system::remove_directory(lfeedback_dir, true);
if (errn) {
return errn;
}
errn = common::file_system::remove_directory(ldata_dir, true);
if (errn) {
return errn;
}
const auto input = ReadInput(config);
if (!input) {
return common::make_errno_error("Define " INPUT_FIELD " variable and make it valid", EAGAIN);
}
lsha.input = *input;
bool is_timeshift_rec = type == fastotv::TIMESHIFT_RECORDER; // no outputs
if (is_timeshift_rec || type == fastotv::CATCHUP) {
std::string timeshift_dir;
common::Value* timeshift_dir_field = config->Find(TIMESHIFT_DIR_FIELD);
if (!timeshift_dir_field || !timeshift_dir_field->GetAsBasicString(&timeshift_dir)) {
return common::make_errno_error("Define " TIMESHIFT_DIR_FIELD " variable and make it valid", EAGAIN);
}
errn = common::file_system::remove_directory(timeshift_dir, true);
if (errn) {
return errn;
}
}
if (!is_timeshift_rec) {
const auto output = ReadOutput(config);
if (!output) {
return common::make_errno_error("Define " OUTPUT_FIELD " variable and make it valid", EAGAIN);
}
for (const auto& out_uri : *output) {
auto ouri = out_uri.GetUrl();
if (ouri.SchemeIsHTTPOrHTTPS()) {
if (out_uri.IsHls()) {
const auto http_root = out_uri.GetHttpRoot();
if (!http_root) {
return common::make_errno_error_inval();
}
const std::string http_root_str = http_root->GetPath();
common::ErrnoError errn = common::file_system::remove_directory(http_root_str, true);
if (errn) {
return errn;
}
}
} else if (ouri.SchemeIsFile()) {
const auto file_path = common::file_system::ascii_file_string_path(ouri.path());
if (!file_path.IsValid()) {
return common::make_errno_error_inval();
}
const std::string file_root_str = file_path.GetDirectory();
common::ErrnoError errn = common::file_system::remove_directory(file_root_str, true);
if (errn) {
return errn;
}
}
lsha.output.push_back(out_uri);
}
}
return common::ErrnoError();
}
} // namespace fastocloud

42
src/base/stream_config.h Normal file
View file

@ -0,0 +1,42 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <memory>
#include <string>
#include "base/stream_info.h"
#include <fastotv/types/stream_ttl.h>
namespace fastocloud {
typedef std::shared_ptr<common::HashValue> StreamConfig;
common::Optional<fastotv::stream_id_t> GetSid(const StreamConfig& config) WARN_UNUSED_RESULT;
common::Optional<fastotv::StreamTTL> GetTTL(const StreamConfig& config) WARN_UNUSED_RESULT;
common::Optional<input_t> ReadInput(const StreamConfig& config) WARN_UNUSED_RESULT;
common::Optional<output_t> ReadOutput(const StreamConfig& config) WARN_UNUSED_RESULT;
common::ErrnoError MakeStreamInfo(const StreamConfig& config,
bool check_folders,
StreamInfo* sha,
std::string* feedback_dir,
std::string* data_dir,
common::logging::LOG_LEVEL* logs_level) WARN_UNUSED_RESULT;
common::ErrnoError CleanStream(const StreamConfig& config) WARN_UNUSED_RESULT;
} // namespace fastocloud

View file

@ -0,0 +1,188 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/stream_config_parse.h"
#include <string>
#include <vector>
#include <json-c/json_tokener.h>
#include <json-c/linkhash.h>
#include <common/serializer/json_serializer.h>
namespace {
common::Value* MakeValueFromJson(json_object* obj) {
json_type obj_type = json_object_get_type(obj);
if (obj_type == json_type_null) {
return common::Value::CreateNullValue();
} else if (obj_type == json_type_boolean) {
return common::Value::CreateBooleanValue(json_object_get_boolean(obj));
} else if (obj_type == json_type_double) {
return common::Value::CreateDoubleValue(json_object_get_double(obj));
} else if (obj_type == json_type_int) {
int64_t jint = json_object_get_int64(obj);
return common::Value::CreateInteger64Value(jint);
} else if (obj_type == json_type_string) {
return common::Value::CreateStringValueFromBasicString(json_object_get_string(obj));
} else if (obj_type == json_type_object) {
common::HashValue* result = common::Value::CreateHashValue();
json_object_object_foreach(obj, key, val) {
json_type val_type = json_object_get_type(val);
common::Value* value = nullptr;
switch (val_type) {
case json_type_null:
value = common::Value::CreateNullValue();
break;
case json_type_boolean:
value = common::Value::CreateBooleanValue(json_object_get_boolean(val));
break;
case json_type_double:
value = common::Value::CreateDoubleValue(json_object_get_double(val));
break;
case json_type_int:
value = common::Value::CreateInteger64Value(json_object_get_int64(val));
break;
case json_type_string:
value = common::Value::CreateStringValueFromBasicString(json_object_get_string(val));
break;
case json_type_object:
value = MakeValueFromJson(val);
break;
case json_type_array:
common::ArrayValue* arr = common::Value::CreateArrayValue();
for (size_t i = 0; i < json_object_array_length(val); i++) {
json_object* item = json_object_array_get_idx(val, i);
arr->Append(MakeValueFromJson(item));
}
value = arr;
break;
}
result->Insert(key, value);
}
return result;
} else if (obj_type == json_type_array) {
common::ArrayValue* arr = common::Value::CreateArrayValue();
for (size_t i = 0; i < json_object_array_length(obj); i++) {
json_object* item = json_object_array_get_idx(obj, i);
arr->Append(MakeValueFromJson(item));
}
return arr;
}
DNOTREACHED();
return nullptr;
}
json_object* MakeJson(const common::Value* value) {
const common::Value::Type type = value->GetType();
if (type == common::Value::TYPE_NULL) {
return nullptr;
} else if (type == common::Value::TYPE_BOOLEAN) {
bool rbool;
if (value->GetAsBoolean(&rbool)) {
return json_object_new_boolean(rbool);
}
} else if (type == common::Value::TYPE_DOUBLE) {
double rdouble;
if (value->GetAsDouble(&rdouble)) {
return json_object_new_double(rdouble);
}
} else if (type == common::Value::TYPE_INTEGER64) {
int64_t rint;
if (value->GetAsInteger64(&rint)) {
return json_object_new_int64(rint);
}
} else if (type == common::Value::TYPE_STRING) {
common::Value::string_t rstring;
if (value->GetAsString(&rstring)) {
const std::string r = rstring.as_string();
return json_object_new_string(r.c_str());
}
} else if (type == common::Value::TYPE_HASH) {
json_object* result = json_object_new_object();
const common::HashValue* hash = nullptr;
if (value->GetAsHash(&hash)) {
for (auto it = hash->begin(); it != hash->end(); ++it) {
const common::Value::string_t key = it->first;
const std::string key_str = key.as_string();
const common::Value* value = it->second;
ignore_result(common::serializer::json_set_object(result, key_str.c_str(), MakeJson(value)));
}
}
return result;
} else if (type == common::Value::TYPE_ARRAY) {
json_object* arr = json_object_new_array();
const common::ArrayValue* arr_value = nullptr;
if (value->GetAsList(&arr_value)) {
for (size_t i = 0; i < arr_value->GetSize(); ++i) {
const common::Value* val = nullptr;
if (arr_value->Get(i, &val)) {
json_object* obj = MakeJson(val);
json_object_array_add(arr, obj);
}
}
}
return arr;
}
DNOTREACHED();
return nullptr;
}
} // namespace
namespace fastocloud {
std::unique_ptr<common::HashValue> MakeConfigFromJson(const std::string& json) {
if (json.empty()) {
return nullptr;
}
json_object* obj = json_tokener_parse(json.c_str());
if (!obj) {
return nullptr;
}
std::unique_ptr<common::HashValue> res = MakeConfigFromJson(obj);
json_object_put(obj);
return res;
}
std::unique_ptr<common::HashValue> MakeConfigFromJson(json_object* obj) {
json_type obj_type = json_object_get_type(obj);
if (obj_type == json_type_object) {
return std::unique_ptr<common::HashValue>(static_cast<common::HashValue*>(MakeValueFromJson(obj)));
}
return nullptr;
}
bool MakeJsonFromConfig(std::shared_ptr<common::HashValue> config, std::string* json) {
if (!config || !json) {
return false;
}
json_object* jobj = MakeJson(config.get());
if (!jobj) {
return false;
}
*json = json_object_get_string(jobj);
json_object_put(jobj);
return true;
}
} // namespace fastocloud

View file

@ -0,0 +1,32 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <memory>
#include <string>
#include <vector>
#include <common/value.h>
#include <json-c/json_types.h>
namespace fastocloud {
std::unique_ptr<common::HashValue> MakeConfigFromJson(const std::string& json);
std::unique_ptr<common::HashValue> MakeConfigFromJson(json_object* obj);
bool MakeJsonFromConfig(std::shared_ptr<common::HashValue> config, std::string* json);
} // namespace fastocloud

17
src/base/stream_info.cpp Normal file
View file

@ -0,0 +1,17 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/stream_info.h"
namespace fastocloud {} // namespace fastocloud

34
src/base/stream_info.h Normal file
View file

@ -0,0 +1,34 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <vector>
#include "base/channel_stats.h"
#include "base/types.h"
namespace fastocloud {
typedef std::vector<ChannelStats> input_channels_info_t;
typedef std::vector<ChannelStats> output_channels_info_t;
struct StreamInfo {
fastotv::stream_id_t id;
fastotv::StreamType type;
input_t input;
output_t output;
};
} // namespace fastocloud

View file

@ -0,0 +1,98 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/stream_struct.h"
#include <string>
#include <common/time.h>
#include "base/channel_stats.h"
namespace common {
std::string ConvertToString(fastocloud::StreamStatus st) {
static const std::string kStreamStatuses[] = {
"New", "Inited", "Started", "Ready", "Playing", "Frozen", "Waiting",
};
return kStreamStatuses[st];
}
} // namespace common
namespace fastocloud {
namespace {
output_channels_info_t make_outputs(const std::vector<fastotv::OutputUri>& output) {
output_channels_info_t res;
for (auto out : output) {
res.push_back(ChannelStats(out.GetID()));
}
return res;
}
input_channels_info_t make_inputs(const std::vector<fastotv::InputUri>& input) {
input_channels_info_t res;
for (auto in : input) {
res.push_back(ChannelStats(in.GetID()));
}
return res;
}
} // namespace
StreamStruct::StreamStruct() : StreamStruct(StreamInfo()) {}
StreamStruct::StreamStruct(const StreamInfo& sha) : StreamStruct(sha, common::time::current_utc_mstime(), 0, 0) {}
StreamStruct::StreamStruct(const StreamInfo& sha,
fastotv::timestamp_t start_time,
fastotv::timestamp_t lst,
size_t rest)
: StreamStruct(sha.id, sha.type, NEW, make_inputs(sha.input), make_outputs(sha.output), start_time, lst, rest) {}
StreamStruct::StreamStruct(fastotv::stream_id_t sid,
fastotv::StreamType type,
StreamStatus status,
input_channels_info_t input,
output_channels_info_t output,
fastotv::timestamp_t start_time,
fastotv::timestamp_t lst,
size_t rest)
: id(sid),
type(type),
start_time(start_time),
loop_start_time(lst),
idle_time(0),
restarts(rest),
status(status),
input(input),
output(output) {}
bool StreamStruct::IsValid() const {
return !id.empty();
}
StreamStruct::~StreamStruct() {}
void StreamStruct::ResetDataWait() {
for (size_t i = 0; i < input.size(); ++i) {
input[i].UpdateCheckPoint();
}
for (size_t i = 0; i < output.size(); ++i) {
output[i].UpdateCheckPoint();
}
}
} // namespace fastocloud

62
src/base/stream_struct.h Normal file
View file

@ -0,0 +1,62 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <string>
#include <vector>
#include "base/stream_info.h"
namespace fastocloud {
enum StreamStatus { NEW = 0, INIT = 1, STARTED = 2, READY = 3, PLAYING = 4, FROZEN = 5, WAITING = 6 };
struct StreamStruct {
StreamStruct();
explicit StreamStruct(const StreamInfo& sha);
StreamStruct(const StreamInfo& sha, fastotv::timestamp_t start_time, fastotv::timestamp_t lst, size_t rest);
StreamStruct(fastotv::stream_id_t sid,
fastotv::StreamType type,
StreamStatus status,
input_channels_info_t input,
output_channels_info_t output,
fastotv::timestamp_t start_time,
fastotv::timestamp_t lst,
size_t rest);
bool IsValid() const;
~StreamStruct();
void ResetDataWait();
fastotv::stream_id_t id;
fastotv::StreamType type;
fastotv::timestamp_t start_time;
fastotv::timestamp_t loop_start_time;
fastotv::timestamp_t idle_time;
size_t restarts;
StreamStatus status;
input_channels_info_t input;
output_channels_info_t output;
};
} // namespace fastocloud
namespace common {
std::string ConvertToString(fastocloud::StreamStatus st);
}

17
src/base/types.cpp Normal file
View file

@ -0,0 +1,17 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/types.h"
namespace fastocloud {} // namespace fastocloud

40
src/base/types.h Normal file
View file

@ -0,0 +1,40 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <common/optional.h>
#include <fastotv/types/input_uri.h>
#include <fastotv/types/output_uri.h>
#define TS_EXTENSION "ts"
#define M3U8_EXTENSION "m3u8"
#define DASH_EXTENSION "mpd"
#define M3U8_CHUNK_MARKER "#EXTINF"
#define CHUNK_EXT "." TS_EXTENSION
#define DUMP_FILE_NAME "dump.html"
#define CONFIG_FILE_NAME "config.json"
namespace fastocloud {
typedef common::Optional<double> volume_t;
typedef double alpha_t;
typedef common::Optional<int> bit_rate_t;
typedef std::vector<fastotv::InputUri> input_t;
typedef std::vector<fastotv::OutputUri> output_t;
} // namespace fastocloud

159
src/base/utils.cpp Normal file
View file

@ -0,0 +1,159 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "base/utils.h"
#include <common/file_system/file_system.h>
#include <common/file_system/string_path_utils.h>
#include <common/sprintf.h>
#include <common/uri/gurl.h>
#include <dirent.h>
#include <string.h>
namespace fastocloud {
common::Optional<common::net::HostAndPort> GetHostAndPortFromGurl(const common::uri::GURL& url) {
if (!url.is_valid()) {
return common::Optional<common::net::HostAndPort>();
}
return common::net::HostAndPort(url.host(), url.IntPort());
}
common::ErrnoError CreateAndCheckDir(const std::string& directory_path) {
if (!common::file_system::is_directory_exist(directory_path)) {
common::ErrnoError errn = common::file_system::create_directory(directory_path, true);
if (errn) {
return errn;
}
}
return common::file_system::node_access(directory_path);
}
void RemoveFilesByExtension(const common::file_system::ascii_directory_string_path& dir, const char* ext) {
if (!dir.IsValid()) {
return;
}
const std::string path = dir.GetPath();
DIR* dirp = opendir(path.c_str());
if (!dirp) {
return;
}
DEBUG_LOG() << "Started clean up folder: " << path;
struct dirent* dent;
while ((dent = readdir(dirp)) != nullptr) {
if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) {
continue;
}
char* pch = strstr(dent->d_name, ext);
if (pch) {
std::string file_path = common::MemSPrintf("%s%s", path, dent->d_name);
time_t mtime;
common::ErrnoError err = common::file_system::get_file_time_last_modification(file_path, &mtime);
if (err) {
WARNING_LOG() << "Can't get timestamp file: " << file_path << ", error: " << err->GetDescription();
} else {
err = common::file_system::remove_file(file_path);
if (err) {
WARNING_LOG() << "Can't remove file: " << file_path << ", error: " << err->GetDescription();
} else {
DEBUG_LOG() << "File path: " << file_path << " removed.";
}
}
}
}
closedir(dirp);
DEBUG_LOG() << "Finished clean up folder: " << path;
}
void RemoveOldFilesByTime(const common::file_system::ascii_directory_string_path& dir,
common::utctime_t max_life_secs,
const char* pattern,
bool recursive) {
if (!dir.IsValid()) {
return;
}
const std::string path = dir.GetPath();
DIR* dirp = opendir(path.c_str());
if (!dirp) {
return;
}
DEBUG_LOG() << "Started clean up folder: " << path;
struct dirent* dent;
while ((dent = readdir(dirp)) != nullptr) {
if (!strcmp(dent->d_name, ".") || !strcmp(dent->d_name, "..")) {
continue;
}
#ifdef OS_WIN
const std::string dir_str = common::file_system::make_path(path, dent->d_name);
common::tribool is_dir_tr = common::file_system::is_directory(dir_str);
if (is_dir_tr == common::INDETERMINATE) {
continue;
}
bool is_dir = is_dir_tr == common::SUCCESS;
#else
bool is_dir = dent->d_type == DT_DIR;
#endif
if (!is_dir) {
if (common::MatchPattern(dent->d_name, pattern)) {
std::string file_path = common::MemSPrintf("%s%s", path, dent->d_name);
common::utctime_t mtime;
common::ErrnoError err = common::file_system::get_file_time_last_modification(file_path, &mtime);
if (err) {
WARNING_LOG() << "Can't get timestamp file: " << file_path << ", error: " << err->GetDescription();
} else {
if (mtime < max_life_secs) {
err = common::file_system::remove_file(file_path);
if (err) {
WARNING_LOG() << "Can't remove file: " << file_path << ", error: " << err->GetDescription();
} else {
DEBUG_LOG() << "File path: " << file_path << " removed.";
}
}
}
}
} else if (recursive) {
auto folder = dir.MakeDirectoryStringPath(dent->d_name);
if (folder) {
RemoveOldFilesByTime(*folder, max_life_secs, pattern, recursive);
}
}
}
closedir(dirp);
DEBUG_LOG() << "Finished clean up folder: " << path;
}
common::Optional<std::string> GetAudioMasterUrlFromQuery(const std::string& query_str) {
common::uri::Component key, value;
common::uri::Component query(0, query_str.length());
while (common::uri::ExtractQueryKeyValue(query_str.c_str(), &query, &key, &value)) {
std::string key_string(query_str.substr(key.begin, key.len));
std::string param_text(query_str.substr(value.begin, value.len));
if (common::EqualsASCII(key_string, "audio", false)) {
return common::Optional<std::string>(param_text);
}
}
return common::Optional<std::string>();
}
} // namespace fastocloud

37
src/base/utils.h Normal file
View file

@ -0,0 +1,37 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <common/error.h>
#include <common/file_system/path.h>
#include <common/net/types.h>
#include <common/uri/gurl.h>
#include <string>
namespace fastocloud {
common::Optional<common::net::HostAndPort> GetHostAndPortFromGurl(const common::uri::GURL& url);
common::ErrnoError CreateAndCheckDir(const std::string& directory_path) WARN_UNUSED_RESULT;
void RemoveOldFilesByTime(const common::file_system::ascii_directory_string_path& dir,
common::utctime_t max_life_secs,
const char* pattern,
bool recursive = false);
void RemoveFilesByExtension(const common::file_system::ascii_directory_string_path& dir, const char* ext);
common::Optional<std::string> GetAudioMasterUrlFromQuery(const std::string& query);
} // namespace fastocloud

391
src/server/CMakeLists.txt Normal file
View file

@ -0,0 +1,391 @@
# service variables
SET(STREAMER_SERVICE_PORT 6317)
SET(STREAMER_SERVICE_ALIAS "127.0.0.1")
SET(STREAMER_SERVICE_HOST "${STREAMER_SERVICE_ALIAS}:${STREAMER_SERVICE_PORT}") # service endpoint
SET(STREAMER_SERVICE_HLS_HOST "http://0.0.0.0:8000") # hls endpoint
SET(STREAMER_SERVICE_VODS_HOST "http://0.0.0.0:7000") # vods endpoint
SET(STREAMER_SERVICE_CODS_HOST "http://0.0.0.0:6000") # cods endpoint
SET(STREAMER_SERVICE_CODS_TTL 600)
SET(STREAMER_SERVICE_FILES_TTL 604800) #7 days (7 * 24 * 3600)
SET(STREAMER_SERVICE_PYFASTOSTREAM_PATH "/usr/local/bin/pyfastostream")
SET(STREAMER_SERVICE_HLS_DIR "~/streamer/hls")
SET(STREAMER_SERVICE_VODS_DIR "~/streamer/vods")
SET(STREAMER_SERVICE_CODS_DIR "~/streamer/cods")
SET(STREAMER_SERVICE_TIMESHIFTS_DIR "~/streamer/timeshifts")
SET(STREAMER_SERVICE_FEEDBACK_DIR "~/streamer/feedback")
SET(STREAMER_SERVICE_PROXY_DIR "~/streamer/proxy")
SET(STREAMER_SERVICE_DATA_DIR "~/streamer/data")
#
SET(STREAMER_SERVICE_NAME_EXE ${STREAMER_SERVICE_NAME}_s)
SET(STREAMER_EXE_NAME stream)
FIND_PACKAGE(Common REQUIRED)
FIND_PACKAGE(FastoTvCPP REQUIRED)
FIND_PACKAGE(JSON-C REQUIRED)
FIND_PACKAGE(OpenSSL REQUIRED)
SET(PRIVATE_COMPILE_DEFINITIONS_SLAVE ${PRIVATE_COMPILE_DEFINITIONS_SLAVE} -DHAVE_OPENSSL)
# platform specific
IF(OS_WINDOWS)
SET(PLATFORM_HEADER)
SET(PLATFORM_SOURCES)
SET(PLATFORM_LIBRARIES ws2_32 psapi)
SET(RELATIVE_SOURCE_DIR .)
ELSEIF(OS_LINUX)
SET(PLATFORM_HEADER)
SET(PLATFORM_SOURCES)
SET(PLATFORM_LIBRARIES dl)
SET(RELATIVE_SOURCE_DIR ..)
FIND_LIBRARY(UDEV_LIBRARY udev)
FIND_PATH(UDEV_INCLUDE_DIR NAMES libudev.h)
IF(UDEV_LIBRARY AND UDEV_INCLUDE_DIR)
SET(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} ${UDEV_LIBRARY})
ENDIF(UDEV_LIBRARY AND UDEV_INCLUDE_DIR)
IF (PLATFORM_ARM)
FIND_LIBRARY(ATOMIC_LIBRARY NAMES atomic atomic.so.1 libatomic.so.1)
IF(ATOMIC_LIBRARY)
SET(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} ${ATOMIC_LIBRARY})
ENDIF(ATOMIC_LIBRARY)
ENDIF(PLATFORM_ARM)
ELSEIF(OS_MACOSX)
FIND_LIBRARY(FOUNDATION_LIBRARY Foundation)
FIND_LIBRARY(IOKIT_LIBRARY IOKit)
SET(PLATFORM_HEADER)
SET(PLATFORM_SOURCES)
SET(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} dl ${FOUNDATION_LIBRARY} ${IOKIT_LIBRARY})
SET(RELATIVE_SOURCE_DIR ..)
ELSEIF(OS_FREEBSD)
SET(PLATFORM_HEADER)
SET(PLATFORM_SOURCES)
SET(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} dl)
SET(RELATIVE_SOURCE_DIR ..)
FIND_LIBRARY(UDEV_LIBRARY udev)
FIND_PATH(UDEV_INCLUDE_DIR NAMES libudev.h)
IF(UDEV_LIBRARY AND UDEV_INCLUDE_DIR)
SET(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} ${UDEV_LIBRARY})
ENDIF(UDEV_LIBRARY AND UDEV_INCLUDE_DIR)
ELSEIF(OS_POSIX)
SET(PLATFORM_HEADER)
SET(PLATFORM_SOURCES)
SET(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} udev dl)
SET(RELATIVE_SOURCE_DIR ..)
ENDIF(OS_WINDOWS)
IF(USE_PTHREAD)
IF(NOT OS_ANDROID)
SET(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} pthread)
ENDIF(NOT OS_ANDROID)
ENDIF(USE_PTHREAD)
SET(PIPE_HEADERS ${CMAKE_SOURCE_DIR}/src/server/pipe/client.h)
SET(PIPE_SOURCES ${CMAKE_SOURCE_DIR}/src/server/pipe/client.cpp)
SET(TCP_HEADERS ${CMAKE_SOURCE_DIR}/src/server/tcp/client.h)
SET(TCP_SOURCES ${CMAKE_SOURCE_DIR}/src/server/tcp/client.cpp)
SET(UTILS_HEADERS ${CMAKE_SOURCE_DIR}/src/server/utils/utils.h)
SET(UTILS_SOURCES ${CMAKE_SOURCE_DIR}/src/server/utils/utils.cpp)
SET(OPTIONS_HEADERS ${CMAKE_SOURCE_DIR}/src/server/options/options.h)
SET(OPTIONS_SOURCES ${CMAKE_SOURCE_DIR}/src/server/options/options.cpp)
SET(SERVER_HTTP_HEADERS
${CMAKE_SOURCE_DIR}/src/server/http/handler.h
${CMAKE_SOURCE_DIR}/src/server/http/client.h
${CMAKE_SOURCE_DIR}/src/server/http/server.h
)
SET(SERVER_HTTP_SOURCES
${CMAKE_SOURCE_DIR}/src/server/http/handler.cpp
${CMAKE_SOURCE_DIR}/src/server/http/client.cpp
${CMAKE_SOURCE_DIR}/src/server/http/server.cpp
)
SET(SERVER_DAEMON_HEADERS
${CMAKE_SOURCE_DIR}/src/server/daemon/client.h
${CMAKE_SOURCE_DIR}/src/server/daemon/server.h
${CMAKE_SOURCE_DIR}/src/server/daemon/commands.h
${CMAKE_SOURCE_DIR}/src/server/daemon/commands_factory.h
${CMAKE_SOURCE_DIR}/src/server/daemon/commands_info/service/details/shots.h
${CMAKE_SOURCE_DIR}/src/server/daemon/commands_info/service/server_info.h
${CMAKE_SOURCE_DIR}/src/server/daemon/commands_info/stream/stream_info.h
${CMAKE_SOURCE_DIR}/src/server/daemon/commands_info/stream/start_info.h
${CMAKE_SOURCE_DIR}/src/server/daemon/commands_info/stream/quit_status_info.h
${CMAKE_SOURCE_DIR}/src/server/daemon/commands_info/stream/restart_info.h
${CMAKE_SOURCE_DIR}/src/server/daemon/commands_info/stream/stop_info.h
${CMAKE_SOURCE_DIR}/src/server/daemon/commands_info/stream/get_log_info.h
)
SET(SERVER_DAEMON_SOURCES
${CMAKE_SOURCE_DIR}/src/server/daemon/client.cpp
${CMAKE_SOURCE_DIR}/src/server/daemon/server.cpp
${CMAKE_SOURCE_DIR}/src/server/daemon/commands.cpp
${CMAKE_SOURCE_DIR}/src/server/daemon/commands_factory.cpp
${CMAKE_SOURCE_DIR}/src/server/daemon/commands_info/service/details/shots.cpp
${CMAKE_SOURCE_DIR}/src/server/daemon/commands_info/service/server_info.cpp
${CMAKE_SOURCE_DIR}/src/server/daemon/commands_info/stream/stream_info.cpp
${CMAKE_SOURCE_DIR}/src/server/daemon/commands_info/stream/start_info.cpp
${CMAKE_SOURCE_DIR}/src/server/daemon/commands_info/stream/quit_status_info.cpp
${CMAKE_SOURCE_DIR}/src/server/daemon/commands_info/stream/restart_info.cpp
${CMAKE_SOURCE_DIR}/src/server/daemon/commands_info/stream/stop_info.cpp
${CMAKE_SOURCE_DIR}/src/server/daemon/commands_info/stream/get_log_info.cpp
)
SET(SERVER_HEADERS
${CMAKE_SOURCE_DIR}/src/server/base/iserver_handler.h
${CMAKE_SOURCE_DIR}/src/server/child.h
${CMAKE_SOURCE_DIR}/src/server/child_stream.h
${CMAKE_SOURCE_DIR}/src/server/process_slave_wrapper.h
${CMAKE_SOURCE_DIR}/src/server/config.h
${SERVER_HTTP_HEADERS}
${SERVER_DAEMON_HEADERS}
${PIPE_HEADERS}
${TCP_HEADERS}
${UTILS_HEADERS}
${OPTIONS_HEADERS}
)
SET(SERVER_SOURCES
${CMAKE_SOURCE_DIR}/src/server/base/iserver_handler.cpp
${CMAKE_SOURCE_DIR}/src/server/child.cpp
${CMAKE_SOURCE_DIR}/src/server/child_stream.cpp
${CMAKE_SOURCE_DIR}/src/server/process_slave_wrapper.cpp
${CMAKE_SOURCE_DIR}/src/server/config.cpp
${SERVER_HTTP_SOURCES}
${SERVER_DAEMON_SOURCES}
${PIPE_SOURCES}
${TCP_SOURCES}
${UTILS_SOURCES}
${OPTIONS_SOURCES}
)
SET(PERF_OBSERVER_HEADERS
${CMAKE_SOURCE_DIR}/src/server/gpu_stats/perf_monitor.h
)
SET(PERF_OBSERVER_SOURCES
${CMAKE_SOURCE_DIR}/src/server/gpu_stats/perf_monitor.cpp
)
#gpu nvidia
FIND_PACKAGE(NVML)
IF(NVML_FOUND)
SET(DAEMON_LIBRARIES ${DAEMON_LIBRARIES} ${NVML_LIBRARIES})
SET(PERF_OBSERVER_HEADERS ${PERF_OBSERVER_HEADERS} ${CMAKE_SOURCE_DIR}/src/server/gpu_stats/nvidia_monitor.h)
SET(PERF_OBSERVER_SOURCES ${PERF_OBSERVER_SOURCES} ${CMAKE_SOURCE_DIR}/src/server/gpu_stats/nvidia_monitor.cpp)
SET(PRIVATE_INCLUDE_DIRECTORIES_SLAVE ${PRIVATE_INCLUDE_DIRECTORIES_SLAVE} ${NVML_INCLUDE_DIRS})
SET(PRIVATE_COMPILE_DEFINITIONS_SLAVE ${PRIVATE_COMPILE_DEFINITIONS_SLAVE} -DHAVE_NVML)
# ibnvidia-ml.so.1
GET_FILENAME_COMPONENT(NVML_LIBRARY_WITHOUT_SYMLINK ${NVML_LIBRARIES} REALPATH)
GET_FILENAME_COMPONENT(NVML_LIBRARY_NAME ${NVML_LIBRARY_WITHOUT_SYMLINK} NAME)
STRING(REGEX REPLACE "[^so]+$" ".1" NVML_LNNAME ${NVML_LIBRARY_NAME})
#libSDL2-2.0.so.0
INSTALL(FILES ${NVML_LIBRARY_WITHOUT_SYMLINK} DESTINATION ${LIB_INSTALL_DESTINATION} RENAME ${NVML_LNNAME} COMPONENT RUNTIME)
ENDIF(NVML_FOUND)
#gpu intel
SET(CTT_METRICS_PATH "/usr/local/share/mfx/samples/")
FIND_LIBRARY(CTT_METRICS_LIBRARY NAMES cttmetrics PATHS ${CTT_METRICS_PATH})
IF (CTT_METRICS_LIBRARY)
SET(DAEMON_LIBRARIES ${DAEMON_LIBRARIES} ${CTT_METRICS_LIBRARY})
SET(PERF_OBSERVER_HEADERS ${PERF_OBSERVER_HEADERS} ${CMAKE_SOURCE_DIR}/src/server/gpu_stats/intel_monitor.h)
SET(PERF_OBSERVER_SOURCES ${PERF_OBSERVER_SOURCES} ${CMAKE_SOURCE_DIR}/src/server/gpu_stats/intel_monitor.cpp)
SET(PRIVATE_COMPILE_DEFINITIONS_SLAVE ${PRIVATE_COMPILE_DEFINITIONS_SLAVE} -DHAVE_CTT_METRICS)
INSTALL(FILES ${CTT_METRICS_LIBRARY} DESTINATION ${LIB_INSTALL_DESTINATION} COMPONENT RUNTIME)
ENDIF(CTT_METRICS_LIBRARY)
#ssl libs install
GET_FILENAME_COMPONENT(OPENSSL_CRYPTO_LIBRARY_SYMLINK ${OPENSSL_CRYPTO_LIBRARY} REALPATH)
GET_FILENAME_COMPONENT(OPENSSL_CRYPTO_LIBRARY_NAME ${OPENSSL_CRYPTO_LIBRARY_SYMLINK} NAME)
INSTALL(FILES ${OPENSSL_CRYPTO_LIBRARY_SYMLINK} DESTINATION ${LIB_INSTALL_DESTINATION} COMPONENT RUNTIME)
GET_FILENAME_COMPONENT(OPENSSL_SSL_LIBRARY_SYMLINK ${OPENSSL_SSL_LIBRARY} REALPATH)
GET_FILENAME_COMPONENT(OPENSSL_SSL_LIBRARY_NAME ${OPENSSL_SSL_LIBRARY_SYMLINK} NAME)
INSTALL(FILES ${OPENSSL_SSL_LIBRARY_SYMLINK} DESTINATION ${LIB_INSTALL_DESTINATION} COMPONENT RUNTIME)
#INSTALL(FILES ${OPENSSL_LIBRARIES} DESTINATION ${LIB_INSTALL_DESTINATION} COMPONENT RUNTIME)
IF(OS_POSIX)
SET(SERVER_SOURCES ${SERVER_SOURCES} ${CMAKE_SOURCE_DIR}/src/server/process_slave_wrapper_posix.cpp)
ELSEIF(OS_WIN)
SET(SERVER_SOURCES ${SERVER_SOURCES} ${CMAKE_SOURCE_DIR}/src/server/process_slave_wrapper_win.cpp)
ENDIF(OS_POSIX)
SET(DAEMON_SOURCES
${SERVER_HEADERS} ${SERVER_SOURCES}
${PERF_OBSERVER_HEADERS} ${PERF_OBSERVER_SOURCES}
)
SET(DAEMON_LIBRARIES
${DAEMON_LIBRARIES}
${FASTOTV_CPP_LIBRARIES}
${COMMON_LIBRARIES}
${JSONC_LIBRARIES}
${PLATFORM_LIBRARIES}
${STREAMER_COMMON}
${OPENSSL_LIBRARIES}
)
SET(PRIVATE_INCLUDE_DIRECTORIES_SLAVE
${PRIVATE_INCLUDE_DIRECTORIES_SLAVE}
${FASTOTV_CPP_INCLUDE_DIRS}
${COMMON_INCLUDE_DIRS}
${CMAKE_SOURCE_DIR}/src
)
SET(CORE_LIBRARY ${LIB_INSTALL_DESTINATION}/${CMAKE_SHARED_LIBRARY_PREFIX}${STREAMER_CORE}${CMAKE_SHARED_LIBRARY_SUFFIX})
SET(RUN_DIR_PATH "/var/run/${STREAMER_SERVICE_NAME}")
SET(PIDFILE_PATH "${RUN_DIR_PATH}/${STREAMER_SERVICE_NAME}.pid")
SET(USER_NAME ${PROJECT_NAME_LOWERCASE})
SET(USER_GROUP ${PROJECT_NAME_LOWERCASE})
SET(CONFIG_PATH "/etc/${STREAMER_SERVICE_NAME}.conf")
SET(STREAM_DEFINITIONS
-DRELATIVE_SOURCE_DIR="${RELATIVE_SOURCE_DIR}"
-DCORE_LIBRARY="${CORE_LIBRARY}"
-DSTREAMER_NAME="${STREAMER_NAME}"
)
SET(PRIVATE_COMPILE_DEFINITIONS_SLAVE
${PRIVATE_COMPILE_DEFINITIONS_SLAVE}
${STREAM_DEFINITIONS}
-DCONFIG_PATH="${CONFIG_PATH}"
-DPIDFILE_PATH="${PIDFILE_PATH}"
-DSTREAMER_SERVICE_NAME="${STREAMER_SERVICE_NAME}"
-DCLIENT_PORT=${STREAMER_SERVICE_PORT}
-DSTREAMER_SERVICE_HLS_HOST="${STREAMER_SERVICE_HLS_HOST}"
-DSTREAMER_SERVICE_VODS_HOST="${STREAMER_SERVICE_VODS_HOST}"
-DSTREAMER_SERVICE_CODS_HOST="${STREAMER_SERVICE_CODS_HOST}"
-DCODS_TTL=${STREAMER_SERVICE_CODS_TTL}
-DFILES_TTL=${STREAMER_SERVICE_FILES_TTL}
-DSTREAMER_SERVICE_PYFASTOSTREAM_PATH="${STREAMER_SERVICE_PYFASTOSTREAM_PATH}"
-DSTREAMER_SERVICE_ALIAS="${STREAMER_SERVICE_ALIAS}"
-DSTREAMER_SERVICE_HLS_DIR="${STREAMER_SERVICE_HLS_DIR}"
-DSTREAMER_SERVICE_VODS_DIR="${STREAMER_SERVICE_VODS_DIR}"
-DSTREAMER_SERVICE_CODS_DIR="${STREAMER_SERVICE_CODS_DIR}"
-DSTREAMER_SERVICE_TIMESHIFTS_DIR="${STREAMER_SERVICE_TIMESHIFTS_DIR}"
-DSTREAMER_SERVICE_FEEDBACK_DIR="${STREAMER_SERVICE_FEEDBACK_DIR}"
-DSTREAMER_SERVICE_PROXY_DIR="${STREAMER_SERVICE_PROXY_DIR}"
-DSTREAMER_SERVICE_DATA_DIR="${STREAMER_SERVICE_DATA_DIR}"
)
IF(OS_WIN)
SET(PRIVATE_COMPILE_DEFINITIONS_SLAVE ${PRIVATE_COMPILE_DEFINITIONS_SLAVE} -DSTREAMER_EXE_NAME="${STREAMER_EXE_NAME}")
ENDIF(OS_WIN)
SET(EXE_DAEMON_SOURCES ${CMAKE_SOURCE_DIR}/src/server/daemon_slave.cpp)
ADD_EXECUTABLE(${STREAMER_SERVICE_NAME_EXE} ${DAEMON_SOURCES} ${EXE_DAEMON_SOURCES})
TARGET_INCLUDE_DIRECTORIES(${STREAMER_SERVICE_NAME_EXE} PRIVATE ${PRIVATE_INCLUDE_DIRECTORIES_SLAVE})
TARGET_COMPILE_DEFINITIONS(${STREAMER_SERVICE_NAME_EXE} PRIVATE ${PRIVATE_COMPILE_DEFINITIONS_SLAVE})
TARGET_LINK_LIBRARIES(${STREAMER_SERVICE_NAME_EXE} ${DAEMON_LIBRARIES})
IF(PROJECT_BUILD_TYPE_VERSION STREQUAL "release")
STRIP_TARGET(${STREAMER_SERVICE_NAME_EXE})
ENDIF(PROJECT_BUILD_TYPE_VERSION STREQUAL "release")
INSTALL(TARGETS ${STREAMER_SERVICE_NAME_EXE} DESTINATION ${TARGET_INSTALL_DESTINATION} COMPONENT APPLICATIONS)
IF(OS_WIN)
ADD_EXECUTABLE(${STREAMER_EXE_NAME} ${CMAKE_SOURCE_DIR}/src/server/stream_win.cpp ${TCP_SOURCES})
TARGET_INCLUDE_DIRECTORIES(${STREAMER_EXE_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/src)
TARGET_COMPILE_DEFINITIONS(${STREAMER_EXE_NAME} PRIVATE ${STREAM_DEFINITIONS})
TARGET_LINK_LIBRARIES(${STREAMER_EXE_NAME} ${COMMON_LIBRARIES} ${PLATFORM_LIBRARIES} ${STREAMER_COMMON} ${FASTOTV_CPP_LIBRARIES})
IF(PROJECT_BUILD_TYPE_VERSION STREQUAL "release")
STRIP_TARGET(${STREAMER_EXE_NAME})
ENDIF(PROJECT_BUILD_TYPE_VERSION STREQUAL "release")
INSTALL(TARGETS ${STREAMER_EXE_NAME} DESTINATION ${TARGET_INSTALL_DESTINATION} COMPONENT APPLICATIONS)
ENDIF(OS_WIN)
SET(EXECUTABLE_FOLDER_PATH ${CMAKE_INSTALL_PREFIX}/bin)
IF(OS_WINDOWS)
ELSEIF(OS_MACOSX)
ELSEIF(OS_LINUX OR OS_FREEBSD)
SET(EXECUTABLE_PATH ${EXECUTABLE_FOLDER_PATH}/${STREAMER_SERVICE_NAME} CACHE INTERNAL "Daemon path: ${EXECUTABLE_PATH}")
ENDIF(OS_WINDOWS)
# script
SET(SERVICE_START_SCRIPT_GEN_PATH ${CMAKE_BINARY_DIR}/service/${STREAMER_SERVICE_NAME})
GEN_START_SCRIPT(${SERVICE_START_SCRIPT_GEN_PATH} ${STREAMER_SERVICE_NAME_EXE})
INSTALL(PROGRAMS ${SERVICE_START_SCRIPT_GEN_PATH} DESTINATION
${TARGET_INSTALL_DESTINATION} COMPONENT APPLICATIONS
)
# service
IF(OS_LINUX OR OS_FREEBSD)
SET(SERVICE_SCRIPT_GEN_PATH ${CMAKE_BINARY_DIR}/service/${STREAMER_SERVICE_NAME}.service)
GEN_SERVICE_SERVICE_FILE(${SERVICE_SCRIPT_GEN_PATH}
${STREAMER_SERVICE_NAME} ${STREAMER_SERVICE_NAME_EXE} forking
${EXECUTABLE_PATH}
${RUN_DIR_PATH}
${PIDFILE_PATH}
${USER_NAME} ${USER_GROUP}
${PROJECT_SUMMARY}
)
INSTALL(FILES ${SERVICE_SCRIPT_GEN_PATH} DESTINATION /etc/systemd/system/)
SET(SERVICE_DEB_SCRIPT_GEN_PATH ${CMAKE_BINARY_DIR}/service/${STREAMER_SERVICE_NAME}.debian)
GEN_DEBIAN_SERVICE_FILE(${SERVICE_DEB_SCRIPT_GEN_PATH}
${STREAMER_SERVICE_NAME} ${STREAMER_SERVICE_NAME_EXE}
${EXECUTABLE_PATH}
${RUN_DIR_PATH}
${PIDFILE_PATH}
${USER_NAME} ${USER_GROUP}
${PROJECT_SUMMARY}
)
INSTALL(FILES ${SERVICE_DEB_SCRIPT_GEN_PATH}
DESTINATION /etc/init.d
RENAME ${STREAMER_SERVICE_NAME}
PERMISSIONS OWNER_READ OWNER_WRITE OWNER_EXECUTE GROUP_READ GROUP_EXECUTE WORLD_READ WORLD_EXECUTE)
ENDIF(OS_LINUX OR OS_FREEBSD)
# config file
SET(SERVICE_CONF_GEN_PATH ${CMAKE_BINARY_DIR}/service/${STREAMER_SERVICE_NAME}.conf)
CONFIGURE_FILE(${CMAKE_SOURCE_DIR}/install/${PROJECT_NAME_LOWERCASE}/service/service.conf.in
${SERVICE_CONF_GEN_PATH} @ONLY IMMEDIATE
)
IF(NOT EXISTS ${CONFIG_PATH} OR CPACK_SUPPORT)
INSTALL(FILES ${SERVICE_CONF_GEN_PATH} DESTINATION /etc/)
ENDIF(NOT EXISTS ${CONFIG_PATH} OR CPACK_SUPPORT)
IF (DEVELOPER_CHECK_STYLE)
SET(CHECK_SOURCES_DAEMON ${DAEMON_SOURCES} ${EXE_DAEMON_SOURCES})
REGISTER_CHECK_STYLE_TARGET(check_style_${STREAMER_SERVICE_NAME} "${CHECK_SOURCES_DAEMON}")
REGISTER_CHECK_INCLUDES_TARGET(${STREAMER_SERVICE_NAME_EXE})
ENDIF(DEVELOPER_CHECK_STYLE)
IF(DEVELOPER_ENABLE_TESTS)
FIND_PACKAGE(GTest REQUIRED)
## Unit tests
SET(PRIVATE_INCLUDE_DIRECTORIES_UNIT_TESTS
${PRIVATE_INCLUDE_DIRECTORIES_UNIT_TESTS}
${CMAKE_SOURCE_DIR}/src
)
SET(UNIT_TESTS_LIBS
${GTEST_BOTH_LIBRARIES}
${STREAMER_COMMON}
${PLATFORM_LIBRARIES})
SET(UNIT_TESTS unit_tests_server)
ADD_EXECUTABLE(${UNIT_TESTS}
${CMAKE_SOURCE_DIR}/tests/server/unit_test_server.cpp ${OPTIONS_SOURCES}
)
TARGET_INCLUDE_DIRECTORIES(${UNIT_TESTS} PRIVATE ${PRIVATE_INCLUDE_DIRECTORIES_UNIT_TESTS} ${JSONC_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(${UNIT_TESTS} ${UNIT_TESTS_LIBS} ${DAEMON_LIBRARIES})
ADD_TEST_TARGET(${UNIT_TESTS})
SET_PROPERTY(TARGET ${UNIT_TESTS} PROPERTY FOLDER "Unit tests")
ENDIF(DEVELOPER_ENABLE_TESTS)

View file

@ -0,0 +1,45 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/base/iserver_handler.h"
namespace fastocloud {
namespace server {
namespace base {
IServerHandler::IServerHandler() : online_clients_(0) {}
size_t IServerHandler::GetOnlineClients() const {
return online_clients_;
}
void IServerHandler::Accepted(common::libev::IoClient* client) {
UNUSED(client);
online_clients_++;
}
void IServerHandler::Moved(common::libev::IoLoop* server, common::libev::IoClient* client) {
UNUSED(server);
UNUSED(client);
online_clients_--;
}
void IServerHandler::Closed(common::libev::IoClient* client) {
UNUSED(client);
online_clients_--;
}
} // namespace base
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,51 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <common/libev/io_loop_observer.h>
namespace fastocloud {
namespace server {
namespace base {
class IServerHandler : public common::libev::IoLoopObserver {
public:
typedef std::atomic<size_t> online_clients_t;
IServerHandler();
size_t GetOnlineClients() const;
void PreLooped(common::libev::IoLoop* server) override = 0;
void Accepted(common::libev::IoClient* client) override;
void Moved(common::libev::IoLoop* server, common::libev::IoClient* client) override;
void Closed(common::libev::IoClient* client) override;
void TimerEmited(common::libev::IoLoop* server, common::libev::timer_id_t id) override = 0;
void Accepted(common::libev::IoChild* child) override = 0;
void Moved(common::libev::IoLoop* server, common::libev::IoChild* child) override = 0;
void ChildStatusChanged(common::libev::IoChild* child, int status, int signal) override = 0;
void DataReceived(common::libev::IoClient* client) override = 0;
void DataReadyToWrite(common::libev::IoClient* client) override = 0;
void PostLooped(common::libev::IoLoop* server) override = 0;
private:
online_clients_t online_clients_;
};
} // namespace base
} // namespace server
} // namespace fastocloud

91
src/server/child.cpp Normal file
View file

@ -0,0 +1,91 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/child.h"
#include <common/time.h>
#include "base/constants.h"
#include "stream_commands/commands_factory.h"
namespace fastocloud {
namespace server {
Child::Child(common::libev::IoLoop* server)
: IoChild(server), client_(nullptr), request_id_(0), last_update_(common::time::current_utc_mstime()) {}
Child::~Child() {}
Child::client_t* Child::GetClient() const {
return client_;
}
void Child::SetClient(client_t* pipe) {
client_ = pipe;
}
void Child::UpdateTimestamp() {
last_update_ = common::time::current_utc_mstime();
}
fastotv::timestamp_t Child::GetLastUpdate() const {
return last_update_;
}
common::ErrnoError Child::Stop() {
if (!client_) {
return common::make_errno_error_inval();
}
fastotv::protocol::request_t req;
common::Error err = StopStreamRequest(NextRequestID(), &req);
if (err) {
return common::make_errno_error(err->GetDescription(), EAGAIN);
}
return client_->WriteRequest(req);
}
common::ErrnoError Child::Restart() {
if (!client_) {
return common::make_errno_error_inval();
}
fastotv::protocol::request_t req;
common::Error err = RestartStreamRequest(NextRequestID(), &req);
if (err) {
return common::make_errno_error(err->GetDescription(), EAGAIN);
}
return client_->WriteRequest(req);
}
common::ErrnoError Child::Terminate() {
#if defined(OS_POSIX)
int result = kill(GetProcessID(), KILL_STREAM_SIGNAL);
if (result != 0) {
return common::make_errno_error(errno);
}
return common::ErrnoError();
#else
return common::make_errno_error("Not implemented", EAGAIN);
#endif
}
fastotv::protocol::sequance_id_t Child::NextRequestID() {
const fastotv::protocol::seq_id_t next_id = request_id_++;
return common::protocols::json_rpc::MakeRequestID(next_id);
}
} // namespace server
} // namespace fastocloud

58
src/server/child.h Normal file
View file

@ -0,0 +1,58 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <common/libev/io_child.h>
#include <fastotv/protocol/protocol.h>
#include <fastotv/protocol/types.h>
#include <fastotv/types/input_uri.h>
namespace fastocloud {
namespace server {
class Child : public common::libev::IoChild {
public:
typedef fastotv::protocol::protocol_client_t client_t;
virtual fastotv::stream_id_t GetStreamID() const = 0;
common::ErrnoError Stop() WARN_UNUSED_RESULT;
common::ErrnoError Restart() WARN_UNUSED_RESULT;
common::ErrnoError Terminate() WARN_UNUSED_RESULT;
client_t* GetClient() const;
void SetClient(client_t* pipe);
virtual ~Child();
void UpdateTimestamp();
fastotv::timestamp_t GetLastUpdate() const;
protected:
explicit Child(common::libev::IoLoop* server);
fastotv::protocol::sequance_id_t NextRequestID();
protected:
client_t* client_;
private:
std::atomic<fastotv::protocol::seq_id_t> request_id_;
fastotv::timestamp_t last_update_;
};
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,55 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/child_stream.h"
#include <common/file_system/file_system.h>
namespace fastocloud {
namespace server {
ChildStream::ChildStream(common::libev::IoLoop* server, const StreamInfo& conf) : base_class(server), conf_(conf) {}
fastotv::stream_id_t ChildStream::GetStreamID() const {
return conf_.id;
}
fastotv::StreamType ChildStream::GetStreamType() const {
return conf_.type;
}
bool ChildStream::IsCOD() const {
const fastotv::StreamType type = GetStreamType();
return type == fastotv::COD_RELAY || type == fastotv::COD_ENCODE;
}
void ChildStream::CleanUp() {
if (conf_.type == fastotv::VOD_ENCODE || conf_.type == fastotv::VOD_RELAY || conf_.type == fastotv::CATCHUP ||
conf_.type == fastotv::TIMESHIFT_RECORDER || conf_.type == fastotv::TEST_LIFE) {
return;
}
for (auto out_uri : conf_.output) {
auto ouri = out_uri.GetUrl();
if (ouri.SchemeIsHTTPOrHTTPS()) {
const auto http_root = out_uri.GetHttpRoot();
if (http_root) {
common::file_system::remove_directory(http_root->GetPath(), true);
}
}
}
}
} // namespace server
} // namespace fastocloud

40
src/server/child_stream.h Normal file
View file

@ -0,0 +1,40 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "server/child.h"
#include "base/stream_info.h"
namespace fastocloud {
namespace server {
class ChildStream : public Child {
public:
typedef Child base_class;
ChildStream(common::libev::IoLoop* server, const StreamInfo& conf);
fastotv::stream_id_t GetStreamID() const override;
fastotv::StreamType GetStreamType() const;
bool IsCOD() const;
void CleanUp();
private:
const StreamInfo conf_;
DISALLOW_COPY_AND_ASSIGN(ChildStream);
};
} // namespace server
} // namespace fastocloud

309
src/server/config.cpp Normal file
View file

@ -0,0 +1,309 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/config.h"
#include <fstream>
#include <utility>
#include <common/convert2string.h>
#include <common/file_system/path.h>
#include <common/value.h>
#define SETTINGS_SECTION "[settings]"
#define SERVICE_LOG_PATH_FIELD "log_path"
#define SERVICE_LOG_LEVEL_FIELD "log_level"
#define SERVICE_HOST_FIELD "host"
#define SERVICE_ALIAS_FIELD "alias"
#define SERVICE_HLS_HOST_FIELD "hls_host"
#define SERVICE_VODS_HOST_FIELD "vods_host"
#define SERVICE_CODS_HOST_FIELD "cods_host"
#define SERVICE_HLS_DIR_FIELD "hls_dir"
#define SERVICE_VODS_DIR_FIELD "vods_dir"
#define SERVICE_CODS_DIR_FIELD "cods_dir"
#define SERVICE_TIMESHIFTS_DIR_FIELD "timeshifts_dir"
#define SERVICE_FEEDBACK_DIR_FIELD "feedback_dir"
#define SERVICE_PROXY_DIR_FIELD "proxy_dir"
#define SERVICE_DATA_DIR_FIELD "data_dir"
#define SERVICE_CODS_TTL_FIELD "cods_ttl"
#define SERVICE_FILES_TTL_FIELD "files_ttl"
#define SERVICE_PYFASTOSTREAM_PATH_FIELD "pyfastostream_path"
#define SERVICE_REPORT_NODE_STATS_FIELD "report_node_stats"
#define DUMMY_LOG_FILE_PATH "/dev/null"
#define REPORT_NODE_STATS 10
namespace {
common::Optional<std::pair<std::string, std::string>> GetKeyValue(const std::string& line, char separator) {
const size_t pos = line.find(separator);
if (pos != std::string::npos) {
const std::string key = line.substr(0, pos);
const std::string value = line.substr(pos + 1);
return std::make_pair(key, value);
}
return common::Optional<std::pair<std::string, std::string>>();
}
common::ErrnoError ReadConfigFile(const std::string& path, common::HashValue** args) {
if (!args) {
return common::make_errno_error_inval();
}
if (path.empty()) {
return common::make_errno_error("Invalid config path", EINVAL);
}
std::ifstream config(path);
if (!config.is_open()) {
return common::make_errno_error("Failed to open config file", EINVAL);
}
common::HashValue* options = new common::HashValue;
std::string line;
while (getline(config, line)) {
if (line == SETTINGS_SECTION) {
continue;
}
const auto kv = GetKeyValue(line, '=');
if (!kv) {
continue;
}
const auto pair = *kv;
if (pair.first == SERVICE_LOG_PATH_FIELD) {
options->Insert(pair.first, common::Value::CreateStringValueFromBasicString(pair.second));
} else if (pair.first == SERVICE_LOG_LEVEL_FIELD) {
options->Insert(pair.first, common::Value::CreateStringValueFromBasicString(pair.second));
} else if (pair.first == SERVICE_HOST_FIELD) {
options->Insert(pair.first, common::Value::CreateStringValueFromBasicString(pair.second));
} else if (pair.first == SERVICE_ALIAS_FIELD) {
options->Insert(pair.first, common::Value::CreateStringValueFromBasicString(pair.second));
} else if (pair.first == SERVICE_HLS_HOST_FIELD) {
options->Insert(pair.first, common::Value::CreateStringValueFromBasicString(pair.second));
} else if (pair.first == SERVICE_VODS_HOST_FIELD) {
options->Insert(pair.first, common::Value::CreateStringValueFromBasicString(pair.second));
} else if (pair.first == SERVICE_CODS_HOST_FIELD) {
options->Insert(pair.first, common::Value::CreateStringValueFromBasicString(pair.second));
} else if (pair.first == SERVICE_HLS_DIR_FIELD) {
options->Insert(pair.first, common::Value::CreateStringValueFromBasicString(pair.second));
} else if (pair.first == SERVICE_VODS_DIR_FIELD) {
options->Insert(pair.first, common::Value::CreateStringValueFromBasicString(pair.second));
} else if (pair.first == SERVICE_CODS_DIR_FIELD) {
options->Insert(pair.first, common::Value::CreateStringValueFromBasicString(pair.second));
} else if (pair.first == SERVICE_TIMESHIFTS_DIR_FIELD) {
options->Insert(pair.first, common::Value::CreateStringValueFromBasicString(pair.second));
} else if (pair.first == SERVICE_FEEDBACK_DIR_FIELD) {
options->Insert(pair.first, common::Value::CreateStringValueFromBasicString(pair.second));
} else if (pair.first == SERVICE_PROXY_DIR_FIELD) {
options->Insert(pair.first, common::Value::CreateStringValueFromBasicString(pair.second));
} else if (pair.first == SERVICE_DATA_DIR_FIELD) {
options->Insert(pair.first, common::Value::CreateStringValueFromBasicString(pair.second));
} else if (pair.first == SERVICE_PYFASTOSTREAM_PATH_FIELD) {
options->Insert(pair.first, common::Value::CreateStringValueFromBasicString(pair.second));
} else if (pair.first == SERVICE_CODS_TTL_FIELD) {
common::utctime_t ttl;
if (common::ConvertFromString(pair.second, &ttl)) {
options->Insert(pair.first, common::Value::CreateTimeValue(ttl));
}
} else if (pair.first == SERVICE_FILES_TTL_FIELD) {
common::utctime_t ttl;
if (common::ConvertFromString(pair.second, &ttl)) {
options->Insert(pair.first, common::Value::CreateTimeValue(ttl));
}
} else if (pair.first == SERVICE_REPORT_NODE_STATS_FIELD) {
common::utctime_t report;
if (common::ConvertFromString(pair.second, &report)) {
options->Insert(pair.first, common::Value::CreateTimeValue(report));
}
}
}
*args = options;
return common::ErrnoError();
}
} // namespace
namespace fastocloud {
namespace server {
Config::Config()
: host(GetDefaultHost()),
log_path(DUMMY_LOG_FILE_PATH),
log_level(common::logging::LOG_LEVEL_INFO),
hls_dir(STREAMER_SERVICE_HLS_DIR),
vods_dir(STREAMER_SERVICE_VODS_DIR),
cods_dir(STREAMER_SERVICE_CODS_DIR),
timeshifts_dir(STREAMER_SERVICE_TIMESHIFTS_DIR),
feedback_dir(STREAMER_SERVICE_FEEDBACK_DIR),
proxy_dir(STREAMER_SERVICE_PROXY_DIR),
data_dir(STREAMER_SERVICE_DATA_DIR),
pyfastostream_path(STREAMER_SERVICE_PYFASTOSTREAM_PATH),
cods_ttl(CODS_TTL),
files_ttl(FILES_TTL),
report_node(REPORT_NODE_STATS) {}
common::net::HostAndPort Config::GetDefaultHost() {
return common::net::HostAndPort::CreateLocalHostIPV4(CLIENT_PORT);
}
bool Config::IsValid() const {
return host.IsValid();
}
common::ErrnoError load_config_from_file(const std::string& config_absolute_path, Config* config) {
if (!config) {
return common::make_errno_error_inval();
}
Config lconfig;
common::HashValue* slave_config_args = nullptr;
common::ErrnoError err = ReadConfigFile(config_absolute_path, &slave_config_args);
if (err) {
return err;
}
common::Value* log_path_field = slave_config_args->Find(SERVICE_LOG_PATH_FIELD);
if (!log_path_field || !log_path_field->GetAsBasicString(&lconfig.log_path)) {
lconfig.log_path = DUMMY_LOG_FILE_PATH;
}
std::string level_str;
common::logging::LOG_LEVEL level = common::logging::LOG_LEVEL_INFO;
common::Value* level_field = slave_config_args->Find(SERVICE_LOG_LEVEL_FIELD);
if (level_field && level_field->GetAsBasicString(&level_str)) {
if (!common::logging::text_to_log_level(level_str.c_str(), &level)) {
level = common::logging::LOG_LEVEL_INFO;
}
}
lconfig.log_level = level;
common::Value* host_field = slave_config_args->Find(SERVICE_HOST_FIELD);
std::string host_str;
if (!host_field || !host_field->GetAsBasicString(&host_str) || !common::ConvertFromString(host_str, &lconfig.host)) {
lconfig.host = Config::GetDefaultHost();
}
common::Value* alias_field = slave_config_args->Find(SERVICE_ALIAS_FIELD);
if (!alias_field || !alias_field->GetAsBasicString(&lconfig.alias)) {
lconfig.alias = STREAMER_SERVICE_ALIAS;
}
common::Value* http_host_field = slave_config_args->Find(SERVICE_HLS_HOST_FIELD);
std::string http_host_str;
if (http_host_field && http_host_field->GetAsBasicString(&http_host_str)) {
common::uri::GURL gurl(http_host_str);
if (gurl.is_valid() && gurl.SchemeIsHTTPOrHTTPS()) {
lconfig.hls_host = gurl;
} else {
lconfig.hls_host = common::uri::GURL(SERVICE_HLS_HOST_FIELD);
}
}
common::Value* vods_host_field = slave_config_args->Find(SERVICE_VODS_HOST_FIELD);
std::string vods_host_str;
if (vods_host_field && vods_host_field->GetAsBasicString(&vods_host_str)) {
common::uri::GURL gurl(vods_host_str);
if (gurl.is_valid() && gurl.SchemeIsHTTPOrHTTPS()) {
lconfig.vods_host = gurl;
} else {
lconfig.vods_host = common::uri::GURL(SERVICE_VODS_HOST_FIELD);
}
}
common::Value* cods_host_field = slave_config_args->Find(SERVICE_CODS_HOST_FIELD);
std::string cods_host_str;
if (cods_host_field && cods_host_field->GetAsBasicString(&cods_host_str)) {
common::uri::GURL gurl(cods_host_str);
if (gurl.is_valid() && gurl.SchemeIsHTTPOrHTTPS()) {
lconfig.cods_host = gurl;
} else {
lconfig.cods_host = common::uri::GURL(SERVICE_CODS_HOST_FIELD);
}
}
common::Value* hls_field = slave_config_args->Find(SERVICE_HLS_DIR_FIELD);
if (!hls_field || !hls_field->GetAsBasicString(&lconfig.hls_dir)) {
lconfig.hls_dir = STREAMER_SERVICE_HLS_DIR;
}
lconfig.hls_dir = common::file_system::stable_dir_path(lconfig.hls_dir);
common::Value* vods_field = slave_config_args->Find(SERVICE_VODS_DIR_FIELD);
if (!vods_field || !vods_field->GetAsBasicString(&lconfig.vods_dir)) {
lconfig.vods_dir = STREAMER_SERVICE_VODS_DIR;
}
lconfig.vods_dir = common::file_system::stable_dir_path(lconfig.vods_dir);
common::Value* cods_field = slave_config_args->Find(SERVICE_CODS_DIR_FIELD);
if (!cods_field || !cods_field->GetAsBasicString(&lconfig.cods_dir)) {
lconfig.cods_dir = STREAMER_SERVICE_CODS_DIR;
}
lconfig.cods_dir = common::file_system::stable_dir_path(lconfig.cods_dir);
common::Value* timeshifts_field = slave_config_args->Find(SERVICE_TIMESHIFTS_DIR_FIELD);
if (!timeshifts_field || !timeshifts_field->GetAsBasicString(&lconfig.timeshifts_dir)) {
lconfig.timeshifts_dir = STREAMER_SERVICE_TIMESHIFTS_DIR;
}
lconfig.timeshifts_dir = common::file_system::stable_dir_path(lconfig.timeshifts_dir);
common::Value* feedback_field = slave_config_args->Find(SERVICE_FEEDBACK_DIR_FIELD);
if (!feedback_field || !feedback_field->GetAsBasicString(&lconfig.feedback_dir)) {
lconfig.feedback_dir = STREAMER_SERVICE_FEEDBACK_DIR;
}
lconfig.feedback_dir = common::file_system::stable_dir_path(lconfig.feedback_dir);
common::Value* proxy_field = slave_config_args->Find(SERVICE_PROXY_DIR_FIELD);
if (!proxy_field || !proxy_field->GetAsBasicString(&lconfig.proxy_dir)) {
lconfig.proxy_dir = STREAMER_SERVICE_PROXY_DIR;
}
lconfig.proxy_dir = common::file_system::stable_dir_path(lconfig.proxy_dir);
common::Value* data_field = slave_config_args->Find(SERVICE_DATA_DIR_FIELD);
if (!data_field || !data_field->GetAsBasicString(&lconfig.data_dir)) {
lconfig.data_dir = STREAMER_SERVICE_DATA_DIR;
}
lconfig.data_dir = common::file_system::stable_dir_path(lconfig.data_dir);
common::Value* PyFastoStream_field = slave_config_args->Find(SERVICE_PYFASTOSTREAM_PATH_FIELD);
if (!PyFastoStream_field || !PyFastoStream_field->GetAsBasicString(&lconfig.pyfastostream_path)) {
lconfig.pyfastostream_path = STREAMER_SERVICE_PYFASTOSTREAM_PATH;
}
lconfig.pyfastostream_path = common::file_system::prepare_path(lconfig.pyfastostream_path);
common::Value* cods_ttl_field = slave_config_args->Find(SERVICE_CODS_TTL_FIELD);
if (!cods_ttl_field || !cods_ttl_field->GetAsTime(&lconfig.cods_ttl)) {
lconfig.cods_ttl = CODS_TTL;
}
common::Value* files_ttl_field = slave_config_args->Find(SERVICE_FILES_TTL_FIELD);
if (!files_ttl_field || !files_ttl_field->GetAsTime(&lconfig.files_ttl)) {
lconfig.files_ttl = FILES_TTL;
}
common::Value* report_node_stats_field = slave_config_args->Find(SERVICE_REPORT_NODE_STATS_FIELD);
if (!report_node_stats_field || !report_node_stats_field->GetAsTime(&lconfig.report_node)) {
lconfig.report_node = REPORT_NODE_STATS;
}
*config = lconfig;
delete slave_config_args;
return common::ErrnoError();
}
} // namespace server
} // namespace fastocloud

63
src/server/config.h Normal file
View file

@ -0,0 +1,63 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <string>
#include <common/error.h>
#include <common/net/types.h>
#include <common/types.h>
#include <common/uri/gurl.h>
namespace fastocloud {
namespace server {
struct Config {
typedef common::utctime_t seconds_t;
Config();
static common::net::HostAndPort GetDefaultHost();
bool IsValid() const;
common::net::HostAndPort host;
std::string alias;
std::string log_path;
common::logging::LOG_LEVEL log_level;
// info
common::uri::GURL hls_host;
common::uri::GURL vods_host;
common::uri::GURL cods_host;
std::string hls_dir;
std::string vods_dir;
std::string cods_dir;
std::string timeshifts_dir;
std::string feedback_dir;
std::string proxy_dir;
std::string data_dir;
std::string pyfastostream_path;
seconds_t cods_ttl;
seconds_t files_ttl;
seconds_t report_node;
};
common::ErrnoError load_config_from_file(const std::string& config_absolute_path, Config* config) WARN_UNUSED_RESULT;
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,271 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include <memory>
#include "server/daemon/client.h"
#include "server/daemon/commands_factory.h"
namespace fastocloud {
namespace server {
ProtocoledDaemonClient::ProtocoledDaemonClient(common::libev::IoLoop* server, const common::net::socket_info& info)
: base_class(std::make_shared<fastotv::protocol::FastoTVCompressor>(), server, info) {}
common::ErrnoError ProtocoledDaemonClient::StopMe() {
const common::daemon::commands::StopInfo stop_req;
fastotv::protocol::request_t req;
common::Error err_ser = StopServiceRequest(NextRequestID(), stop_req, &req);
if (err_ser) {
return common::make_errno_error(err_ser->GetDescription(), EAGAIN);
}
return WriteRequest(req);
}
common::ErrnoError ProtocoledDaemonClient::RestartMe() {
const common::daemon::commands::RestartInfo stop_req;
fastotv::protocol::request_t req;
common::Error err_ser = RestartServiceRequest(NextRequestID(), stop_req, &req);
if (err_ser) {
return common::make_errno_error(err_ser->GetDescription(), EAGAIN);
}
return WriteRequest(req);
}
common::ErrnoError ProtocoledDaemonClient::StopFail(fastotv::protocol::sequance_id_t id, common::Error err) {
const std::string error_str = err->GetDescription();
fastotv::protocol::response_t resp;
common::Error err_ser = StopServiceResponseFail(id, error_str, &resp);
if (err_ser) {
return common::make_errno_error(err_ser->GetDescription(), EAGAIN);
}
return WriteResponse(resp);
}
common::ErrnoError ProtocoledDaemonClient::StopSuccess(fastotv::protocol::sequance_id_t id) {
fastotv::protocol::response_t resp;
common::Error err_ser = StopServiceResponseSuccess(id, &resp);
if (err_ser) {
return common::make_errno_error(err_ser->GetDescription(), EAGAIN);
}
return WriteResponse(resp);
}
common::ErrnoError ProtocoledDaemonClient::Ping() {
common::daemon::commands::ClientPingInfo server_ping_info;
return Ping(server_ping_info);
}
common::ErrnoError ProtocoledDaemonClient::Ping(const common::daemon::commands::ClientPingInfo& server_ping_info) {
fastotv::protocol::request_t ping_request;
common::Error err_ser = PingRequest(NextRequestID(), server_ping_info, &ping_request);
if (err_ser) {
return common::make_errno_error(err_ser->GetDescription(), EAGAIN);
}
return WriteRequest(ping_request);
}
common::ErrnoError ProtocoledDaemonClient::PongFail(fastotv::protocol::sequance_id_t id, common::Error err) {
const std::string error_str = err->GetDescription();
fastotv::protocol::response_t resp;
common::Error err_ser = PingServiceResponseFail(id, error_str, &resp);
if (err_ser) {
return common::make_errno_error(err_ser->GetDescription(), EAGAIN);
}
return WriteResponse(resp);
}
common::ErrnoError ProtocoledDaemonClient::Pong(fastotv::protocol::sequance_id_t id) {
common::daemon::commands::ServerPingInfo server_ping_info;
return Pong(id, server_ping_info);
}
common::ErrnoError ProtocoledDaemonClient::Pong(fastotv::protocol::sequance_id_t id,
const common::daemon::commands::ServerPingInfo& pong) {
fastotv::protocol::response_t resp;
common::Error err_ser = PingServiceResponseSuccess(id, pong, &resp);
if (err_ser) {
return common::make_errno_error(err_ser->GetDescription(), EAGAIN);
}
return WriteResponse(resp);
}
common::ErrnoError ProtocoledDaemonClient::ActivateFail(fastotv::protocol::sequance_id_t id, common::Error err) {
const std::string error_str = err->GetDescription();
fastotv::protocol::response_t resp;
common::Error err_ser = ActivateResponseFail(id, error_str, &resp);
if (err_ser) {
return common::make_errno_error(err_ser->GetDescription(), EAGAIN);
}
return WriteResponse(resp);
}
common::ErrnoError ProtocoledDaemonClient::ActivateSuccess(fastotv::protocol::sequance_id_t id,
const std::string& result) {
fastotv::protocol::response_t resp;
common::Error err_ser = ActivateResponseSuccess(id, result, &resp);
if (err_ser) {
return common::make_errno_error(err_ser->GetDescription(), EAGAIN);
}
return WriteResponse(resp);
}
common::ErrnoError ProtocoledDaemonClient::GetLogServiceFail(fastotv::protocol::sequance_id_t id, common::Error err) {
const std::string error_str = err->GetDescription();
fastotv::protocol::response_t resp;
common::Error err_ser = GetLogServiceResponseFail(id, error_str, &resp);
if (err_ser) {
return common::make_errno_error(err_ser->GetDescription(), EAGAIN);
}
return WriteResponse(resp);
}
common::ErrnoError ProtocoledDaemonClient::GetLogServiceSuccess(fastotv::protocol::sequance_id_t id) {
fastotv::protocol::response_t resp;
common::Error err_ser = GetLogServiceResponseSuccess(id, &resp);
if (err_ser) {
return common::make_errno_error(err_ser->GetDescription(), EAGAIN);
}
return WriteResponse(resp);
}
common::ErrnoError ProtocoledDaemonClient::GetLogStreamFail(fastotv::protocol::sequance_id_t id, common::Error err) {
const std::string error_str = err->GetDescription();
fastotv::protocol::response_t resp;
common::Error err_ser = GetLogStreamResponseFail(id, error_str, &resp);
if (err_ser) {
return common::make_errno_error(err_ser->GetDescription(), EAGAIN);
}
return WriteResponse(resp);
}
common::ErrnoError ProtocoledDaemonClient::GetLogStreamSuccess(fastotv::protocol::sequance_id_t id) {
fastotv::protocol::response_t resp;
common::Error err_ser = GetLogStreamResponseSuccess(id, &resp);
if (err_ser) {
return common::make_errno_error(err_ser->GetDescription(), EAGAIN);
}
return WriteResponse(resp);
}
common::ErrnoError ProtocoledDaemonClient::GetPipeStreamFail(fastotv::protocol::sequance_id_t id, common::Error err) {
const std::string error_str = err->GetDescription();
fastotv::protocol::response_t resp;
common::Error err_ser = GetPipeStreamResponseFail(id, error_str, &resp);
if (err_ser) {
return common::make_errno_error(err_ser->GetDescription(), EAGAIN);
}
return WriteResponse(resp);
}
common::ErrnoError ProtocoledDaemonClient::GetPipeStreamSuccess(fastotv::protocol::sequance_id_t id) {
fastotv::protocol::response_t resp;
common::Error err_ser = GetPipeStreamResponseSuccess(id, &resp);
if (err_ser) {
return common::make_errno_error(err_ser->GetDescription(), EAGAIN);
}
return WriteResponse(resp);
}
common::ErrnoError ProtocoledDaemonClient::StartStreamFail(fastotv::protocol::sequance_id_t id, common::Error err) {
const std::string error_str = err->GetDescription();
fastotv::protocol::response_t resp;
common::Error err_ser = StartStreamResponseFail(id, error_str, &resp);
if (err_ser) {
return common::make_errno_error(err_ser->GetDescription(), EAGAIN);
}
return WriteResponse(resp);
}
common::ErrnoError ProtocoledDaemonClient::StartStreamSuccess(fastotv::protocol::sequance_id_t id) {
fastotv::protocol::response_t resp;
common::Error err_ser = StartStreamResponseSuccess(id, &resp);
if (err_ser) {
return common::make_errno_error(err_ser->GetDescription(), EAGAIN);
}
return WriteResponse(resp);
}
common::ErrnoError ProtocoledDaemonClient::ReStartStreamFail(fastotv::protocol::sequance_id_t id, common::Error err) {
const std::string error_str = err->GetDescription();
fastotv::protocol::response_t resp;
common::Error err_ser = RestartStreamResponseFail(id, error_str, &resp);
if (err_ser) {
return common::make_errno_error(err_ser->GetDescription(), EAGAIN);
}
return WriteResponse(resp);
}
common::ErrnoError ProtocoledDaemonClient::ReStartStreamSuccess(fastotv::protocol::sequance_id_t id) {
fastotv::protocol::response_t resp;
common::Error err_ser = RestartStreamResponseSuccess(id, &resp);
if (err_ser) {
return common::make_errno_error(err_ser->GetDescription(), EAGAIN);
}
return WriteResponse(resp);
}
common::ErrnoError ProtocoledDaemonClient::StopStreamFail(fastotv::protocol::sequance_id_t id, common::Error err) {
const std::string error_str = err->GetDescription();
fastotv::protocol::response_t resp;
common::Error err_ser = StopStreamResponseFail(id, error_str, &resp);
if (err_ser) {
return common::make_errno_error(err_ser->GetDescription(), EAGAIN);
}
return WriteResponse(resp);
}
common::ErrnoError ProtocoledDaemonClient::StopStreamSuccess(fastotv::protocol::sequance_id_t id) {
fastotv::protocol::response_t resp;
common::Error err_ser = StopStreamResponseSuccess(id, &resp);
if (err_ser) {
return common::make_errno_error(err_ser->GetDescription(), EAGAIN);
}
return WriteResponse(resp);
}
common::ErrnoError ProtocoledDaemonClient::UnknownMethodError(fastotv::protocol::sequance_id_t id,
const std::string& method) {
fastotv::protocol::response_t resp;
common::Error err_ser = UnknownMethodResponse(id, method, &resp);
if (err_ser) {
return common::make_errno_error(err_ser->GetDescription(), EAGAIN);
}
return WriteResponse(resp);
}
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,75 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <string>
#include <common/daemon/client.h>
#include <common/daemon/commands/license_info.h>
#include <common/daemon/commands/ping_info.h>
#include <common/license/types.h>
#include <fastotv/protocol/protocol.h>
#include <fastotv/protocol/types.h>
namespace fastocloud {
namespace server {
class ProtocoledDaemonClient : public fastotv::protocol::ProtocolClient<common::daemon::DaemonClient> {
public:
typedef fastotv::protocol::ProtocolClient<common::daemon::DaemonClient> base_class;
ProtocoledDaemonClient(common::libev::IoLoop* server, const common::net::socket_info& info);
common::ErrnoError StopMe() WARN_UNUSED_RESULT;
common::ErrnoError RestartMe() WARN_UNUSED_RESULT;
common::ErrnoError StopFail(fastotv::protocol::sequance_id_t id, common::Error err) WARN_UNUSED_RESULT;
common::ErrnoError StopSuccess(fastotv::protocol::sequance_id_t id) WARN_UNUSED_RESULT;
common::ErrnoError Ping() WARN_UNUSED_RESULT;
common::ErrnoError Ping(const common::daemon::commands::ClientPingInfo& server_ping_info) WARN_UNUSED_RESULT;
common::ErrnoError PongFail(fastotv::protocol::sequance_id_t id, common::Error err) WARN_UNUSED_RESULT;
common::ErrnoError Pong(fastotv::protocol::sequance_id_t id) WARN_UNUSED_RESULT;
common::ErrnoError Pong(fastotv::protocol::sequance_id_t id,
const common::daemon::commands::ServerPingInfo& pong) WARN_UNUSED_RESULT;
common::ErrnoError ActivateFail(fastotv::protocol::sequance_id_t id, common::Error err) WARN_UNUSED_RESULT;
common::ErrnoError ActivateSuccess(fastotv::protocol::sequance_id_t id, const std::string& result) WARN_UNUSED_RESULT;
common::ErrnoError GetLogServiceFail(fastotv::protocol::sequance_id_t id, common::Error err) WARN_UNUSED_RESULT;
common::ErrnoError GetLogServiceSuccess(fastotv::protocol::sequance_id_t id) WARN_UNUSED_RESULT;
common::ErrnoError GetLogStreamFail(fastotv::protocol::sequance_id_t id, common::Error err) WARN_UNUSED_RESULT;
common::ErrnoError GetLogStreamSuccess(fastotv::protocol::sequance_id_t id) WARN_UNUSED_RESULT;
common::ErrnoError GetPipeStreamFail(fastotv::protocol::sequance_id_t id, common::Error err) WARN_UNUSED_RESULT;
common::ErrnoError GetPipeStreamSuccess(fastotv::protocol::sequance_id_t id) WARN_UNUSED_RESULT;
common::ErrnoError StartStreamFail(fastotv::protocol::sequance_id_t id, common::Error err) WARN_UNUSED_RESULT;
common::ErrnoError StartStreamSuccess(fastotv::protocol::sequance_id_t id) WARN_UNUSED_RESULT;
common::ErrnoError ReStartStreamFail(fastotv::protocol::sequance_id_t id, common::Error err) WARN_UNUSED_RESULT;
common::ErrnoError ReStartStreamSuccess(fastotv::protocol::sequance_id_t id) WARN_UNUSED_RESULT;
common::ErrnoError StopStreamFail(fastotv::protocol::sequance_id_t id, common::Error err) WARN_UNUSED_RESULT;
common::ErrnoError StopStreamSuccess(fastotv::protocol::sequance_id_t id) WARN_UNUSED_RESULT;
common::ErrnoError UnknownMethodError(fastotv::protocol::sequance_id_t id,
const std::string& method) WARN_UNUSED_RESULT;
};
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,94 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/daemon/commands.h"
namespace fastocloud {
namespace server {
common::Error ChangedSourcesStreamBroadcast(const ChangedSouresInfo& params, fastotv::protocol::request_t* req) {
if (!req) {
return common::make_error_inval();
}
std::string changed_json;
common::Error err_ser = params.SerializeToString(&changed_json);
if (err_ser) {
return err_ser;
}
*req = fastotv::protocol::request_t::MakeNotification(STREAM_CHANGED_SOURCES_STREAM, changed_json);
return common::Error();
}
common::Error StatisitcStreamBroadcast(const StatisticInfo& params, fastotv::protocol::request_t* req) {
if (!req) {
return common::make_error_inval();
}
std::string stat_json;
common::Error err_ser = params.SerializeToString(&stat_json);
if (err_ser) {
return err_ser;
}
*req = fastotv::protocol::request_t::MakeNotification(STREAM_STATISTIC_STREAM, stat_json);
return common::Error();
}
#if defined(MACHINE_LEARNING)
common::Error MlNotificationStreamBroadcast(const fastotv::commands_info::ml::NotificationInfo& params,
fastotv::protocol::request_t* req) {
if (!req) {
return common::make_error_inval();
}
std::string stat_json;
common::Error err_ser = params.SerializeToString(&stat_json);
if (err_ser) {
return err_ser;
}
*req = fastotv::protocol::request_t::MakeNotification(STREAM_ML_NOTIFICATION_STREAM, stat_json);
return common::Error();
}
#endif
common::Error StatisitcServiceBroadcast(fastotv::protocol::serializet_params_t params,
fastotv::protocol::request_t* req) {
if (!req) {
return common::make_error_inval();
}
*req = fastotv::protocol::request_t::MakeNotification(STREAM_STATISTIC_SERVICE, params);
return common::Error();
}
common::Error QuitStatusStreamBroadcast(const stream::QuitStatusInfo& params, fastotv::protocol::request_t* req) {
if (!req) {
return common::make_error_inval();
}
std::string quit_json;
common::Error err_ser = params.SerializeToString(&quit_json);
if (err_ser) {
return err_ser;
}
*req = fastotv::protocol::request_t::MakeNotification(STREAM_QUIT_STATUS_STREAM, quit_json);
return common::Error();
}
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,72 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <string>
#include <fastotv/protocol/types.h>
#if defined(MACHINE_LEARNING)
#include <fastotv/commands_info/ml/notification_info.h>
#endif
#include "server/daemon/commands_info/stream/quit_status_info.h"
#include "stream_commands/commands_info/changed_sources_info.h"
#include "stream_commands/commands_info/statistic_info.h"
// daemon
// client commands
#define DAEMON_START_STREAM "start_stream" // {"config": {...}, "command_line": {...} }
#define DAEMON_STOP_STREAM "stop_stream"
#define DAEMON_RESTART_STREAM "restart_stream"
#define DAEMON_GET_LOG_STREAM "get_log_stream"
#define DAEMON_GET_PIPELINE_STREAM "get_pipeline_stream"
#define DAEMON_ACTIVATE "activate_request" // {"key": "XXXXXXXXXXXXXXXXXX"}
#define DAEMON_STOP_SERVICE "stop_service" // {"delay": 0 }
#define DAEMON_RESTART_SERVICE "restart_service" // {"delay": 0 }
#define DAEMON_GET_CONFIG_JSON_STREAM "get_config_json_stream"
#define DAEMON_PING_SERVICE "ping_service"
#define DAEMON_GET_LOG_SERVICE "get_log_service" // {"path":"http://localhost/service/id"}
#define DAEMON_SERVER_PING "ping_client"
// Broadcast
#define STREAM_CHANGED_SOURCES_STREAM "changed_source_stream"
#define STREAM_STATISTIC_STREAM "statistic_stream"
#define STREAM_QUIT_STATUS_STREAM "quit_status_stream"
#if defined(MACHINE_LEARNING)
#define STREAM_ML_NOTIFICATION_STREAM "ml_notification_stream"
#endif
#define STREAM_STATISTIC_SERVICE "statistic_service"
namespace fastocloud {
namespace server {
// Broadcast
common::Error ChangedSourcesStreamBroadcast(const ChangedSouresInfo& params, fastotv::protocol::request_t* req);
common::Error StatisitcStreamBroadcast(const StatisticInfo& params, fastotv::protocol::request_t* req);
#if defined(MACHINE_LEARNING)
common::Error MlNotificationStreamBroadcast(const fastotv::commands_info::ml::NotificationInfo& params,
fastotv::protocol::request_t* req);
#endif
common::Error StatisitcServiceBroadcast(fastotv::protocol::serializet_params_t params,
fastotv::protocol::request_t* req);
common::Error QuitStatusStreamBroadcast(const stream::QuitStatusInfo& params, fastotv::protocol::request_t* req);
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,311 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/daemon/commands_factory.h"
#include <common/sprintf.h>
#include "server/daemon/commands.h"
namespace fastocloud {
namespace server {
common::Error StopServiceRequest(fastotv::protocol::sequance_id_t id,
const common::daemon::commands::StopInfo& params,
fastotv::protocol::request_t* req) {
if (!req) {
return common::make_error_inval();
}
std::string req_str;
common::Error err_ser = params.SerializeToString(&req_str);
if (err_ser) {
return err_ser;
}
fastotv::protocol::request_t lreq;
lreq.id = id;
lreq.method = DAEMON_STOP_SERVICE;
lreq.params = req_str;
*req = lreq;
return common::Error();
}
common::Error RestartServiceRequest(fastotv::protocol::sequance_id_t id,
const common::daemon::commands::RestartInfo& params,
fastotv::protocol::request_t* req) {
if (!req) {
return common::make_error_inval();
}
std::string req_str;
common::Error err_ser = params.SerializeToString(&req_str);
if (err_ser) {
return err_ser;
}
fastotv::protocol::request_t lreq;
lreq.id = id;
lreq.method = DAEMON_RESTART_SERVICE;
lreq.params = req_str;
*req = lreq;
return common::Error();
}
common::Error PingRequest(fastotv::protocol::sequance_id_t id,
const common::daemon::commands::ClientPingInfo& params,
fastotv::protocol::request_t* req) {
if (!req) {
return common::make_error_inval();
}
std::string req_str;
common::Error err_ser = params.SerializeToString(&req_str);
if (err_ser) {
return err_ser;
}
fastotv::protocol::request_t lreq;
lreq.id = id;
lreq.method = DAEMON_SERVER_PING;
lreq.params = req_str;
*req = lreq;
return common::Error();
}
common::Error StopServiceResponseSuccess(fastotv::protocol::sequance_id_t id, fastotv::protocol::response_t* resp) {
if (!resp) {
return common::make_error_inval();
}
*resp =
fastotv::protocol::response_t::MakeMessage(id, common::protocols::json_rpc::JsonRPCMessage::MakeSuccessMessage());
return common::Error();
}
common::Error StopServiceResponseFail(fastotv::protocol::sequance_id_t id,
const std::string& error_text,
fastotv::protocol::response_t* resp) {
if (!resp) {
return common::make_error_inval();
}
*resp = fastotv::protocol::response_t::MakeError(
id, common::protocols::json_rpc::JsonRPCError::MakeServerErrorFromText(error_text));
return common::Error();
}
common::Error GetLogServiceResponseSuccess(fastotv::protocol::sequance_id_t id, fastotv::protocol::response_t* resp) {
if (!resp) {
return common::make_error_inval();
}
*resp =
fastotv::protocol::response_t::MakeMessage(id, common::protocols::json_rpc::JsonRPCMessage::MakeSuccessMessage());
return common::Error();
}
common::Error GetLogServiceResponseFail(fastotv::protocol::sequance_id_t id,
const std::string& error_text,
fastotv::protocol::response_t* resp) {
if (!resp) {
return common::make_error_inval();
}
*resp = fastotv::protocol::response_t::MakeError(
id, common::protocols::json_rpc::JsonRPCError::MakeServerErrorFromText(error_text));
return common::Error();
}
common::Error ActivateResponseSuccess(fastotv::protocol::sequance_id_t id,
const std::string& result,
fastotv::protocol::response_t* resp) {
if (!resp) {
return common::make_error_inval();
}
*resp = fastotv::protocol::response_t::MakeMessage(
id, common::protocols::json_rpc::JsonRPCMessage::MakeSuccessMessage(result));
return common::Error();
}
common::Error ActivateResponseFail(fastotv::protocol::sequance_id_t id,
const std::string& error_text,
fastotv::protocol::response_t* resp) {
if (!resp) {
return common::make_error_inval();
}
*resp = fastotv::protocol::response_t::MakeError(
id, common::protocols::json_rpc::JsonRPCError::MakeServerErrorFromText(error_text));
return common::Error();
}
common::Error StartStreamResponseSuccess(fastotv::protocol::sequance_id_t id, fastotv::protocol::response_t* resp) {
if (!resp) {
return common::make_error_inval();
}
*resp =
fastotv::protocol::response_t::MakeMessage(id, common::protocols::json_rpc::JsonRPCMessage::MakeSuccessMessage());
return common::Error();
}
common::Error StartStreamResponseFail(fastotv::protocol::sequance_id_t id,
const std::string& error_text,
fastotv::protocol::response_t* resp) {
if (!resp) {
return common::make_error_inval();
}
*resp = fastotv::protocol::response_t::MakeError(
id, common::protocols::json_rpc::JsonRPCError::MakeServerErrorFromText(error_text));
return common::Error();
}
common::Error StopStreamResponseSuccess(fastotv::protocol::sequance_id_t id, fastotv::protocol::response_t* resp) {
if (!resp) {
return common::make_error_inval();
}
*resp =
fastotv::protocol::response_t::MakeMessage(id, common::protocols::json_rpc::JsonRPCMessage::MakeSuccessMessage());
return common::Error();
}
common::Error StopStreamResponseFail(fastotv::protocol::sequance_id_t id,
const std::string& error_text,
fastotv::protocol::response_t* resp) {
if (!resp) {
return common::make_error_inval();
}
*resp = fastotv::protocol::response_t::MakeError(
id, common::protocols::json_rpc::JsonRPCError::MakeServerErrorFromText(error_text));
return common::Error();
}
common::Error RestartStreamResponseSuccess(fastotv::protocol::sequance_id_t id, fastotv::protocol::response_t* resp) {
if (!resp) {
return common::make_error_inval();
}
*resp =
fastotv::protocol::response_t::MakeMessage(id, common::protocols::json_rpc::JsonRPCMessage::MakeSuccessMessage());
return common::Error();
}
common::Error RestartStreamResponseFail(fastotv::protocol::sequance_id_t id,
const std::string& error_text,
fastotv::protocol::response_t* resp) {
if (!resp) {
return common::make_error_inval();
}
*resp = fastotv::protocol::response_t::MakeError(
id, common::protocols::json_rpc::JsonRPCError::MakeServerErrorFromText(error_text));
return common::Error();
}
common::Error GetLogStreamResponseSuccess(fastotv::protocol::sequance_id_t id, fastotv::protocol::response_t* resp) {
if (!resp) {
return common::make_error_inval();
}
*resp =
fastotv::protocol::response_t::MakeMessage(id, common::protocols::json_rpc::JsonRPCMessage::MakeSuccessMessage());
return common::Error();
}
common::Error GetLogStreamResponseFail(fastotv::protocol::sequance_id_t id,
const std::string& error_text,
fastotv::protocol::response_t* resp) {
if (!resp) {
return common::make_error_inval();
}
*resp = fastotv::protocol::response_t::MakeError(
id, common::protocols::json_rpc::JsonRPCError::MakeServerErrorFromText(error_text));
return common::Error();
}
common::Error GetPipeStreamResponseSuccess(fastotv::protocol::sequance_id_t id, fastotv::protocol::response_t* resp) {
if (!resp) {
return common::make_error_inval();
}
*resp =
fastotv::protocol::response_t::MakeMessage(id, common::protocols::json_rpc::JsonRPCMessage::MakeSuccessMessage());
return common::Error();
}
common::Error GetPipeStreamResponseFail(fastotv::protocol::sequance_id_t id,
const std::string& error_text,
fastotv::protocol::response_t* resp) {
if (!resp) {
return common::make_error_inval();
}
*resp = fastotv::protocol::response_t::MakeError(
id, common::protocols::json_rpc::JsonRPCError::MakeServerErrorFromText(error_text));
return common::Error();
}
common::Error PingServiceResponseSuccess(fastotv::protocol::sequance_id_t id,
const common::daemon::commands::ServerPingInfo& ping,
fastotv::protocol::response_t* resp) {
if (!resp) {
return common::make_error_inval();
}
std::string ping_server_json;
common::Error err_ser = ping.SerializeToString(&ping_server_json);
if (err_ser) {
return err_ser;
}
*resp = fastotv::protocol::response_t::MakeMessage(
id, common::protocols::json_rpc::JsonRPCMessage::MakeSuccessMessage(ping_server_json));
return common::Error();
}
common::Error PingServiceResponseFail(fastotv::protocol::sequance_id_t id,
const std::string& error_text,
fastotv::protocol::response_t* resp) {
if (!resp) {
return common::make_error_inval();
}
*resp = fastotv::protocol::response_t::MakeError(
id, common::protocols::json_rpc::JsonRPCError::MakeServerErrorFromText(error_text));
return common::Error();
}
common::Error UnknownMethodResponse(fastotv::protocol::sequance_id_t id,
const std::string& method,
fastotv::protocol::response_t* resp) {
if (!resp) {
return common::make_error_inval();
}
*resp =
fastotv::protocol::response_t::MakeError(id, common::protocols::json_rpc::JsonRPCError::MakeServerErrorFromText(
common::MemSPrintf("Unknown method: %s", method)));
return common::Error();
}
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,96 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <string>
#include <common/daemon/commands/activate_info.h>
#include <common/daemon/commands/ping_info.h>
#include <common/daemon/commands/restart_info.h>
#include <common/daemon/commands/stop_info.h>
#include <fastotv/protocol/types.h>
namespace fastocloud {
namespace server {
// requests
common::Error StopServiceRequest(fastotv::protocol::sequance_id_t id,
const common::daemon::commands::StopInfo& params,
fastotv::protocol::request_t* req);
common::Error RestartServiceRequest(fastotv::protocol::sequance_id_t id,
const common::daemon::commands::RestartInfo& params,
fastotv::protocol::request_t* req);
common::Error PingRequest(fastotv::protocol::sequance_id_t id,
const common::daemon::commands::ClientPingInfo& params,
fastotv::protocol::request_t* req);
// responses service
common::Error StopServiceResponseSuccess(fastotv::protocol::sequance_id_t id, fastotv::protocol::response_t* resp);
common::Error StopServiceResponseFail(fastotv::protocol::sequance_id_t id,
const std::string& error_text,
fastotv::protocol::response_t* resp);
common::Error GetLogServiceResponseSuccess(fastotv::protocol::sequance_id_t id, fastotv::protocol::response_t* resp);
common::Error GetLogServiceResponseFail(fastotv::protocol::sequance_id_t id,
const std::string& error_text,
fastotv::protocol::response_t* resp);
common::Error ActivateResponseSuccess(fastotv::protocol::sequance_id_t id,
const std::string& result,
fastotv::protocol::response_t* resp);
common::Error ActivateResponseFail(fastotv::protocol::sequance_id_t id,
const std::string& error_text,
fastotv::protocol::response_t* resp);
common::Error PingServiceResponseSuccess(fastotv::protocol::sequance_id_t id,
const common::daemon::commands::ServerPingInfo& ping,
fastotv::protocol::response_t* resp);
common::Error PingServiceResponseFail(fastotv::protocol::sequance_id_t id,
const std::string& error_text,
fastotv::protocol::response_t* resp);
common::Error UnknownMethodResponse(fastotv::protocol::sequance_id_t id,
const std::string& method,
fastotv::protocol::response_t* resp) WARN_UNUSED_RESULT;
// responces streams
common::Error StartStreamResponseSuccess(fastotv::protocol::sequance_id_t id, fastotv::protocol::response_t* resp);
common::Error StartStreamResponseFail(fastotv::protocol::sequance_id_t id,
const std::string& error_text,
fastotv::protocol::response_t* resp);
common::Error StopStreamResponseSuccess(fastotv::protocol::sequance_id_t id, fastotv::protocol::response_t* resp);
common::Error StopStreamResponseFail(fastotv::protocol::sequance_id_t id,
const std::string& error_text,
fastotv::protocol::response_t* resp);
common::Error RestartStreamResponseSuccess(fastotv::protocol::sequance_id_t id, fastotv::protocol::response_t* resp);
common::Error RestartStreamResponseFail(fastotv::protocol::sequance_id_t id,
const std::string& error_text,
fastotv::protocol::response_t* resp);
common::Error GetLogStreamResponseSuccess(fastotv::protocol::sequance_id_t id, fastotv::protocol::response_t* resp);
common::Error GetLogStreamResponseFail(fastotv::protocol::sequance_id_t id,
const std::string& error_text,
fastotv::protocol::response_t* resp);
common::Error GetPipeStreamResponseSuccess(fastotv::protocol::sequance_id_t id, fastotv::protocol::response_t* resp);
common::Error GetPipeStreamResponseFail(fastotv::protocol::sequance_id_t id,
const std::string& error_text,
fastotv::protocol::response_t* resp);
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,216 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/daemon/commands_info/service/details/shots.h"
#include <inttypes.h>
#include <string.h>
#include <sys/stat.h>
#include <string>
#if defined(OS_LINUX)
#include <sys/sysinfo.h>
#endif
#if defined(OS_MACOSX)
#include <mach/mach.h>
#endif
#if defined(OS_WIN)
#include <windows.h>
#endif
#if defined(OS_MACOSX) || defined(OS_FREEBSD)
#include <sys/resource.h>
#include <sys/sysctl.h>
#endif
#include <common/system_info/system_info.h>
#include <common/time.h>
#define CPU_FORMAT "cpu %" PRIu64 " %" PRIu64 " %" PRIu64 " %" PRIu64
#if defined(OS_WIN)
namespace {
uint64_t FiletimeToInt(const FILETIME& ft) {
ULARGE_INTEGER i;
i.LowPart = ft.dwLowDateTime;
i.HighPart = ft.dwHighDateTime;
return i.QuadPart;
}
} // namespace
#endif
namespace fastocloud {
namespace server {
namespace service {
double GetCpuMachineLoad(const CpuShot& prev, const CpuShot& next) {
double total = next.cpu_limit - prev.cpu_limit;
if (total == 0.0) {
return 0;
}
double busy = next.cpu_usage - prev.cpu_usage;
return (busy / total) * 100;
}
CpuShot GetMachineCpuShot() {
uint64_t busy = 0, total = 0;
#if defined(OS_LINUX)
FILE* fp = fopen("/proc/stat", "r");
uint64_t user, nice, system, idle;
if (fscanf(fp, CPU_FORMAT, &user, &nice, &system, &idle) != 4) {
// Something bad happened with the information, so assume it's all invalid
user = nice = system = idle = 0;
}
fclose(fp);
busy = user + nice + system;
total = busy + idle;
#elif defined(OS_MACOSX)
host_cpu_load_info_data_t cpuinfo;
mach_msg_type_number_t count = HOST_CPU_LOAD_INFO_COUNT;
if (host_statistics(mach_host_self(), HOST_CPU_LOAD_INFO, (host_info_t)&cpuinfo, &count) == KERN_SUCCESS) {
for (int i = 0; i < CPU_STATE_MAX; i++) {
total += cpuinfo.cpu_ticks[i];
}
busy = total - cpuinfo.cpu_ticks[CPU_STATE_IDLE];
}
#elif defined(OS_WINDOWS)
FILETIME idle, kernel, user;
if (GetSystemTimes(&idle, &kernel, &user) != 0) {
total = FiletimeToInt(kernel) + FiletimeToInt(user);
busy = total - FiletimeToInt(idle);
}
#else
#pragma message "Please implement"
#endif
return {busy, total};
}
MemoryShot::MemoryShot() : ram_bytes_total(0), ram_bytes_free(0) {}
MemoryShot GetMachineMemoryShot() {
MemoryShot shot;
const auto total = common::system_info::AmountOfTotalRAM();
if (total) {
shot.ram_bytes_total = *total;
}
const auto avail = common::system_info::AmountOfAvailableRAM();
if (avail) {
shot.ram_bytes_free = *avail;
}
return shot;
}
HddShot::HddShot() : hdd_bytes_total(0), hdd_bytes_free(0) {}
HddShot GetMachineHddShot() {
HddShot sh;
const auto total = common::system_info::AmountOfTotalDiskSpace("/");
if (total) {
sh.hdd_bytes_total = *total;
}
const auto avail = common::system_info::AmountOfFreeDiskSpace("/");
if (avail) {
sh.hdd_bytes_free = *avail;
}
return sh;
}
NetShot::NetShot() : bytes_recv(0), bytes_send(0) {}
NetShot GetMachineNetShot() {
NetShot shot;
#if defined(OS_LINUX)
FILE* netinfo = fopen("/proc/net/dev", "r");
if (!netinfo) {
return shot;
}
char line[512];
char interf[128] = {0};
int pos = 0;
while (fgets(line, sizeof(line), netinfo)) {
// face |bytes packets errs drop fifo frame compressed multicast|
// bytes packets errs drop fifo colls carrier compressed
if (pos > 1) {
unsigned long long int r_bytes, r_packets, r_errs, r_drop, r_fifo, r_frame, r_compressed, r_multicast;
unsigned long long int s_bytes, s_packets, s_errs, s_drop, s_fifo, s_colls, s_carrier, s_compressed;
sscanf(line,
"%s %16llu %16llu %16llu %16llu %16llu %16llu %16llu %16llu "
"%16llu %16llu %16llu "
"%16llu %16llu %16llu %16llu %16llu",
interf, &r_bytes, &r_packets, &r_errs, &r_drop, &r_fifo, &r_frame, &r_compressed, &r_multicast, &s_bytes,
&s_packets, &s_errs, &s_drop, &s_fifo, &s_colls, &s_carrier, &s_compressed);
if (strncmp(interf, "lo", 2) != 0) {
shot.bytes_recv += r_bytes;
shot.bytes_send += s_bytes;
}
memset(interf, 0, sizeof(interf));
}
pos++;
}
fclose(netinfo);
return shot;
#else
#pragma message "Please implement"
return shot;
#endif
}
SysinfoShot::SysinfoShot() : loads{0}, uptime(0) {}
SysinfoShot GetMachineSysinfoShot() {
SysinfoShot inf;
#if defined(OS_LINUX)
struct sysinfo info;
int res = sysinfo(&info);
if (res == ERROR_RESULT_VALUE) {
return inf;
}
memcpy(&inf.loads, &info.loads, sizeof(unsigned long) * SIZEOFMASS(info.loads));
inf.uptime = info.uptime;
return inf;
#elif defined(OS_MACOSX) || defined(OS_FREEBSD)
struct loadavg load;
size_t load_len = sizeof(load);
if (sysctlbyname("vm.loadavg", &load, &load_len, nullptr, 0) < 0) {
return inf;
}
inf.loads[0] = load.ldavg[0] / load.fscale;
inf.loads[1] = load.ldavg[1] / load.fscale;
inf.loads[2] = load.ldavg[2] / load.fscale;
struct timeval boottime;
size_t boottime_len = sizeof(boottime);
if (sysctlbyname("kern.boottime", &boottime, &boottime_len, nullptr, 0) < 0) {
return inf;
}
inf.uptime = (common::time::current_utc_mstime() - common::time::timeval2mstime(&boottime)) / 1000;
return inf;
#else
#pragma message "Please implement"
return inf;
#endif
}
} // namespace service
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,71 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <stdint.h>
#include <common/error.h>
namespace fastocloud {
namespace server {
namespace service {
struct CpuShot {
uint64_t cpu_usage;
uint64_t cpu_limit;
};
double GetCpuMachineLoad(const CpuShot& prev, const CpuShot& next);
CpuShot GetMachineCpuShot();
struct MemoryShot {
MemoryShot();
size_t ram_bytes_total;
size_t ram_bytes_free;
};
MemoryShot GetMachineMemoryShot();
struct HddShot {
HddShot();
size_t hdd_bytes_total;
size_t hdd_bytes_free;
};
HddShot GetMachineHddShot();
struct NetShot {
NetShot();
size_t bytes_recv;
size_t bytes_send;
};
NetShot GetMachineNetShot();
struct SysinfoShot {
SysinfoShot();
unsigned long loads[3];
time_t uptime;
};
SysinfoShot GetMachineSysinfoShot();
} // namespace service
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,298 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/daemon/commands_info/service/server_info.h"
#include <string>
#include <common/system_info/system_info.h>
#define ONLINE_USERS_FIELD "online_users"
#define OS_FIELD "os"
#define PROJECT_FIELD "project"
#define VERSION_FIELD "version"
#define HLS_HOST_FIELD "hls_host"
#define VODS_HOST_FIELD "vods_host"
#define CODS_HOST_FIELD "cods_host"
#define EXPIRATION_TIME_FIELD "expiration_time"
#define VSYSTEM_FIELD "vsystem"
#define VROLE_FIELD "vrole"
#define HLS_DIR_FIELD "hls_dir"
#define VODS_DIR_FIELD "vods_dir"
#define CODS_DIR_FIELD "cods_dir"
#define TIMESHIFTS_DIR_FIELD "timeshifts_dir"
#define FEEDBACK_DIR_FIELD "feedback_dir"
#define DATA_DIR_FIELD "data_dir"
#define ONLINE_USERS_DAEMON_FIELD "daemon"
#define ONLINE_USERS_HTTP_FIELD "http"
#define ONLINE_USERS_VODS_FIELD "vods"
#define ONLINE_USERS_CODS_FIELD "cods"
namespace fastocloud {
namespace server {
namespace service {
OnlineUsers::OnlineUsers() : OnlineUsers(0, 0, 0, 0) {}
OnlineUsers::OnlineUsers(size_t daemon, size_t http, size_t vods, size_t cods)
: daemon_(daemon), http_(http), vods_(vods), cods_(cods) {}
common::Error OnlineUsers::DoDeSerialize(json_object* serialized) {
uint64_t daemon;
ignore_result(GetUint64Field(serialized, ONLINE_USERS_DAEMON_FIELD, &daemon));
uint64_t http;
ignore_result(GetUint64Field(serialized, ONLINE_USERS_HTTP_FIELD, &http));
uint64_t vods;
ignore_result(GetUint64Field(serialized, ONLINE_USERS_VODS_FIELD, &vods));
uint64_t cods;
ignore_result(GetUint64Field(serialized, ONLINE_USERS_CODS_FIELD, &cods));
*this = OnlineUsers(daemon, http, vods, cods);
return common::Error();
}
common::Error OnlineUsers::SerializeFields(json_object* out) const {
ignore_result(SetUInt64Field(out, ONLINE_USERS_DAEMON_FIELD, daemon_));
ignore_result(SetUInt64Field(out, ONLINE_USERS_HTTP_FIELD, http_));
ignore_result(SetUInt64Field(out, ONLINE_USERS_VODS_FIELD, vods_));
ignore_result(SetUInt64Field(out, ONLINE_USERS_CODS_FIELD, cods_));
return common::Error();
}
ServerInfo::ServerInfo() : base_class(), online_users_() {}
ServerInfo::ServerInfo(cpu_load_t cpu_load,
gpu_load_t gpu_load,
const std::string& load_average,
size_t ram_bytes_total,
size_t ram_bytes_free,
size_t hdd_bytes_total,
size_t hdd_bytes_free,
fastotv::bandwidth_t net_bytes_recv,
fastotv::bandwidth_t net_bytes_send,
time_t uptime,
fastotv::timestamp_t timestamp,
const OnlineUsers& online_users,
size_t net_total_bytes_recv,
size_t net_total_bytes_send)
: base_class(cpu_load,
gpu_load,
load_average,
ram_bytes_total,
ram_bytes_free,
hdd_bytes_total,
hdd_bytes_free,
net_bytes_recv,
net_bytes_send,
uptime,
timestamp,
net_total_bytes_recv,
net_total_bytes_send),
online_users_(online_users) {}
common::Error ServerInfo::SerializeFields(json_object* out) const {
common::Error err = base_class::SerializeFields(out);
if (err) {
return err;
}
json_object* obj = nullptr;
err = online_users_.Serialize(&obj);
if (err) {
return err;
}
ignore_result(SetObjectField(out, ONLINE_USERS_FIELD, obj));
return common::Error();
}
common::Error ServerInfo::DoDeSerialize(json_object* serialized) {
ServerInfo inf;
common::Error err = inf.base_class::DoDeSerialize(serialized);
if (err) {
return err;
}
json_object* jonline = nullptr;
json_bool jonline_exists = json_object_object_get_ex(serialized, ONLINE_USERS_FIELD, &jonline);
if (jonline_exists) {
common::Error err = inf.online_users_.DeSerialize(jonline);
if (err) {
return err;
}
}
*this = inf;
return common::Error();
}
OnlineUsers ServerInfo::GetOnlineUsers() const {
return online_users_;
}
FullServiceInfo::FullServiceInfo()
: base_class(),
http_host_(),
project_(PROJECT_NAME_LOWERCASE),
proj_ver_(PROJECT_VERSION_HUMAN),
os_(fastotv::commands_info::OperationSystemInfo::MakeOSSnapshot()),
vsystem_(common::system_info::VirtualizationSystem()),
vrole_(common::system_info::VirtualizationRole()) {}
FullServiceInfo::FullServiceInfo(const host_t& http_host,
const host_t& vods_host,
const host_t& cods_host,
common::time64_t exp_time,
const std::string& hls_dir,
const std::string& vods_dir,
const std::string& cods_dir,
const std::string& timeshifts_dir,
const std::string& feedback_dir,
const std::string& proxy_dir,
const std::string& data_dir,
const base_class& base)
: base_class(base),
http_host_(http_host),
vods_host_(vods_host),
cods_host_(cods_host),
exp_time_(exp_time),
hls_dir_(hls_dir),
vods_dir_(vods_dir),
cods_dir_(cods_dir),
timeshifts_dir_(timeshifts_dir),
feedback_dir_(feedback_dir),
proxy_dir_(proxy_dir),
data_dir_(data_dir),
project_(PROJECT_NAME_LOWERCASE),
proj_ver_(PROJECT_VERSION_HUMAN),
os_(fastotv::commands_info::OperationSystemInfo::MakeOSSnapshot()),
vsystem_(common::system_info::VirtualizationSystem()),
vrole_(common::system_info::VirtualizationRole()) {}
FullServiceInfo::host_t FullServiceInfo::GetHttpHost() const {
return http_host_;
}
FullServiceInfo::host_t FullServiceInfo::GetVodsHost() const {
return vods_host_;
}
FullServiceInfo::host_t FullServiceInfo::GetCodsHost() const {
return cods_host_;
}
std::string FullServiceInfo::GetProject() const {
return project_;
}
std::string FullServiceInfo::GetProjectVersion() const {
return proj_ver_;
}
std::string FullServiceInfo::GetVsystem() const {
return vsystem_;
}
std::string FullServiceInfo::GetVrole() const {
return vrole_;
}
common::Error FullServiceInfo::DoDeSerialize(json_object* serialized) {
FullServiceInfo inf;
common::Error err = inf.base_class::DoDeSerialize(serialized);
if (err) {
return err;
}
json_object* jos;
err = GetObjectField(serialized, OS_FIELD, &jos);
if (!err) {
common::Error err = inf.os_.DeSerialize(jos);
if (err) {
return err;
}
}
std::string http_host;
err = GetStringField(serialized, HLS_HOST_FIELD, &http_host);
if (!err) {
inf.http_host_ = host_t(http_host);
}
std::string vods_host;
err = GetStringField(serialized, VODS_HOST_FIELD, &vods_host);
if (!err) {
inf.vods_host_ = host_t(vods_host);
}
std::string cods_host;
err = GetStringField(serialized, CODS_HOST_FIELD, &cods_host);
if (!err) {
inf.cods_host_ = host_t(cods_host);
}
ignore_result(GetInt64Field(serialized, EXPIRATION_TIME_FIELD, &inf.exp_time_));
ignore_result(GetStringField(serialized, HLS_DIR_FIELD, &inf.hls_dir_));
ignore_result(GetStringField(serialized, VODS_DIR_FIELD, &inf.vods_dir_));
ignore_result(GetStringField(serialized, CODS_DIR_FIELD, &inf.cods_dir_));
ignore_result(GetStringField(serialized, TIMESHIFTS_DIR_FIELD, &inf.timeshifts_dir_));
ignore_result(GetStringField(serialized, FEEDBACK_DIR_FIELD, &inf.feedback_dir_));
ignore_result(GetStringField(serialized, DATA_DIR_FIELD, &inf.data_dir_));
ignore_result(GetStringField(serialized, PROJECT_FIELD, &inf.project_));
ignore_result(GetStringField(serialized, VERSION_FIELD, &inf.proj_ver_));
ignore_result(GetStringField(serialized, VSYSTEM_FIELD, &inf.vsystem_));
ignore_result(GetStringField(serialized, VROLE_FIELD, &inf.vrole_));
*this = inf;
return common::Error();
}
common::Error FullServiceInfo::SerializeFields(json_object* out) const {
json_object* jos = nullptr;
common::Error err = os_.Serialize(&jos);
if (err) {
return err;
}
std::string http_host_str = http_host_.spec();
std::string vods_host_str = vods_host_.spec();
std::string cods_host_str = cods_host_.spec();
ignore_result(SetStringField(out, HLS_HOST_FIELD, http_host_str));
ignore_result(SetStringField(out, VODS_HOST_FIELD, vods_host_str));
ignore_result(SetStringField(out, CODS_HOST_FIELD, cods_host_str));
ignore_result(SetInt64Field(out, EXPIRATION_TIME_FIELD, exp_time_));
ignore_result(SetStringField(out, HLS_DIR_FIELD, hls_dir_));
ignore_result(SetStringField(out, VODS_DIR_FIELD, vods_dir_));
ignore_result(SetStringField(out, CODS_DIR_FIELD, cods_dir_));
ignore_result(SetStringField(out, TIMESHIFTS_DIR_FIELD, timeshifts_dir_));
ignore_result(SetStringField(out, FEEDBACK_DIR_FIELD, feedback_dir_));
ignore_result(SetStringField(out, DATA_DIR_FIELD, data_dir_));
ignore_result(SetStringField(out, VERSION_FIELD, proj_ver_));
ignore_result(SetStringField(out, PROJECT_FIELD, project_));
ignore_result(SetObjectField(out, OS_FIELD, jos));
ignore_result(SetStringField(out, VSYSTEM_FIELD, vsystem_));
ignore_result(SetStringField(out, VROLE_FIELD, vrole_));
return base_class::SerializeFields(out);
}
} // namespace service
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,130 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <fastotv/commands_info/machine_info.h>
#include <common/uri/gurl.h>
#include <string>
namespace fastocloud {
namespace server {
namespace service {
class OnlineUsers : public common::serializer::JsonSerializer<OnlineUsers> {
public:
typedef JsonSerializer<OnlineUsers> base_class;
OnlineUsers();
explicit OnlineUsers(size_t daemon, size_t http, size_t vods, size_t cods);
protected:
common::Error DoDeSerialize(json_object* serialized) override;
common::Error SerializeFields(json_object* out) const override;
private:
size_t daemon_;
size_t http_;
size_t vods_;
size_t cods_;
};
class ServerInfo : public fastotv::commands_info::MachineInfo {
public:
typedef fastotv::commands_info::MachineInfo base_class;
ServerInfo();
ServerInfo(cpu_load_t cpu_load,
gpu_load_t gpu_load,
const std::string& load_average,
size_t ram_bytes_total,
size_t ram_bytes_free,
size_t hdd_bytes_total,
size_t hdd_bytes_free,
fastotv::bandwidth_t net_bytes_recv,
fastotv::bandwidth_t net_bytes_send,
time_t uptime,
fastotv::timestamp_t timestamp,
const OnlineUsers& online_users,
size_t net_total_bytes_recv,
size_t net_total_bytes_send);
OnlineUsers GetOnlineUsers() const;
protected:
common::Error DoDeSerialize(json_object* serialized) override;
common::Error SerializeFields(json_object* out) const override;
private:
OnlineUsers online_users_;
};
class FullServiceInfo : public ServerInfo {
public:
typedef ServerInfo base_class;
typedef common::uri::GURL host_t;
FullServiceInfo();
explicit FullServiceInfo(const host_t& http_host,
const host_t& vods_host,
const host_t& cods_host,
common::time64_t exp_time,
const std::string& hls_dir,
const std::string& vods_dir,
const std::string& cods_dir,
const std::string& timeshifts_dir,
const std::string& feedback_dir,
const std::string& proxy_dir,
const std::string& data_dir,
const base_class& base);
host_t GetHttpHost() const;
host_t GetVodsHost() const;
host_t GetCodsHost() const;
std::string GetProject() const;
std::string GetProjectVersion() const;
std::string GetVsystem() const;
std::string GetVrole() const;
protected:
common::Error DoDeSerialize(json_object* serialized) override;
common::Error SerializeFields(json_object* out) const override;
private:
host_t http_host_;
host_t vods_host_;
host_t cods_host_;
common::time64_t exp_time_;
std::string hls_dir_;
std::string vods_dir_;
std::string cods_dir_;
std::string timeshifts_dir_;
std::string feedback_dir_;
std::string proxy_dir_;
std::string data_dir_;
std::string project_;
std::string proj_ver_;
fastotv::commands_info::OperationSystemInfo os_;
std::string vsystem_;
std::string vrole_;
};
} // namespace service
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,73 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/daemon/commands_info/stream/get_log_info.h"
#include <string>
#define PATH_FIELD "path"
#define FEEDBACK_DIR_FIELD "feedback_directory"
namespace fastocloud {
namespace server {
namespace stream {
GetLogInfo::GetLogInfo() : base_class(), feedback_dir_(), path_() {}
GetLogInfo::GetLogInfo(const fastotv::stream_id_t& stream_id, const std::string& feedback_dir, const url_t& path)
: base_class(stream_id), feedback_dir_(feedback_dir), path_(path) {}
GetLogInfo::url_t GetLogInfo::GetLogPath() const {
return path_;
}
std::string GetLogInfo::GetFeedbackDir() const {
return feedback_dir_;
}
common::Error GetLogInfo::DoDeSerialize(json_object* serialized) {
GetLogInfo inf;
common::Error err = inf.base_class::DoDeSerialize(serialized);
if (err) {
return err;
}
std::string feedback_dir;
err = GetStringField(serialized, FEEDBACK_DIR_FIELD, &feedback_dir);
if (err) {
return err;
}
inf.feedback_dir_ = feedback_dir;
std::string path;
err = GetStringField(serialized, PATH_FIELD, &path);
if (err) {
return err;
}
inf.path_ = url_t(path);
*this = inf;
return common::Error();
}
common::Error GetLogInfo::SerializeFields(json_object* out) const {
const std::string path_str = path_.spec();
ignore_result(SetStringField(out, PATH_FIELD, path_str));
ignore_result(SetStringField(out, FEEDBACK_DIR_FIELD, feedback_dir_));
return base_class::SerializeFields(out);
}
} // namespace stream
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,52 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <string>
#include <common/uri/gurl.h>
#include "server/daemon/commands_info/stream/stream_info.h"
namespace fastocloud {
namespace server {
namespace stream {
class GetLogInfo : public StreamInfo {
public:
typedef StreamInfo base_class;
typedef common::uri::GURL url_t;
GetLogInfo();
explicit GetLogInfo(const fastotv::stream_id_t& stream_id, const std::string& feedback_dir, const url_t& log_path);
url_t GetLogPath() const;
std::string GetFeedbackDir() const;
protected:
common::Error DoDeSerialize(json_object* serialized) override;
common::Error SerializeFields(json_object* out) const override;
private:
std::string feedback_dir_;
url_t path_;
};
typedef GetLogInfo GetPipelineInfo;
typedef GetLogInfo GetConfigJsonInfo;
} // namespace stream
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,70 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/daemon/commands_info/stream/quit_status_info.h"
#define QUIT_STATUS_INFO_SIGNAL_FIELD "signal"
#define QUIT_STATUS_INFO_EXIT_STATUS_FIELD "exit_status"
namespace fastocloud {
namespace server {
namespace stream {
QuitStatusInfo::QuitStatusInfo() : base_class(), exit_status_(), signal_() {}
QuitStatusInfo::QuitStatusInfo(fastotv::stream_id_t stream_id, int exit_status, int signal)
: base_class(stream_id), exit_status_(exit_status), signal_(signal) {}
int QuitStatusInfo::GetSignal() const {
return signal_;
}
int QuitStatusInfo::GetExitStatus() const {
return exit_status_;
}
common::Error QuitStatusInfo::DoDeSerialize(json_object* serialized) {
QuitStatusInfo inf;
common::Error err = inf.base_class::DoDeSerialize(serialized);
if (err) {
return err;
}
int sig;
err = GetIntField(serialized, QUIT_STATUS_INFO_SIGNAL_FIELD, &sig);
if (err) {
return err;
}
int exit_status;
err = GetIntField(serialized, QUIT_STATUS_INFO_EXIT_STATUS_FIELD, &exit_status);
if (err) {
return err;
}
inf.signal_ = sig;
inf.exit_status_ = exit_status;
*this = inf;
return common::Error();
}
common::Error QuitStatusInfo::SerializeFields(json_object* out) const {
ignore_result(SetIntField(out, QUIT_STATUS_INFO_SIGNAL_FIELD, signal_));
ignore_result(SetIntField(out, QUIT_STATUS_INFO_EXIT_STATUS_FIELD, exit_status_));
return base_class::SerializeFields(out);
}
} // namespace stream
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,44 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "server/daemon/commands_info/stream/stream_info.h"
namespace fastocloud {
namespace server {
namespace stream {
class QuitStatusInfo : public StreamInfo {
public:
typedef StreamInfo base_class;
QuitStatusInfo();
explicit QuitStatusInfo(fastotv::stream_id_t stream_id, int exit_status, int signal);
int GetSignal() const;
int GetExitStatus() const;
protected:
common::Error DoDeSerialize(json_object* serialized) override;
common::Error SerializeFields(json_object* out) const override;
private:
int exit_status_;
int signal_;
};
} // namespace stream
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,27 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/daemon/commands_info/stream/restart_info.h"
namespace fastocloud {
namespace server {
namespace stream {
RestartInfo::RestartInfo() : base_class() {}
RestartInfo::RestartInfo(const fastotv::stream_id_t& stream_id) : base_class(stream_id) {}
} // namespace stream
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,33 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "server/daemon/commands_info/stream/stream_info.h"
namespace fastocloud {
namespace server {
namespace stream {
class RestartInfo : public StreamInfo {
public:
typedef StreamInfo base_class;
RestartInfo();
explicit RestartInfo(const fastotv::stream_id_t& stream_id);
};
} // namespace stream
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,64 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/daemon/commands_info/stream/start_info.h"
#include "base/stream_config_parse.h"
#define START_INFO_CONFIG_FIELD "config"
namespace fastocloud {
namespace server {
namespace stream {
StartInfo::StartInfo() : base_class(), config_() {}
StartInfo::StartInfo(const config_t& config) : config_(config) {}
StartInfo::config_t StartInfo::GetConfig() const {
return config_;
}
common::Error StartInfo::DoDeSerialize(json_object* serialized) {
if (!serialized) {
return common::make_error_inval();
}
json_object* jconfig;
common::Error err = GetObjectField(serialized, START_INFO_CONFIG_FIELD, &jconfig);
if (err) {
return err;
}
config_t conf = MakeConfigFromJson(jconfig);
if (!conf) {
return common::make_error_inval();
}
*this = StartInfo(conf);
return common::Error();
}
common::Error StartInfo::SerializeFields(json_object*) const {
if (!config_) {
return common::make_error_inval();
}
NOTREACHED() << "Not need";
return common::Error();
}
} // namespace stream
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,44 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <common/serializer/json_serializer.h>
#include "base/stream_config.h"
namespace fastocloud {
namespace server {
namespace stream {
class StartInfo : public common::serializer::JsonSerializer<StartInfo> {
public:
typedef common::serializer::JsonSerializer<StartInfo> base_class;
typedef StreamConfig config_t;
StartInfo();
explicit StartInfo(const config_t& config);
config_t GetConfig() const;
protected:
common::Error DoDeSerialize(json_object* serialized) override;
common::Error SerializeFields(json_object* out) const override;
private:
config_t config_;
};
} // namespace stream
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,56 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/daemon/commands_info/stream/stop_info.h"
#define FORCE_FIELD "force"
namespace fastocloud {
namespace server {
namespace stream {
StopInfo::StopInfo() : base_class(), force_(false) {}
StopInfo::StopInfo(const fastotv::stream_id_t& stream_id, bool force) : base_class(stream_id), force_(force) {}
bool StopInfo::GetForce() const {
return force_;
}
common::Error StopInfo::DoDeSerialize(json_object* serialized) {
StopInfo res;
common::Error err = res.base_class::DoDeSerialize(serialized);
if (err) {
return err;
}
bool force;
err = GetBoolField(serialized, FORCE_FIELD, &force);
if (err) {
return err;
}
res.force_ = force;
*this = res;
return common::Error();
}
common::Error StopInfo::SerializeFields(json_object* out) const {
ignore_result(SetBoolField(out, FORCE_FIELD, force_));
return base_class::SerializeFields(out);
}
} // namespace stream
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,41 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "server/daemon/commands_info/stream/stream_info.h"
namespace fastocloud {
namespace server {
namespace stream {
class StopInfo : public StreamInfo {
public:
typedef StreamInfo base_class;
StopInfo();
explicit StopInfo(const fastotv::stream_id_t& stream_id, bool force);
bool GetForce() const;
protected:
common::Error DoDeSerialize(json_object* serialized) override;
common::Error SerializeFields(json_object* out) const override;
private:
bool force_;
};
} // namespace stream
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,49 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/daemon/commands_info/stream/stream_info.h"
#define ID_FIELD "id"
namespace fastocloud {
namespace server {
namespace stream {
StreamInfo::StreamInfo() : base_class(), stream_id_() {}
StreamInfo::StreamInfo(const fastotv::stream_id_t& stream_id) : stream_id_(stream_id) {}
fastotv::stream_id_t StreamInfo::GetStreamID() const {
return stream_id_;
}
common::Error StreamInfo::DoDeSerialize(json_object* serialized) {
fastotv::stream_id_t sid;
common::Error err = GetStringField(serialized, ID_FIELD, &sid);
if (err) {
return err;
}
*this = StreamInfo(sid);
return common::Error();
}
common::Error StreamInfo::SerializeFields(json_object* out) const {
ignore_result(SetStringField(out, ID_FIELD, stream_id_));
return common::Error();
}
} // namespace stream
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,45 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <string>
#include <common/serializer/json_serializer.h>
#include <fastotv/types.h>
namespace fastocloud {
namespace server {
namespace stream {
class StreamInfo : public common::serializer::JsonSerializer<StreamInfo> {
public:
typedef JsonSerializer<StreamInfo> base_class;
StreamInfo();
explicit StreamInfo(const fastotv::stream_id_t& stream_id);
std::string GetStreamID() const;
protected:
common::Error DoDeSerialize(json_object* serialized) override;
common::Error SerializeFields(json_object* out) const override;
private:
fastotv::stream_id_t stream_id_;
};
} // namespace stream
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,31 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/daemon/server.h"
#include "server/daemon/client.h"
namespace fastocloud {
namespace server {
DaemonServer::DaemonServer(const common::net::HostAndPort& host, common::libev::IoLoopObserver* observer)
: base_class(new common::net::ServerSocketEvTcp(host), true, observer) {}
common::libev::tcp::TcpClient* DaemonServer::CreateClient(const common::net::socket_info& info, void* user) {
UNUSED(user);
return new ProtocoledDaemonClient(this, info);
}
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,32 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <common/daemon/server.h>
namespace fastocloud {
namespace server {
class DaemonServer : public common::daemon::DaemonServer {
public:
typedef common::daemon::DaemonServer base_class;
explicit DaemonServer(const common::net::HostAndPort& host, common::libev::IoLoopObserver* observer = nullptr);
private:
common::libev::tcp::TcpClient* CreateClient(const common::net::socket_info& info, void* user) override;
};
} // namespace server
} // namespace fastocloud

207
src/server/daemon_slave.cpp Normal file
View file

@ -0,0 +1,207 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include <unistd.h>
#if defined(OS_WIN)
#include <winsock2.h>
#else
#include <signal.h>
#endif
#include <common/file_system/file.h>
#include <common/file_system/file_system.h>
#include <common/file_system/string_path_utils.h>
#include <iostream>
#if defined(OS_POSIX)
#include <common/utils.h>
#endif
#include "server/process_slave_wrapper.h"
#define HELP_TEXT \
"Usage: " STREAMER_SERVICE_NAME \
" [option]\n\n" \
" --version display version\n" \
" --daemon run as a daemon\n" \
" --reload restart service\n" \
" --stop stop service\n"
namespace {
#if defined(OS_WIN)
struct WinsockInit {
WinsockInit() {
WSADATA d;
if (WSAStartup(0x202, &d) != 0) {
_exit(1);
}
}
~WinsockInit() { WSACleanup(); }
} winsock_init;
#else
struct SigIgnInit {
SigIgnInit() { signal(SIGPIPE, SIG_IGN); }
} sig_init;
#endif
const size_t kMaxSizeLogFile = 10 * 1024 * 1024; // 10 MB
} // namespace
int main(int argc, char** argv, char** envp) {
bool run_as_daemon = false;
for (int i = 1; i < argc; ++i) {
if (strcmp(argv[i], "--version") == 0) {
std::cout << PROJECT_VERSION_HUMAN << std::endl;
return EXIT_SUCCESS;
} else if (strcmp(argv[i], "--daemon") == 0) {
run_as_daemon = true;
} else if (strcmp(argv[i], "--stop") == 0) {
fastocloud::server::Config config;
common::ErrnoError err = fastocloud::server::load_config_from_file(CONFIG_PATH, &config);
if (err) {
std::cerr << "Can't read config, file path: " << CONFIG_PATH << ", error: " << err->GetDescription()
<< std::endl;
return EXIT_FAILURE;
}
err = fastocloud::server::ProcessSlaveWrapper::SendStopDaemonRequest(config);
sleep(fastocloud::server::ProcessSlaveWrapper::cleanup_seconds + 1);
if (err) {
std::cerr << "Stop command failed error: " << err->GetDescription() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
} else if (strcmp(argv[i], "--reload") == 0) {
fastocloud::server::Config config;
common::ErrnoError err = fastocloud::server::load_config_from_file(CONFIG_PATH, &config);
if (err) {
std::cerr << "Can't read config, file path: " << CONFIG_PATH << ", error: " << err->GetDescription()
<< std::endl;
return EXIT_FAILURE;
}
err = fastocloud::server::ProcessSlaveWrapper::SendRestartDaemonRequest(config);
sleep(fastocloud::server::ProcessSlaveWrapper::cleanup_seconds + 1);
if (err) {
std::cerr << "Reload command failed error: " << err->GetDescription() << std::endl;
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
} else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
std::cout << HELP_TEXT << std::endl;
return EXIT_SUCCESS;
} else {
std::cerr << HELP_TEXT << std::endl;
return EXIT_FAILURE;
}
}
if (run_as_daemon) {
#if defined(OS_POSIX)
if (!common::create_as_daemon()) {
return EXIT_FAILURE;
}
#endif
}
int res = EXIT_FAILURE;
while (true) {
fastocloud::server::Config config;
common::ErrnoError err = fastocloud::server::load_config_from_file(CONFIG_PATH, &config);
if (err) {
std::cerr << "Can't read config, file path: " << CONFIG_PATH << ", error: " << err->GetDescription() << std::endl;
return EXIT_FAILURE;
}
common::logging::INIT_LOGGER(STREAMER_SERVICE_NAME, config.log_path, config.log_level,
kMaxSizeLogFile); // initialization of logging system
const pid_t daemon_pid = getpid();
const std::string folder_path_to_pid = common::file_system::get_dir_path(PIDFILE_PATH);
if (folder_path_to_pid.empty()) {
ERROR_LOG() << "Can't get pid file path: " << PIDFILE_PATH;
return EXIT_FAILURE;
}
if (!common::file_system::is_directory_exist(folder_path_to_pid)) {
common::ErrnoError errn = common::file_system::create_directory(folder_path_to_pid, true);
if (errn) {
ERROR_LOG() << "Pid file directory not exists, pid file path: " << PIDFILE_PATH;
return EXIT_FAILURE;
}
}
err = common::file_system::node_access(folder_path_to_pid);
if (err) {
ERROR_LOG() << "Can't have permissions to create, pid file path: " << PIDFILE_PATH;
return EXIT_FAILURE;
}
common::file_system::File pidfile;
err = pidfile.Open(PIDFILE_PATH, common::file_system::File::FLAG_CREATE | common::file_system::File::FLAG_WRITE);
if (err) {
ERROR_LOG() << "Can't open pid file path: " << PIDFILE_PATH;
return EXIT_FAILURE;
}
err = pidfile.Lock();
if (err) {
ERROR_LOG() << "Can't lock pid file path: " << PIDFILE_PATH << "; message: " << err->GetDescription();
return EXIT_FAILURE;
}
const std::string pid_str = common::MemSPrintf("%ld\n", static_cast<long>(daemon_pid));
size_t writed;
err = pidfile.WriteBuffer(pid_str, &writed);
if (err) {
ERROR_LOG() << "Failed to write pid file path: " << PIDFILE_PATH << "; message: " << err->GetDescription();
return EXIT_FAILURE;
}
// start
fastocloud::server::ProcessSlaveWrapper wrapper(config);
NOTICE_LOG() << "Running " PROJECT_VERSION_HUMAN << " in " << (run_as_daemon ? "daemon" : "common") << " mode";
for (char** env = envp; *env != nullptr; env++) {
char* cur_env = *env;
DEBUG_LOG() << cur_env;
}
res = wrapper.Exec(argc, argv);
NOTICE_LOG() << "Quiting " PROJECT_VERSION_HUMAN;
err = pidfile.Unlock();
if (err) {
ERROR_LOG() << "Failed to unlock pidfile: " << PIDFILE_PATH << "; message: " << err->GetDescription();
return EXIT_FAILURE;
}
err = pidfile.Close();
if (err) {
ERROR_LOG() << "Failed to close pidfile: " << PIDFILE_PATH << "; message: " << err->GetDescription();
return EXIT_FAILURE;
}
err = common::file_system::remove_file(PIDFILE_PATH);
if (err) {
WARNING_LOG() << "Can't remove file: " << PIDFILE_PATH << ", error: " << err->GetDescription();
}
if (wrapper.IsStoped()) {
break;
}
}
return res;
}

View file

@ -0,0 +1,116 @@
/* Copyright (C) 2014-2018 FastoGT. All right reserved.
This file is part of iptv_cloud.
iptv_cloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
iptv_cloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with iptv_cloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/gpu_stats/intel_monitor.h"
#include <string.h>
#include <cttmetrics.h>
#define METRIC_TIMEOUT_MSEC 1000
namespace fastocloud {
namespace server {
namespace gpu_stats {
IntelMonitor::IntelMonitor(double* load) : load_(load), stop_mutex_(), stop_cond_(), stop_flag_(false) {}
IntelMonitor::~IntelMonitor() {}
bool IntelMonitor::IsGpuAvailable() {
cttStatus status = CTTMetrics_Init(nullptr);
if (CTT_ERR_NONE != status) {
return false;
}
CTTMetrics_Close();
return true;
}
bool IntelMonitor::Exec() {
if (!load_) {
return false;
}
cttStatus status = CTTMetrics_Init(nullptr);
if (CTT_ERR_NONE != status) {
return false;
}
cttMetric metrics_ids[] = {CTT_USAGE_RENDER};
static const unsigned int metric_cnt = sizeof(metrics_ids) / sizeof(metrics_ids[0]);
static const unsigned int num_samples = 100;
static const unsigned int period_ms = METRIC_TIMEOUT_MSEC;
unsigned int metric_all_cnt = 0;
status = CTTMetrics_GetMetricCount(&metric_all_cnt);
if (CTT_ERR_NONE != status) {
CTTMetrics_Close();
return false;
}
cttMetric metric_all_ids[CTT_MAX_METRIC_COUNT] = {CTT_WRONG_METRIC_ID};
status = CTTMetrics_GetMetricInfo(metric_all_cnt, metric_all_ids);
if (CTT_ERR_NONE != status) {
CTTMetrics_Close();
return false;
}
status = CTTMetrics_Subscribe(metric_cnt, metrics_ids);
if (CTT_ERR_NONE != status) {
CTTMetrics_Close();
return false;
}
status = CTTMetrics_SetSampleCount(num_samples);
if (CTT_ERR_NONE != status) {
CTTMetrics_Close();
return false;
}
status = CTTMetrics_SetSamplePeriod(period_ms);
if (CTT_ERR_NONE != status) {
CTTMetrics_Close();
return false;
}
float metric_values[metric_cnt];
memset(metric_values, 0, (size_t)metric_cnt * sizeof(float));
std::unique_lock<std::mutex> lock(stop_mutex_);
while (!stop_flag_) {
status = CTTMetrics_GetValue(metric_cnt, metric_values);
if (CTT_ERR_NONE != status) {
break;
}
*load_ = metric_values[0];
std::cv_status interrupt_status = stop_cond_.wait_for(lock, std::chrono::seconds(1));
if (interrupt_status == std::cv_status::no_timeout) { // if notify
if (stop_flag_) {
break;
}
}
}
CTTMetrics_Close();
return true;
}
void IntelMonitor::Stop() {
std::unique_lock<std::mutex> lock(stop_mutex_);
stop_flag_ = true;
stop_cond_.notify_one();
}
} // namespace gpu_stats
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,44 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <condition_variable>
#include "server/gpu_stats/perf_monitor.h"
namespace fastocloud {
namespace server {
namespace gpu_stats {
class IntelMonitor : public IPerfMonitor {
public:
explicit IntelMonitor(double* load);
~IntelMonitor() override;
bool Exec() override;
void Stop() override;
static bool IsGpuAvailable();
private:
double* load_;
std::mutex stop_mutex_;
std::condition_variable stop_cond_;
bool stop_flag_;
};
} // namespace gpu_stats
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,104 @@
/* Copyright (C) 2014-2017 FastoGT. All right reserved.
This file is part of iptv_cloud.
iptv_cloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
iptv_cloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with iptv_cloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/gpu_stats/nvidia_monitor.h"
#include <nvml.h>
namespace fastocloud {
namespace server {
namespace gpu_stats {
NvidiaMonitor::NvidiaMonitor(double* load) : load_(load), stop_mutex_(), stop_cond_(), stop_flag_(false) {}
NvidiaMonitor::~NvidiaMonitor() {}
bool NvidiaMonitor::IsGpuAvailable() {
nvmlReturn_t ret = nvmlInit();
if (ret != NVML_SUCCESS) {
return false;
}
unsigned devices_num = 0;
ret = nvmlDeviceGetCount(&devices_num);
if (ret != NVML_SUCCESS || devices_num == 0) {
nvmlShutdown();
return false;
}
nvmlShutdown();
return true;
}
bool NvidiaMonitor::Exec() {
if (!load_) {
return false;
}
nvmlReturn_t ret = nvmlInit();
if (ret != NVML_SUCCESS) {
return false;
}
unsigned devices_num = 0;
ret = nvmlDeviceGetCount(&devices_num);
if (ret != NVML_SUCCESS || devices_num == 0) {
nvmlShutdown();
return false;
}
std::unique_lock<std::mutex> lock(stop_mutex_);
while (!stop_flag_) {
uint64_t total_enc = 0, total_dec = 0;
for (unsigned i = 0; i != devices_num; ++i) {
unsigned enc, dec, enc_sampling, dec_sampling;
nvmlDevice_t device;
ret = nvmlDeviceGetHandleByIndex(i, &device);
if (ret != NVML_SUCCESS) {
continue;
}
ret = nvmlDeviceGetDecoderUtilization(device, &dec, &dec_sampling);
if (ret != NVML_SUCCESS) {
continue;
}
ret = nvmlDeviceGetEncoderUtilization(device, &enc, &enc_sampling);
if (ret != NVML_SUCCESS) {
continue;
}
total_dec += dec;
total_enc += enc;
}
*load_ = static_cast<double>(total_dec + total_enc) / static_cast<double>(devices_num * 2); // 2 because enc + dec
std::cv_status interrupt_status = stop_cond_.wait_for(lock, std::chrono::seconds(1));
if (interrupt_status == std::cv_status::no_timeout) { // if notify
if (stop_flag_) {
break;
}
}
}
nvmlShutdown();
return true;
}
void NvidiaMonitor::Stop() {
std::unique_lock<std::mutex> lock(stop_mutex_);
stop_flag_ = true;
stop_cond_.notify_one();
}
} // namespace gpu_stats
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,44 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <condition_variable>
#include "server/gpu_stats/perf_monitor.h"
namespace fastocloud {
namespace server {
namespace gpu_stats {
class NvidiaMonitor : public IPerfMonitor {
public:
explicit NvidiaMonitor(double* load);
~NvidiaMonitor() override;
bool Exec() override;
void Stop() override;
static bool IsGpuAvailable();
private:
double* load_;
std::mutex stop_mutex_;
std::condition_variable stop_cond_;
bool stop_flag_;
};
} // namespace gpu_stats
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,83 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/gpu_stats/perf_monitor.h"
#include <common/macros.h>
#ifdef HAVE_NVML
#include "server/gpu_stats/nvidia_monitor.h"
#endif
#ifdef HAVE_CTT_METRICS
#include "server/gpu_stats/intel_monitor.h"
#endif
#define MAX_LEN 1024
namespace {
bool IsNvidiaGpuAvailable() {
#ifdef HAVE_NVML
return fastocloud::server::gpu_stats::NvidiaMonitor::IsGpuAvailable();
#else
return false;
#endif
}
bool IsIntelGpuAvailable() {
#ifdef HAVE_CTT_METRICS
return fastocloud::server::gpu_stats::IntelMonitor::IsGpuAvailable();
#else
return false;
#endif
}
} // namespace
namespace fastocloud {
namespace server {
namespace gpu_stats {
IPerfMonitor::~IPerfMonitor() {}
IPerfMonitor* CreateNvidiaPerfMonitor(double* load) {
#if !defined(HAVE_NVML) && !defined(HAVE_CTT_METRICS)
UNUSED(load);
#endif
if (IsNvidiaGpuAvailable()) {
#if defined(HAVE_NVML)
return new NvidiaMonitor(load);
#else
return nullptr;
#endif
}
return nullptr;
}
IPerfMonitor* CreateIntelPerfMonitor(double* load) {
#if !defined(HAVE_NVML) && !defined(HAVE_CTT_METRICS)
UNUSED(load);
#endif
if (IsIntelGpuAvailable()) {
#if defined(HAVE_CTT_METRICS)
return new IntelMonitor(load);
#else
return nullptr;
#endif
}
return nullptr;
}
} // namespace gpu_stats
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,34 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
namespace fastocloud {
namespace server {
namespace gpu_stats {
class IPerfMonitor {
public:
virtual ~IPerfMonitor();
virtual bool Exec() = 0;
virtual void Stop() = 0;
};
IPerfMonitor* CreateIntelPerfMonitor(double* load);
IPerfMonitor* CreateNvidiaPerfMonitor(double* load);
} // namespace gpu_stats
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,37 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/http/client.h"
#include <common/net/socket_tcp_tls.h>
namespace fastocloud {
namespace server {
HttpClient::HttpClient(common::libev::IoLoop* server, const common::net::socket_info& info)
: base_class(server, info) {}
const char* HttpClient::ClassName() const {
return "HttpClient";
}
HttpsClient::HttpsClient(common::libev::IoLoop* server, const common::net::socket_info& info, SSL* ssl)
: base_class(server, new common::net::TcpTlsSocketHolder(info, ssl)) {}
const char* HttpsClient::ClassName() const {
return "HttpsClient";
}
} // namespace server
} // namespace fastocloud

43
src/server/http/client.h Normal file
View file

@ -0,0 +1,43 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <common/libev/http/http_client.h>
typedef struct ssl_st SSL;
namespace fastocloud {
namespace server {
class HttpClient : public common::libev::http::HttpClient {
public:
typedef common::libev::http::HttpClient base_class;
HttpClient(common::libev::IoLoop* server, const common::net::socket_info& info);
const char* ClassName() const override;
};
class HttpsClient : public common::libev::http::HttpClient {
public:
typedef common::libev::http::HttpClient base_class;
HttpsClient(common::libev::IoLoop* server, const common::net::socket_info& info, SSL* ssl);
const char* ClassName() const override;
};
} // namespace server
} // namespace fastocloud

202
src/server/http/handler.cpp Normal file
View file

@ -0,0 +1,202 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/http/handler.h"
#include <fcntl.h>
#include <sys/stat.h>
#include <unistd.h>
#include <string>
#include <utility>
#include "server/http/client.h"
namespace fastocloud {
namespace server {
HttpHandler::HttpHandler(const std::string& http_root) : base_class(), http_root_(http_root) {}
const HttpHandler::http_directory_path_t& HttpHandler::GetHttpRoot() const {
return http_root_;
}
void HttpHandler::PreLooped(common::libev::IoLoop* server) {
UNUSED(server);
}
void HttpHandler::Accepted(common::libev::IoClient* client) {
base_class::Accepted(client);
}
void HttpHandler::Moved(common::libev::IoLoop* server, common::libev::IoClient* client) {
base_class::Moved(server, client);
}
void HttpHandler::Closed(common::libev::IoClient* client) {
base_class::Closed(client);
}
void HttpHandler::TimerEmited(common::libev::IoLoop* server, common::libev::timer_id_t id) {
UNUSED(server);
UNUSED(id);
}
void HttpHandler::Accepted(common::libev::IoChild* child) {
UNUSED(child);
}
void HttpHandler::Moved(common::libev::IoLoop* server, common::libev::IoChild* child) {
UNUSED(server);
UNUSED(child);
}
void HttpHandler::ChildStatusChanged(common::libev::IoChild* child, int status, int signal) {
UNUSED(child);
UNUSED(status);
UNUSED(signal);
}
void HttpHandler::DataReceived(common::libev::IoClient* client) {
char buff[BUF_SIZE] = {0};
size_t nread = 0;
common::ErrnoError errn = client->SingleRead(buff, BUF_SIZE - 1, &nread);
if (errn || nread == 0) {
ignore_result(client->Close());
delete client;
return;
}
HttpClient* hclient = static_cast<server::HttpClient*>(client);
ProcessReceived(hclient, buff, nread);
}
void HttpHandler::DataReadyToWrite(common::libev::IoClient* client) {
UNUSED(client);
}
void HttpHandler::PostLooped(common::libev::IoLoop* server) {
UNUSED(server);
}
void HttpHandler::ProcessReceived(HttpClient* hclient, const char* request, size_t req_len) {
static const common::libev::http::HttpServerInfo hinf(PROJECT_NAME_TITLE "/" PROJECT_VERSION, PROJECT_DOMAIN);
common::http::HttpRequest hrequest;
const auto result = common::http::parse_http_request(request, req_len, &hrequest);
DEBUG_LOG() << "Http request:\n" << request;
common::http::headers_t extra_headers = {{"Access-Control-Allow-Origin", "*"}};
if (result.second) {
const std::string error_text = result.second->GetDescription();
DEBUG_MSG_ERROR(result.second, common::logging::LOG_LEVEL_ERR);
common::ErrnoError err =
hclient->SendError(common::http::HP_1_0, result.first, extra_headers, error_text.c_str(), false, hinf);
if (err) {
DEBUG_MSG_ERROR(err, common::logging::LOG_LEVEL_ERR);
}
ignore_result(hclient->Close());
delete hclient;
return;
}
// keep alive
common::http::header_t connection_field;
bool is_find_connection = hrequest.FindHeaderByKey("Connection", false, &connection_field);
bool IsKeepAlive = is_find_connection ? common::EqualsASCII(connection_field.value, "Keep-Alive", false) : false;
const common::http::http_protocol protocol = hrequest.GetProtocol();
const common::http::http_method method = hrequest.GetMethod();
if (method == common::http::http_method::HM_GET || method == common::http::http_method::HM_HEAD) {
auto url = hrequest.GetURL();
if (!url.is_valid()) { // for hls
common::ErrnoError err =
hclient->SendError(protocol, common::http::HS_NOT_FOUND, extra_headers, "File not found.", IsKeepAlive, hinf);
if (err) {
DEBUG_MSG_ERROR(err, common::logging::LOG_LEVEL_ERR);
}
goto finish;
}
const std::string path_abs = url.PathForRequest();
auto file_path = http_root_.MakeConcatFileStringPath(path_abs.substr(1));
if (!file_path) {
common::ErrnoError err =
hclient->SendError(protocol, common::http::HS_NOT_FOUND, extra_headers, "File not found.", IsKeepAlive, hinf);
if (err) {
DEBUG_MSG_ERROR(err, common::logging::LOG_LEVEL_ERR);
}
goto finish;
}
const std::string file_path_str = file_path->GetPath();
int open_flags = O_RDONLY;
struct stat sb;
if (stat(file_path_str.c_str(), &sb) < 0) {
common::ErrnoError err =
hclient->SendError(protocol, common::http::HS_NOT_FOUND, extra_headers, "File not found.", IsKeepAlive, hinf);
if (err) {
DEBUG_MSG_ERROR(err, common::logging::LOG_LEVEL_ERR);
}
goto finish;
}
if (S_ISDIR(sb.st_mode)) {
common::ErrnoError err =
hclient->SendError(protocol, common::http::HS_BAD_REQUEST, extra_headers, "Bad filename.", IsKeepAlive, hinf);
if (err) {
DEBUG_MSG_ERROR(err, common::logging::LOG_LEVEL_ERR);
}
goto finish;
}
int file = open(file_path_str.c_str(), open_flags);
if (file == INVALID_DESCRIPTOR) { /* open the file for reading */
common::ErrnoError err = hclient->SendError(protocol, common::http::HS_FORBIDDEN, extra_headers,
"File is protected.", IsKeepAlive, hinf);
if (err) {
DEBUG_MSG_ERROR(err, common::logging::LOG_LEVEL_ERR);
}
goto finish;
}
const std::string fileName = url.ExtractFileName();
const char* mime = common::http::MimeTypes::GetType(fileName.c_str());
common::ErrnoError err = hclient->SendHeaders(protocol, common::http::HS_OK, extra_headers, mime, &sb.st_size,
&sb.st_mtime, IsKeepAlive, hinf);
if (err) {
DEBUG_MSG_ERROR(err, common::logging::LOG_LEVEL_ERR);
::close(file);
goto finish;
}
if (hrequest.GetMethod() == common::http::http_method::HM_GET) {
common::ErrnoError err = hclient->SendFileByFd(protocol, file, sb.st_size);
if (err) {
DEBUG_MSG_ERROR(err, common::logging::LOG_LEVEL_ERR);
} else {
DEBUG_LOG() << "Sent file path: " << file_path_str << ", size: " << sb.st_size;
}
}
::close(file);
}
finish:
if (!IsKeepAlive) {
ignore_result(hclient->Close());
delete hclient;
}
}
} // namespace server
} // namespace fastocloud

57
src/server/http/handler.h Normal file
View file

@ -0,0 +1,57 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <common/file_system/path.h>
#include "server/base/iserver_handler.h"
namespace fastocloud {
namespace server {
class HttpClient;
class HttpHandler : public base::IServerHandler {
public:
enum { BUF_SIZE = 4096 };
typedef base::IServerHandler base_class;
typedef common::file_system::ascii_directory_string_path http_directory_path_t;
explicit HttpHandler(const std::string& http_root);
const http_directory_path_t& GetHttpRoot() const;
void PreLooped(common::libev::IoLoop* server) override;
void Accepted(common::libev::IoClient* client) override;
void Moved(common::libev::IoLoop* server, common::libev::IoClient* client) override;
void Closed(common::libev::IoClient* client) override;
void TimerEmited(common::libev::IoLoop* server, common::libev::timer_id_t id) override;
void Accepted(common::libev::IoChild* child) override;
void Moved(common::libev::IoLoop* server, common::libev::IoChild* child) override;
void ChildStatusChanged(common::libev::IoChild* child, int status, int signal) override;
void DataReceived(common::libev::IoClient* client) override;
void DataReadyToWrite(common::libev::IoClient* client) override;
void PostLooped(common::libev::IoLoop* server) override;
private:
void ProcessReceived(HttpClient* hclient, const char* request, size_t req_len);
const http_directory_path_t http_root_;
};
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,45 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/http/server.h"
#include "server/http/client.h"
#include <common/net/socket_tcp_tls.h>
namespace fastocloud {
namespace server {
HttpServer::HttpServer(const common::net::HostAndPort& host, common::libev::IoLoopObserver* observer)
: base_class(new common::net::ServerSocketEvTcp(host), false, observer) {}
common::libev::tcp::TcpClient* HttpServer::CreateClient(const common::net::socket_info& info, void* user) {
UNUSED(user);
return new HttpClient(this, info);
}
HttpsServer::HttpsServer(const common::net::HostAndPort& host, common::libev::IoLoopObserver* observer)
: base_class(new common::net::ServerSocketEvTcpTls(host), false, observer) {}
common::ErrnoError HttpsServer::LoadCertificates(const std::string& cert, const std::string& key) {
auto sock = GetSocket();
return static_cast<common::net::ServerSocketEvTcpTls*>(sock)->LoadCertificates(cert, key);
}
common::libev::tcp::TcpClient* HttpsServer::CreateClient(const common::net::socket_info& info, void* user) {
return new HttpsClient(this, info, static_cast<SSL*>(user));
}
} // namespace server
} // namespace fastocloud

43
src/server/http/server.h Normal file
View file

@ -0,0 +1,43 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <common/libev/http/http_server.h>
namespace fastocloud {
namespace server {
class HttpServer : public common::libev::http::HttpServer {
public:
typedef common::libev::http::HttpServer base_class;
explicit HttpServer(const common::net::HostAndPort& host, common::libev::IoLoopObserver* observer = nullptr);
private:
common::libev::tcp::TcpClient* CreateClient(const common::net::socket_info& info, void* user) override;
};
class HttpsServer : public common::libev::http::HttpServer {
public:
typedef common::libev::http::HttpServer base_class;
explicit HttpsServer(const common::net::HostAndPort& host, common::libev::IoLoopObserver* observer = nullptr);
common::ErrnoError LoadCertificates(const std::string& cert, const std::string& key);
private:
common::libev::tcp::TcpClient* CreateClient(const common::net::socket_info& info, void* user) override;
};
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,397 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/options/options.h"
#include <limits>
#include <string>
#include <utility>
#include <vector>
#include <common/draw/size.h>
#include <common/file_system/path.h>
#include <common/media/types.h>
#include "base/config_fields.h"
#include "base/gst_constants.h"
#include "base/types.h"
namespace fastocloud {
namespace {
enum Validity { VALID, INVALID, FATAL };
typedef Validity (*validate_callback_t)(const common::Value*);
typedef std::pair<std::string, validate_callback_t> option_t;
Validity dont_validate(const common::Value*) {
return Validity::VALID;
}
Validity validate_range(const common::Value* value, double min, double max, bool is_fatal) {
double i;
if (value->GetAsDouble(&i) && i >= min && i <= max) {
return Validity::VALID;
}
return is_fatal ? Validity::FATAL : Validity::INVALID;
}
Validity validate_range(const common::Value* value, int min, int max, bool is_fatal) {
int64_t i;
if (value->GetAsInteger64(&i) && i >= min && i <= max) {
return Validity::VALID;
}
return is_fatal ? Validity::FATAL : Validity::INVALID;
}
Validity validate_is_positive(const common::Value* value, bool is_fatal) {
int64_t i;
if (value->GetAsInteger64(&i) && i >= 0) {
return Validity::VALID;
}
return is_fatal ? Validity::FATAL : Validity::INVALID;
}
Validity validate_id(const common::Value* value) {
fastotv::stream_id_t id;
if (!value->GetAsBasicString(&id)) {
return Validity::INVALID;
}
return id.empty() ? Validity::INVALID : Validity::VALID;
}
Validity validate_input(const common::Value* value) {
const common::ArrayValue* input = nullptr;
if (!value->GetAsList(&input)) {
return Validity::INVALID;
}
return Validity::VALID;
}
Validity validate_output(const common::Value* value) {
const common::ArrayValue* output = nullptr;
if (!value->GetAsList(&output)) {
return Validity::INVALID;
}
return Validity::VALID;
}
Validity validate_restart_attempts(const common::Value* value) {
return validate_range(value, 1, std::numeric_limits<int>::max(), false);
}
Validity validate_feedback_dir(const common::Value* value) {
std::string path;
if (!value->GetAsBasicString(&path)) {
return Validity::INVALID;
}
return common::file_system::is_valid_path(path) ? Validity::VALID : Validity::INVALID;
}
Validity validate_data_dir(const common::Value* value) {
std::string path;
if (!value->GetAsBasicString(&path)) {
return Validity::INVALID;
}
return common::file_system::is_valid_path(path) ? Validity::VALID : Validity::INVALID;
}
Validity validate_timeshift_dir(const common::Value* value) {
std::string path;
if (!value->GetAsBasicString(&path)) {
return Validity::INVALID;
}
return common::file_system::is_valid_path(path) ? Validity::VALID : Validity::FATAL;
}
Validity validate_timeshift_chunk_life_time(const common::Value* value) {
return validate_range(value, 0, 12 * 24 * 3600, false);
}
Validity validate_timeshift_delay(const common::Value* value) {
return validate_range(value, 0, 12 * 24 * 3600, false);
}
Validity validate_video_parser(const common::Value* value) {
std::string parser_str;
if (!value->GetAsBasicString(&parser_str)) {
return Validity::INVALID;
}
for (size_t i = 0; i < SUPPORTED_VIDEO_PARSERS_COUNT; ++i) {
const char* parser = kSupportedVideoParsers[i];
if (parser_str == parser) {
return Validity::VALID;
}
}
return Validity::INVALID;
}
Validity validate_audio_parser(const common::Value* value) {
std::string parser_str;
if (!value->GetAsBasicString(&parser_str)) {
return Validity::INVALID;
}
for (size_t i = 0; i < SUPPORTED_AUDIO_PARSERS_COUNT; ++i) {
const char* parser = kSupportedAudioParsers[i];
if (parser_str == parser) {
return Validity::VALID;
}
}
return Validity::INVALID;
}
Validity validate_video_codec(const common::Value* value) {
std::string codec_str;
if (!value->GetAsBasicString(&codec_str)) {
return Validity::INVALID;
}
for (size_t i = 0; i < SUPPORTED_VIDEO_ENCODERS_COUNT; ++i) {
const char* codec = kSupportedVideoEncoders[i];
if (codec_str == codec) {
return Validity::VALID;
}
}
return Validity::INVALID;
}
Validity validate_audio_codec(const common::Value* value) {
std::string codec_str;
if (!value->GetAsBasicString(&codec_str)) {
return Validity::INVALID;
}
for (size_t i = 0; i < SUPPORTED_AUDIO_ENCODERS_COUNT; ++i) {
const char* codec = kSupportedAudioEncoders[i];
if (codec_str == codec) {
return Validity::VALID;
}
}
return Validity::INVALID;
}
Validity validate_type(const common::Value* value) {
return validate_range(value, static_cast<int>(fastotv::PROXY), static_cast<int>(fastotv::CHANGER_ENCODE), true);
}
Validity validate_log_level(const common::Value* value) {
return validate_range(value, static_cast<int>(common::logging::LOG_LEVEL_EMERG),
static_cast<int>(common::logging::LOG_LEVEL_DEBUG), false);
}
Validity validate_volume(const common::Value* value) {
return validate_range(value, 0.0, 10.0, false);
}
Validity validate_delay_time(const common::Value* value) {
return validate_is_positive(value, false);
}
Validity validate_timeshift_chunk_duration(const common::Value* value) {
return validate_is_positive(value, false);
}
Validity validate_auto_exit_time(const common::Value* value) {
return validate_is_positive(value, false);
}
Validity validate_size(const common::Value* value) {
std::string size_str;
if (!value->GetAsBasicString(&size_str)) {
return Validity::INVALID;
}
common::draw::Size size;
return common::ConvertFromString(size_str, &size) ? Validity::VALID : Validity::INVALID;
}
Validity validate_cleanupts(const common::Value* value) {
bool cleanup;
if (!value->GetAsBoolean(&cleanup)) {
return Validity::INVALID;
}
return Validity::VALID;
}
Validity validate_framerate(const common::Value* value) {
std::string rat_str;
if (!value->GetAsBasicString(&rat_str)) {
return Validity::INVALID;
}
common::media::Rational rat;
return common::ConvertFromString(rat_str, &rat) ? Validity::VALID : Validity::INVALID;
}
Validity validate_aspect_ratio(const common::Value* value) {
std::string rat_str;
if (!value->GetAsBasicString(&rat_str)) {
return Validity::INVALID;
}
common::media::Rational rat;
return common::ConvertFromString(rat_str, &rat) ? Validity::VALID : Validity::INVALID;
}
Validity validate_decklink_video_mode(const common::Value* value) {
return validate_range(value, 0, 30, false);
}
Validity validate_video_bitrate(const common::Value* value) {
return validate_is_positive(value, false);
}
Validity validate_audio_bitrate(const common::Value* value) {
return validate_is_positive(value, false);
}
Validity validate_audio_channels(const common::Value* value) {
return validate_is_positive(value, false);
}
Validity validate_audio_select(const common::Value* value) {
int64_t ais;
if (!value->GetAsInteger64(&ais)) {
return Validity::INVALID;
}
return Validity::VALID;
}
class ConstantOptions : public std::vector<option_t> {
public:
ConstantOptions(std::initializer_list<option_t> l) {
for (auto it = l.begin(); it != l.end(); ++it) {
option_t opt = *it;
for (auto jt = begin(); jt != end(); ++jt) {
option_t opt2 = *jt;
if (opt2.first == opt.first) {
NOTREACHED() << "Only unique options, but option with name: '" << opt.first << "' exists!";
}
}
push_back(opt);
}
}
};
bool FindOption(const std::string& key, option_t* opt) {
if (!opt) {
return false;
}
static const ConstantOptions ALLOWED_OPTIONS = {
{ID_FIELD, validate_id},
{TYPE_FIELD, validate_type},
{FEEDBACK_DIR_FIELD, validate_feedback_dir},
{DATA_DIR_FIELD, validate_data_dir},
{LOG_LEVEL_FIELD, validate_log_level},
{PYFASTOSTREAM_PATH_FIELD, dont_validate},
{INPUT_FIELD, validate_input},
{OUTPUT_FIELD, validate_output},
{RESTART_ATTEMPTS_FIELD, validate_restart_attempts},
{AUTO_EXIT_TIME_FIELD, validate_auto_exit_time},
{TIMESHIFT_DIR_FIELD, validate_timeshift_dir},
{TIMESHIFT_CHUNK_LIFE_TIME_FIELD, validate_timeshift_chunk_life_time},
{TIMESHIFT_DELAY_FIELD, validate_timeshift_delay},
{VOLUME_FIELD, validate_volume},
{DELAY_TIME_FIELD, validate_delay_time},
{TIMESHIFT_CHUNK_DURATION_FIELD, validate_timeshift_chunk_duration},
{VIDEO_PARSER_FIELD, validate_video_parser},
{AUDIO_PARSER_FIELD, validate_audio_parser},
{AUDIO_CODEC_FIELD, validate_audio_codec},
{VIDEO_CODEC_FIELD, validate_video_codec},
{HAVE_VIDEO_FIELD, dont_validate},
{HAVE_AUDIO_FIELD, dont_validate},
{HAVE_SUBTITLE_FIELD, dont_validate},
{DEINTERLACE_FIELD, dont_validate},
{RELAY_AUDIO_FIELD, dont_validate},
{RELAY_VIDEO_FIELD, dont_validate},
{LOOP_FIELD, dont_validate},
{SIZE_FIELD, validate_size},
{CLEANUP_TS_FIELD, validate_cleanupts},
{LOGO_FIELD, dont_validate},
{RSVG_LOGO_FIELD, dont_validate},
{FRAME_RATE_FIELD, validate_framerate},
{ASPECT_RATIO_FIELD, validate_aspect_ratio},
{VIDEO_BIT_RATE_FIELD, validate_video_bitrate},
{AUDIO_BIT_RATE_FIELD, validate_audio_bitrate},
{AUDIO_CHANNELS_FIELD, validate_audio_channels},
{AUDIO_SELECT_FIELD, validate_audio_select},
{DECKLINK_VIDEO_MODE_FIELD, validate_decklink_video_mode},
#if defined(MACHINE_LEARNING)
{DEEP_LEARNING_FIELD, dont_validate},
{DEEP_LEARNING_OVERLAY_FIELD, dont_validate},
#endif
#if defined(AMAZON_KINESIS)
{AMAZON_KINESIS_FIELD, dont_validate},
#endif
};
for (const option_t& cur : ALLOWED_OPTIONS) {
if (cur.first == key) {
*opt = cur;
return true;
}
}
return false;
}
} // namespace
namespace server {
namespace options {
common::ErrnoError ValidateConfig(const StreamConfig& config) {
if (!config) {
return common::make_errno_error_inval();
}
for (auto it = config->begin(); it != config->end(); ++it) {
option_t option;
std::string key = it->first.as_string();
if (!FindOption(key, &option)) {
WARNING_LOG() << "Unknown option: " << key;
} else {
common::Value* value = it->second;
Validity valid = option.second(value);
if (valid == Validity::INVALID) {
WARNING_LOG() << "Invalid value '" << value << "' of option '" << key << "'";
} else if (valid == Validity::FATAL) {
std::stringstream os;
os << "Invalid value '" << value << "' of option '" << key << "'";
ERROR_LOG() << os.str();
return common::make_errno_error(os.str(), EINVAL);
}
}
}
return common::ErrnoError();
}
} // namespace options
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,29 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <common/error.h>
#include "base/stream_config.h"
namespace fastocloud {
namespace server {
namespace options {
common::ErrnoError ValidateConfig(const StreamConfig& config);
} // namespace options
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,64 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/pipe/client.h"
#include <common/libev/pipe_client.h>
#include <memory>
namespace fastocloud {
namespace server {
namespace pipe {
Client::Client(common::libev::IoLoop* server, descriptor_t read_fd, descriptor_t write_fd)
: base_class(std::make_shared<fastotv::protocol::FastoTVCompressor>(), server),
pipe_read_client_(new common::libev::PipeReadClient(nullptr, read_fd)),
pipe_write_client_(new common::libev::PipeWriteClient(nullptr, write_fd)),
read_fd_(read_fd) {}
common::ErrnoError Client::DoSingleWrite(const void* data, size_t size, size_t* nwrite_out) {
return pipe_write_client_->SingleWrite(data, size, nwrite_out);
}
common::ErrnoError Client::DoSingleRead(void* out, size_t max_size, size_t* nread) {
return pipe_read_client_->SingleRead(out, max_size, nread);
}
common::ErrnoError Client::DoSendFile(descriptor_t file_fd, size_t file_size) {
return pipe_read_client_->SendFile(file_fd, file_size);
}
descriptor_t Client::GetFd() const {
return read_fd_;
}
common::ErrnoError Client::DoClose() {
ignore_result(pipe_write_client_->Close());
ignore_result(pipe_read_client_->Close());
return common::ErrnoError();
}
const char* Client::ClassName() const {
return "PipeClient";
}
Client::~Client() {
destroy(&pipe_write_client_);
destroy(&pipe_read_client_);
}
} // namespace pipe
} // namespace server
} // namespace fastocloud

52
src/server/pipe/client.h Normal file
View file

@ -0,0 +1,52 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <common/libev/pipe_client.h>
#include <fastotv/protocol/protocol.h>
namespace fastocloud {
namespace server {
namespace pipe {
class Client : public fastotv::protocol::protocol_client_t {
public:
typedef fastotv::protocol::ProtocolClient<common::libev::IoClient> base_class;
~Client() override;
const char* ClassName() const override;
Client(common::libev::IoLoop* server, descriptor_t read_fd, descriptor_t write_fd);
protected:
descriptor_t GetFd() const override;
private:
common::ErrnoError DoSingleWrite(const void* data, size_t size, size_t* nwrite_out) override;
common::ErrnoError DoSingleRead(void* out, size_t max_size, size_t* nread) override;
common::ErrnoError DoSendFile(descriptor_t file_fd, size_t file_size) override;
common::ErrnoError DoClose() override;
common::libev::PipeReadClient* pipe_read_client_;
common::libev::PipeWriteClient* pipe_write_client_;
const descriptor_t read_fd_;
DISALLOW_COPY_AND_ASSIGN(Client);
};
} // namespace pipe
} // namespace server
} // namespace fastocloud

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,176 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <map>
#include <string>
#include <vector>
#include <common/libev/io_loop_observer.h>
#include <common/net/types.h>
#include <common/threads/ts_queue.h>
#include <fastotv/protocol/protocol.h>
#include <fastotv/protocol/types.h>
#include "base/stream_config.h"
#include "base/stream_info.h"
#include "server/config.h"
namespace fastocloud {
namespace server {
class ChildStream;
class ProtocoledDaemonClient;
class ProcessSlaveWrapper : public common::libev::IoLoopObserver {
public:
enum {
node_stats_send_seconds = 10,
ping_timeout_clients_seconds = 60,
cleanup_seconds = 3,
check_license_timeout_seconds = 300,
dead_client_ttl_in_seconds = 600
};
typedef StreamConfig serialized_stream_t;
typedef fastotv::protocol::protocol_client_t stream_client_t;
explicit ProcessSlaveWrapper(const Config& config);
~ProcessSlaveWrapper() override;
static common::ErrnoError SendStopDaemonRequest(const Config& config);
static common::ErrnoError SendRestartDaemonRequest(const Config& config);
common::net::HostAndPort GetServerHostAndPort();
int Exec(int argc, char** argv) WARN_UNUSED_RESULT;
bool IsStoped() const;
protected:
void PreLooped(common::libev::IoLoop* server) override;
void Accepted(common::libev::IoClient* client) override;
void Moved(common::libev::IoLoop* server,
common::libev::IoClient* client) override; // owner server, now client is orphan
void Closed(common::libev::IoClient* client) override;
void TimerEmited(common::libev::IoLoop* server, common::libev::timer_id_t id) override;
void Accepted(common::libev::IoChild* child) override;
void Moved(common::libev::IoLoop* server, common::libev::IoChild* child) override;
void ChildStatusChanged(common::libev::IoChild* child, int status, int signal) override;
void DataReceived(common::libev::IoClient* client) override;
void DataReadyToWrite(common::libev::IoClient* client) override;
void PostLooped(common::libev::IoLoop* server) override;
virtual common::ErrnoError HandleRequestServiceCommand(ProtocoledDaemonClient* dclient,
const fastotv::protocol::request_t* req) WARN_UNUSED_RESULT;
virtual common::ErrnoError HandleResponceServiceCommand(ProtocoledDaemonClient* dclient,
const fastotv::protocol::response_t* resp) WARN_UNUSED_RESULT;
virtual common::ErrnoError HandleRequestStreamsCommand(stream_client_t* pclient,
const fastotv::protocol::request_t* req) WARN_UNUSED_RESULT;
virtual common::ErrnoError HandleResponceStreamsCommand(stream_client_t* pclient,
const fastotv::protocol::response_t* resp) WARN_UNUSED_RESULT;
private:
common::ErrnoError Prepare() WARN_UNUSED_RESULT;
void StopImpl();
ChildStream* FindChildByID(fastotv::stream_id_t cid) const;
void BroadcastClients(const fastotv::protocol::request_t& req);
common::ErrnoError DaemonDataReceived(ProtocoledDaemonClient* dclient) WARN_UNUSED_RESULT;
common::ErrnoError StreamDataReceived(stream_client_t* pclient) WARN_UNUSED_RESULT;
common::ErrnoError CreateChildStream(const serialized_stream_t& config_args) WARN_UNUSED_RESULT;
common::ErrnoError CreateChildStreamImpl(const serialized_stream_t& config_args,
const StreamInfo& sha) WARN_UNUSED_RESULT;
common::ErrnoError StopChildStreamImpl(fastotv::stream_id_t sid, bool force) WARN_UNUSED_RESULT;
// stream
common::ErrnoError HandleRequestChangedSourcesStream(stream_client_t* pclient,
const fastotv::protocol::request_t* req) WARN_UNUSED_RESULT;
common::ErrnoError HandleRequestStatisticStream(stream_client_t* pclient,
const fastotv::protocol::request_t* req) WARN_UNUSED_RESULT;
#if defined(MACHINE_LEARNING)
common::ErrnoError HandleRequestMlNotificationStream(stream_client_t* pclient,
const fastotv::protocol::request_t* req) WARN_UNUSED_RESULT;
#endif
common::ErrnoError HandleRequestClientStartStream(ProtocoledDaemonClient* dclient,
const fastotv::protocol::request_t* req) WARN_UNUSED_RESULT;
common::ErrnoError HandleRequestClientStopStream(ProtocoledDaemonClient* dclient,
const fastotv::protocol::request_t* req) WARN_UNUSED_RESULT;
common::ErrnoError HandleRequestClientRestartStream(ProtocoledDaemonClient* dclient,
const fastotv::protocol::request_t* req) WARN_UNUSED_RESULT;
common::ErrnoError HandleRequestClientGetLogStream(ProtocoledDaemonClient* dclient,
const fastotv::protocol::request_t* req) WARN_UNUSED_RESULT;
common::ErrnoError HandleRequestClientGetPipelineStream(ProtocoledDaemonClient* dclient,
const fastotv::protocol::request_t* req) WARN_UNUSED_RESULT;
common::ErrnoError HandleRequestClientGetConfigJsonStream(ProtocoledDaemonClient* dclient,
const fastotv::protocol::request_t* req) WARN_UNUSED_RESULT;
common::ErrnoError HandleRequestClientActivate(ProtocoledDaemonClient* dclient,
const fastotv::protocol::request_t* req) WARN_UNUSED_RESULT;
common::ErrnoError HandleRequestClientPingService(ProtocoledDaemonClient* dclient,
const fastotv::protocol::request_t* req) WARN_UNUSED_RESULT;
common::ErrnoError HandleRequestClientGetLogService(ProtocoledDaemonClient* dclient,
const fastotv::protocol::request_t* req) WARN_UNUSED_RESULT;
common::ErrnoError HandleRequestClientRestartService(ProtocoledDaemonClient* dclient,
const fastotv::protocol::request_t* req) WARN_UNUSED_RESULT;
common::ErrnoError HandleRequestClientStopService(ProtocoledDaemonClient* dclient,
const fastotv::protocol::request_t* req) WARN_UNUSED_RESULT;
common::ErrnoError HandleResponcePingService(ProtocoledDaemonClient* dclient,
const fastotv::protocol::response_t* resp) WARN_UNUSED_RESULT;
void CheckLicenseExpired(common::libev::IoLoop* server);
std::string MakeServiceStats(common::Optional<common::time64_t> expiration_time) const;
struct NodeStats;
const Config config_;
int process_argc_;
char** process_argv_;
common::libev::IoLoop* loop_;
// http
common::libev::IoLoop* http_server_;
common::libev::IoLoopObserver* http_handler_;
// vods (video on demand)
common::libev::IoLoop* vods_server_;
common::libev::IoLoopObserver* vods_handler_;
// cods (channel on demand)
common::libev::IoLoop* cods_server_;
common::libev::IoLoopObserver* cods_handler_;
common::libev::timer_id_t ping_client_timer_;
common::libev::timer_id_t check_cods_vods_timer_;
common::libev::timer_id_t check_old_files_timer_;
common::libev::timer_id_t node_stats_timer_;
common::libev::timer_id_t quit_cleanup_timer_;
common::libev::timer_id_t check_license_timer_;
NodeStats* node_stats_;
std::vector<common::file_system::ascii_directory_string_path> folders_for_monitor_;
bool stoped_;
};
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,187 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/process_slave_wrapper.h"
#if defined(OS_LINUX)
#include <sys/prctl.h>
#endif
#include <dlfcn.h>
#include <sys/wait.h>
#include <unistd.h>
#include <common/file_system/file_system.h>
#include <common/file_system/string_path_utils.h>
#include "base/stream_info.h"
#include "server/child_stream.h"
#include "server/daemon/server.h"
#include "server/utils/utils.h"
#define PIPE
#if defined(PIPE)
#include "pipe/client.h"
#else
#include "tcp/client.h"
#endif
namespace fastocloud {
namespace server {
common::ErrnoError ProcessSlaveWrapper::CreateChildStreamImpl(const serialized_stream_t& config_args,
const StreamInfo& sha) {
const auto sid = GetSid(config_args);
if (!sid) {
return common::make_errno_error_inval();
}
#if defined(PIPE)
common::net::socket_descr_t read_command_client;
common::net::socket_descr_t write_requests_client;
common::ErrnoError err = CreatePipe(&read_command_client, &write_requests_client);
if (err) {
return err;
}
common::net::socket_descr_t read_responce_client;
common::net::socket_descr_t write_responce_client;
err = CreatePipe(&read_responce_client, &write_responce_client);
if (err) {
common::ErrnoError errn = common::file_system::close_descriptor(read_command_client);
if (errn) {
DEBUG_MSG_ERROR(errn, common::logging::LOG_LEVEL_WARNING);
}
errn = common::file_system::close_descriptor(write_requests_client);
if (errn) {
DEBUG_MSG_ERROR(errn, common::logging::LOG_LEVEL_WARNING);
}
return err;
}
#else
common::net::socket_descr_t parent_sock;
common::net::socket_descr_t child_sock;
common::ErrnoError err = CreateSocketPair(&parent_sock, &child_sock);
if (err) {
return err;
}
#endif
#if !defined(TEST)
pid_t pid = fork();
#else
pid_t pid = 0;
#endif
if (pid == 0) { // child
typedef int (*stream_exec_t)(const char* process_name, const void* args, void* command_client);
const std::string absolute_source_dir = common::file_system::absolute_path_from_relative(RELATIVE_SOURCE_DIR);
const std::string lib_full_path = common::file_system::make_path(absolute_source_dir, CORE_LIBRARY);
void* handle = dlopen(lib_full_path.c_str(), RTLD_LAZY);
if (!handle) {
ERROR_LOG() << "Failed to load " CORE_LIBRARY " path: " << lib_full_path << ", error: " << dlerror();
_exit(EXIT_FAILURE);
}
stream_exec_t stream_exec_func = reinterpret_cast<stream_exec_t>(dlsym(handle, "stream_exec"));
char* error = dlerror();
if (error) {
ERROR_LOG() << "Failed to load start stream function error: " << error;
dlclose(handle);
_exit(EXIT_FAILURE);
}
const std::string new_process_name = common::MemSPrintf(STREAMER_NAME "_%s", *sid);
const char* new_name = new_process_name.c_str();
#if defined(OS_LINUX)
for (int i = 0; i < process_argc_; ++i) {
memset(process_argv_[i], 0, strlen(process_argv_[i]));
}
char* app_name = process_argv_[0];
strncpy(app_name, new_name, new_process_name.length());
app_name[new_process_name.length()] = 0;
prctl(PR_SET_NAME, new_name);
#elif defined(OS_FREEBSD)
setproctitle(new_name);
#else
#pragma message "Please implement"
#endif
#if defined(PIPE)
#if !defined(TEST)
// close not needed pipes
common::ErrnoError errn = common::file_system::close_descriptor(read_responce_client);
if (errn) {
DEBUG_MSG_ERROR(errn, common::logging::LOG_LEVEL_WARNING);
}
errn = common::file_system::close_descriptor(write_requests_client);
if (errn) {
DEBUG_MSG_ERROR(errn, common::logging::LOG_LEVEL_WARNING);
}
#endif
pipe::Client* client = new pipe::Client(nullptr, read_command_client, write_responce_client);
#else
// close not needed sock
common::ErrnoError errn = common::file_system::close_descriptor(parent_sock);
if (errn) {
DEBUG_MSG_ERROR(errn, common::logging::LOG_LEVEL_WARNING);
}
tcp::Client* client = new tcp::Client(nullptr, common::net::socket_info(child_sock));
#endif
client->SetName(*sid);
int res = stream_exec_func(new_name, config_args.get(), client);
ignore_result(client->Close());
delete client;
dlclose(handle);
_exit(res);
} else if (pid < 0) {
ERROR_LOG() << "Failed to start children!";
} else {
#if defined(PIPE)
// close not needed pipes
common::ErrnoError errn = common::file_system::close_descriptor(read_command_client);
if (errn) {
DEBUG_MSG_ERROR(errn, common::logging::LOG_LEVEL_WARNING);
}
errn = common::file_system::close_descriptor(write_responce_client);
if (err) {
DEBUG_MSG_ERROR(errn, common::logging::LOG_LEVEL_WARNING);
}
pipe::Client* client = new pipe::Client(loop_, read_responce_client, write_requests_client);
#else
// close not needed sock
common::ErrnoError errn = common::file_system::close_descriptor(child_sock);
if (errn) {
DEBUG_MSG_ERROR(errn, common::logging::LOG_LEVEL_WARNING);
}
tcp::Client* client = new tcp::Client(loop_, common::net::socket_info(parent_sock));
#endif
client->SetName(*sid);
bool registered = loop_->RegisterClient(client);
if (!registered) {
return common::make_errno_error("Can't register communication pipe", EAGAIN);
}
ChildStream* new_channel = new ChildStream(loop_, sha);
new_channel->SetClient(client);
loop_->RegisterChild(new_channel, pid);
}
return common::ErrnoError();
}
} // namespace server
} // namespace fastocloud

View file

@ -0,0 +1,121 @@
/* Copyright (C) 2014-2019 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/process_slave_wrapper.h"
#include <common/libev/io_loop.h>
#include "base/stream_config_parse.h"
#include "server/child_stream.h"
#include "server/tcp/client.h"
#include "server/utils/utils.h"
namespace fastocloud {
namespace server {
common::ErrnoError ProcessSlaveWrapper::CreateChildStreamImpl(const serialized_stream_t& config_args,
const StreamInfo& sha) {
const auto sid = GetSid(config_args);
common::net::socket_descr_t parent_sock;
common::net::socket_descr_t child_sock;
common::ErrnoError err = CreateSocketPair(&parent_sock, &child_sock);
if (err) {
return err;
}
SECURITY_ATTRIBUTES sa;
memset(&sa, 0, sizeof(sa));
sa.nLength = sizeof(sa);
sa.bInheritHandle = TRUE;
std::string json;
if (!MakeJsonFromConfig(config_args, &json)) {
return common::make_errno_error(EINTR);
}
const size_t proto_info_len = sizeof(WSAPROTOCOL_INFO);
const size_t allocate_memory = proto_info_len + json.size();
HANDLE args_handle = CreateFileMapping(INVALID_HANDLE_VALUE, &sa, PAGE_READWRITE, 0, allocate_memory, nullptr);
if (args_handle == INVALID_HANDLE_VALUE) {
return common::make_errno_error(errno);
}
char* param = static_cast<char*>(MapViewOfFile(args_handle, FILE_MAP_WRITE, 0, 0, allocate_memory));
if (!param) {
CloseHandle(args_handle);
return common::make_errno_error(errno);
}
#define CMD_LINE_SIZE 512
char cmd_line[CMD_LINE_SIZE] = {0};
#if defined(_WIN64)
common::SNPrintf(cmd_line, CMD_LINE_SIZE, STREAMER_EXE_NAME ".exe %llu %llu", reinterpret_cast<UINT_PTR>(args_handle),
allocate_memory);
#else
common::SNPrintf(cmd_line, CMD_LINE_SIZE, STREAMER_EXE_NAME ".exe %lu %lu", reinterpret_cast<DWORD>(args_handle),
allocate_memory);
#endif
STARTUPINFO si;
PROCESS_INFORMATION pi;
memset(&pi, 0, sizeof(pi));
memset(&si, 0, sizeof(si));
if (!CreateProcess(nullptr, cmd_line, nullptr, nullptr, TRUE, CREATE_SUSPENDED, nullptr, nullptr, &si, &pi)) {
UnmapViewOfFile(param);
CloseHandle(args_handle);
return common::make_errno_error(errno);
}
WSAPROTOCOL_INFO pin;
if (WSADuplicateSocket(child_sock, pi.dwProcessId, &pin) != 0) {
UnmapViewOfFile(param);
CloseHandle(args_handle);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return common::make_errno_error(errno);
}
closesocket(child_sock);
memcpy(param, &pin, proto_info_len);
memcpy(param + proto_info_len, json.c_str(), json.size());
UnmapViewOfFile(param);
CloseHandle(args_handle);
if (ResumeThread(pi.hThread) == -1) {
if (!TerminateProcess(pi.hProcess, EXIT_FAILURE)) {
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return common::make_errno_error(errno);
}
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
return common::make_errno_error(errno);
}
tcp::Client* sock_client = new tcp::Client(loop_, common::net::socket_info(parent_sock));
sock_client->SetName(*sid);
bool registered = loop_->RegisterClient(sock_client);
if (!registered) {
return common::make_errno_error("Can't register communication pipe", EAGAIN);
}
ChildStream* child = new ChildStream(loop_, sha);
child->SetClient(sock_client);
loop_->RegisterChild(child, pi.hProcess);
CloseHandle(pi.hThread);
return common::ErrnoError();
}
} // namespace server
} // namespace fastocloud

109
src/server/stream_win.cpp Normal file
View file

@ -0,0 +1,109 @@
/* Copyright (C) 2014-2019 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdlib.h>
#include <iostream>
#include <string>
#include <common/file_system/string_path_utils.h>
#include <common/sprintf.h>
#include <common/libev/tcp/tcp_client.h>
#include <fastotv/protocol/protocol.h>
#include "base/config_fields.h"
#include "base/stream_config_parse.h"
#include "server/tcp/client.h"
namespace {
struct WinsockInit {
WinsockInit() {
WSADATA d;
if (WSAStartup(0x202, &d) != 0) {
_exit(1);
}
}
~WinsockInit() { WSACleanup(); }
} winsock_init;
} // namespace
int main(int argc, char** argv) {
if (argc != 3) {
std::cerr << "Must be 3 arguments";
return EXIT_FAILURE;
}
const std::string absolute_source_dir = common::file_system::absolute_path_from_relative(RELATIVE_SOURCE_DIR);
const std::string lib_full_path = common::file_system::make_path(absolute_source_dir, CORE_LIBRARY);
HINSTANCE dll = LoadLibrary(lib_full_path.c_str());
if (!dll) {
std::cerr << "Failed to load " CORE_LIBRARY " path: " << lib_full_path << std::endl;
return EXIT_FAILURE;
}
typedef int (*stream_exec_t)(const char* process_name, const void* args, void* command_client);
stream_exec_t stream_exec_func = reinterpret_cast<stream_exec_t>(GetProcAddress(dll, "stream_exec"));
if (!stream_exec_func) {
std::cerr << "Failed to load start stream function error: " << GetLastError();
FreeLibrary(dll);
return EXIT_FAILURE;
}
const char* hid = argv[1];
const char* sz = argv[2];
#if defined(_WIN64)
HANDLE param_handle = reinterpret_cast<HANDLE>(_atoi64(hid));
size_t size = _atoi64(sz);
#else
HANDLE param_handle = reinterpret_cast<HANDLE>(atol(hid));
size_t size = atol(sz);
#endif
char* params = static_cast<char*>(MapViewOfFile(param_handle, FILE_MAP_READ, 0, 0, 0));
if (!params) {
std::cerr << "Can't load shared settings: " << GetLastError();
FreeLibrary(dll);
return EXIT_FAILURE;
}
const size_t proto_info_len = sizeof(WSAPROTOCOL_INFO);
WSAPROTOCOL_INFO pin;
memcpy(&pin, params, proto_info_len);
const char* params_json = params + proto_info_len;
const auto params_config = fastocloud::MakeConfigFromJson(std::string(params_json, size - proto_info_len));
UnmapViewOfFile(params_json);
if (!params_config) {
std::cerr << "Invalid config json";
FreeLibrary(dll);
return EXIT_FAILURE;
}
common::Value* id_field = params_config->Find(ID_FIELD);
std::string sid;
if (!id_field || !id_field->GetAsBasicString(&sid)) {
std::cerr << "Define " ID_FIELD " variable and make it valid";
FreeLibrary(dll);
return EXIT_FAILURE;
}
common::net::socket_descr_t cfd = WSASocket(pin.iAddressFamily, pin.iSocketType, pin.iProtocol, &pin, 0, 0);
const std::string new_process_name = common::MemSPrintf(STREAMER_NAME "_%s", sid);
const char* new_name = new_process_name.c_str();
int res = stream_exec_func(new_name, params_config.get(),
new fastocloud::server::tcp::Client(nullptr, common::net::socket_info(cfd)));
FreeLibrary(dll);
return res;
}

49
src/server/tcp/client.cpp Normal file
View file

@ -0,0 +1,49 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/tcp/client.h"
#include <memory>
namespace fastocloud {
namespace server {
namespace tcp {
Client::Client(common::libev::IoLoop* server, const common::net::socket_info& info)
: base_class(std::make_shared<fastotv::protocol::FastoTVCompressor>(), server),
client_(new common::libev::tcp::TcpClient(nullptr, info)) {}
const char* Client::ClassName() const {
return "TcpClient";
}
common::ErrnoError Client::DoSingleWrite(const void* data, size_t size, size_t* nwrite_out) {
return client_->SingleWrite(data, size, nwrite_out);
}
common::ErrnoError Client::DoSingleRead(void* out, size_t max_size, size_t* nread) {
return client_->SingleRead(out, max_size, nread);
}
descriptor_t Client::GetFd() const {
return client_->GetInfo().fd();
}
common::ErrnoError Client::DoClose() {
return client_->Close();
}
} // namespace tcp
} // namespace server
} // namespace fastocloud

46
src/server/tcp/client.h Normal file
View file

@ -0,0 +1,46 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <common/libev/tcp/tcp_client.h>
#include <fastotv/protocol/protocol.h>
namespace fastocloud {
namespace server {
namespace tcp {
class Client : public fastotv::protocol::protocol_client_t {
public:
typedef fastotv::protocol::protocol_client_t base_class;
Client(common::libev::IoLoop* server, const common::net::socket_info& info);
const char* ClassName() const override;
protected:
descriptor_t GetFd() const override;
private:
common::ErrnoError DoSingleWrite(const void* data, size_t size, size_t* nwrite_out) override;
common::ErrnoError DoSingleRead(void* out, size_t max_size, size_t* nread) override;
common::ErrnoError DoClose() override;
common::libev::tcp::TcpClient* client_;
};
} // namespace tcp
} // namespace server
} // namespace fastocloud

123
src/server/utils/utils.cpp Normal file
View file

@ -0,0 +1,123 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "server/utils/utils.h"
#include <unistd.h>
namespace {
#if defined(OS_WIN)
int socketpair(int domain, int type, int protocol, SOCKET socks[2]) {
SOCKET listener = socket(domain, type, protocol);
if (listener == INVALID_SOCKET_VALUE) {
return SOCKET_ERROR;
}
struct sockaddr_in addr = {0};
addr.sin_family = domain;
addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
addr.sin_port = 0;
socklen_t addr_size = sizeof(addr);
struct sockaddr_in adr2;
socklen_t adr2_size = sizeof(adr2);
if (bind(listener, (struct sockaddr*)&addr, addr_size) == SOCKET_ERROR) {
goto error;
}
if (getsockname(listener, (struct sockaddr*)&addr, &addr_size) == SOCKET_ERROR) {
goto error;
}
if (listen(listener, 1) == SOCKET_ERROR) {
goto error;
}
socks[0] = socket(domain, type, protocol);
if (socks[0] == INVALID_SOCKET_VALUE) {
goto error;
}
if (connect(socks[0], (struct sockaddr*)&addr, addr_size) == SOCKET_ERROR) {
goto error;
}
socks[1] = accept(listener, nullptr, nullptr);
if (socks[1] == INVALID_SOCKET_VALUE) {
goto error;
}
if (getpeername(socks[0], (struct sockaddr*)&addr, &addr_size)) {
goto error;
}
if (getsockname(socks[1], (struct sockaddr*)&adr2, &adr2_size)) {
goto error;
}
closesocket(listener);
return 0;
error:
closesocket(listener);
closesocket(socks[0]);
closesocket(socks[1]);
return ERROR_RESULT_VALUE;
}
#endif
} // namespace
namespace fastocloud {
namespace server {
#if defined(OS_POSIX)
common::ErrnoError CreatePipe(common::net::socket_descr_t* read_client_fd,
common::net::socket_descr_t* write_client_fd) {
if (!read_client_fd || !write_client_fd) {
return common::make_errno_error_inval();
}
int pipefd[2] = {INVALID_DESCRIPTOR, INVALID_DESCRIPTOR};
int res = pipe(pipefd);
if (res == ERROR_RESULT_VALUE) {
return common::make_errno_error(errno);
}
*read_client_fd = pipefd[0];
*write_client_fd = pipefd[1];
return common::ErrnoError();
}
#endif
common::ErrnoError CreateSocketPair(common::net::socket_descr_t* parent_sock, common::net::socket_descr_t* child_sock) {
if (!parent_sock || !child_sock) {
return common::make_errno_error_inval();
}
common::net::socket_descr_t socks[2];
#if defined(OS_POSIX)
int res = socketpair(AF_LOCAL, SOCK_STREAM, 0, socks);
#else
int res = socketpair(AF_INET, SOCK_STREAM, 0, socks);
#endif
if (res == ERROR_RESULT_VALUE) {
return common::make_errno_error(errno);
}
*parent_sock = socks[1];
*child_sock = socks[0];
return common::ErrnoError();
}
} // namespace server
} // namespace fastocloud

30
src/server/utils/utils.h Normal file
View file

@ -0,0 +1,30 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <common/error.h>
#include <common/net/socket_info.h>
namespace fastocloud {
namespace server {
#if defined(OS_POSIX)
common::ErrnoError CreatePipe(common::net::socket_descr_t* read_client_fd,
common::net::socket_descr_t* write_client_fd);
#endif
common::ErrnoError CreateSocketPair(common::net::socket_descr_t* parent_sock, common::net::socket_descr_t* child_sock);
} // namespace server
} // namespace fastocloud

477
src/stream/CMakeLists.txt Normal file
View file

@ -0,0 +1,477 @@
SET(GLOBAL_HEADERS
${CMAKE_SOURCE_DIR}/src/stream/gst_macros.h
${CMAKE_SOURCE_DIR}/src/stream/gst_types.h
${CMAKE_SOURCE_DIR}/src/stream/stypes.h
${CMAKE_SOURCE_DIR}/src/stream/commands_factory.h
${CMAKE_SOURCE_DIR}/src/stream/ilinker.h
${CMAKE_SOURCE_DIR}/src/stream/ibase_builder.h
${CMAKE_SOURCE_DIR}/src/stream/ibase_builder_observer.h
${CMAKE_SOURCE_DIR}/src/stream/ibase_stream.h
${CMAKE_SOURCE_DIR}/src/stream/probes.h
${CMAKE_SOURCE_DIR}/src/stream/timeshift.h
${CMAKE_SOURCE_DIR}/src/stream/stream_controller.h
${CMAKE_SOURCE_DIR}/src/stream/stream_server.h
${CMAKE_SOURCE_DIR}/src/stream/stream_wrapper.h
${CMAKE_SOURCE_DIR}/src/stream/gstreamer_init.h
${CMAKE_SOURCE_DIR}/src/stream/gstreamer_utils.h
${CMAKE_SOURCE_DIR}/src/stream/streams_factory.h
${CMAKE_SOURCE_DIR}/src/stream/configs_factory.h
${CMAKE_SOURCE_DIR}/src/stream/config.h
)
SET(GLOBAL_SOURCES
${CMAKE_SOURCE_DIR}/src/stream/gst_types.cpp
${CMAKE_SOURCE_DIR}/src/stream/stypes.cpp
${CMAKE_SOURCE_DIR}/src/stream/commands_factory.cpp
${CMAKE_SOURCE_DIR}/src/stream/ilinker.cpp
${CMAKE_SOURCE_DIR}/src/stream/ibase_builder.cpp
${CMAKE_SOURCE_DIR}/src/stream/ibase_builder_observer.cpp
${CMAKE_SOURCE_DIR}/src/stream/ibase_stream.cpp
${CMAKE_SOURCE_DIR}/src/stream/probes.cpp
${CMAKE_SOURCE_DIR}/src/stream/timeshift.cpp
${CMAKE_SOURCE_DIR}/src/stream/stream_controller.cpp
${CMAKE_SOURCE_DIR}/src/stream/stream_server.cpp
${CMAKE_SOURCE_DIR}/src/stream/stream_wrapper.cpp
${CMAKE_SOURCE_DIR}/src/stream/gstreamer_init.cpp
${CMAKE_SOURCE_DIR}/src/stream/gstreamer_utils.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams_factory.cpp
${CMAKE_SOURCE_DIR}/src/stream/configs_factory.cpp
${CMAKE_SOURCE_DIR}/src/stream/config.cpp
)
SET(STREAM_CONFIGS_HEADERS
${CMAKE_SOURCE_DIR}/src/stream/streams/configs/relay_config.h
${CMAKE_SOURCE_DIR}/src/stream/streams/configs/encode_config.h
${CMAKE_SOURCE_DIR}/src/stream/streams/configs/audio_video_config.h
)
SET(STREAM_CONFIGS_SOURCES
${CMAKE_SOURCE_DIR}/src/stream/streams/configs/relay_config.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/configs/encode_config.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/configs/audio_video_config.cpp
)
SET(STREAM_BUILDERS_HEADERS
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/gst_base_builder.h
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/src_decodebin_stream_builder.h
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/relay/relay_stream_builder.h
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/relay/rtsp_stream_builder.h
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/relay/playlist_relay_stream_builder.h
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/encoding/encoding_stream_builder.h
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/encoding/encoding_only_audio_stream_builder.h
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/encoding/encoding_only_video_stream_builder.h
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/encoding/playlist_encoding_stream_builder.h
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/encoding/device_stream_builder.h
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/encoding/rtsp_stream_builder.h
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/encoding/fake_stream_builder.h
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/timeshift/catchup_stream_builder.h
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/timeshift/timeshift_player_stream_builder.h
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/timeshift/timeshift_recorder_stream_builder.h
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/test/test_life_stream_builder.h
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/test/test_input_stream_builder.h
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/display/display_input_stream_builder.h
)
SET(STREAM_BUILDERS_SOURCES
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/gst_base_builder.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/src_decodebin_stream_builder.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/relay/relay_stream_builder.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/relay/rtsp_stream_builder.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/relay/playlist_relay_stream_builder.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/encoding/encoding_stream_builder.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/encoding/encoding_only_audio_stream_builder.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/encoding/encoding_only_video_stream_builder.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/encoding/playlist_encoding_stream_builder.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/encoding/device_stream_builder.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/encoding/rtsp_stream_builder.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/encoding/fake_stream_builder.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/timeshift/catchup_stream_builder.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/timeshift/timeshift_player_stream_builder.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/timeshift/timeshift_recorder_stream_builder.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/test/test_life_stream_builder.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/test/test_input_stream_builder.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/builders/display/display_input_stream_builder.cpp
)
SET(STREAMS_HEADERS
${CMAKE_SOURCE_DIR}/src/stream/streams/src_decodebin_stream.h
${CMAKE_SOURCE_DIR}/src/stream/streams/vod/vod_relay_stream.h
${CMAKE_SOURCE_DIR}/src/stream/streams/relay/relay_stream.h
${CMAKE_SOURCE_DIR}/src/stream/streams/relay/rtsp_relay_stream.h
${CMAKE_SOURCE_DIR}/src/stream/streams/relay/playlist_relay_stream.h
${CMAKE_SOURCE_DIR}/src/stream/streams/vod/vod_encoding_stream.h
${CMAKE_SOURCE_DIR}/src/stream/streams/encoding/encoding_stream.h
${CMAKE_SOURCE_DIR}/src/stream/streams/encoding/encoding_only_audio_stream.h
${CMAKE_SOURCE_DIR}/src/stream/streams/encoding/encoding_only_video_stream.h
${CMAKE_SOURCE_DIR}/src/stream/streams/encoding/playlist_encoding_stream.h
${CMAKE_SOURCE_DIR}/src/stream/streams/encoding/device_stream.h
${CMAKE_SOURCE_DIR}/src/stream/streams/encoding/rtsp_encoding_stream.h
${CMAKE_SOURCE_DIR}/src/stream/streams/encoding/fake_stream.h
${CMAKE_SOURCE_DIR}/src/stream/streams/timeshift/catchup_stream.h
${CMAKE_SOURCE_DIR}/src/stream/streams/timeshift/timeshift_player_stream.h
${CMAKE_SOURCE_DIR}/src/stream/streams/timeshift/itimeshift_recorder_stream.h
${CMAKE_SOURCE_DIR}/src/stream/streams/timeshift/timeshift_recorder_stream.h
${CMAKE_SOURCE_DIR}/src/stream/streams/test/test_life_stream.h
${CMAKE_SOURCE_DIR}/src/stream/streams/test/test_stream.h
${CMAKE_SOURCE_DIR}/src/stream/streams/display/display_stream.h
${STREAM_BUILDERS_HEADERS}
${STREAM_CONFIGS_HEADERS}
)
SET(STREAMS_SOURCES
${CMAKE_SOURCE_DIR}/src/stream/streams/src_decodebin_stream.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/vod/vod_relay_stream.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/relay/relay_stream.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/relay/rtsp_relay_stream.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/relay/playlist_relay_stream.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/vod/vod_encoding_stream.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/encoding/encoding_stream.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/encoding/encoding_only_audio_stream.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/encoding/encoding_only_video_stream.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/encoding/playlist_encoding_stream.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/encoding/device_stream.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/encoding/rtsp_encoding_stream.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/encoding/fake_stream.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/timeshift/catchup_stream.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/timeshift/timeshift_player_stream.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/timeshift/itimeshift_recorder_stream.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/timeshift/timeshift_recorder_stream.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/test/test_life_stream.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/test/test_stream.cpp
${CMAKE_SOURCE_DIR}/src/stream/streams/display/display_stream.cpp
${STREAM_BUILDERS_SOURCES}
${STREAM_CONFIGS_SOURCES}
)
SET(ELEMENTS_SOURCES_HEADERS
${CMAKE_SOURCE_DIR}/src/stream/elements/element.h
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/multifilesrc.h
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/httpsrc.h
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/dvbsrc.h
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/appsrc.h
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/rtmpsrc.h
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/rtspsrc.h
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/udpsrc.h
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/tcpsrc.h
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/srtsrc.h
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/v4l2src.h
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/alsasrc.h
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/filesrc.h
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/build_input.h
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/sources.h
)
SET(ELEMENTS_SOURCES_SOURCES
${CMAKE_SOURCE_DIR}/src/stream/elements/element.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/multifilesrc.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/httpsrc.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/dvbsrc.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/appsrc.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/rtmpsrc.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/rtspsrc.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/udpsrc.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/tcpsrc.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/srtsrc.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/v4l2src.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/alsasrc.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/filesrc.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/build_input.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/sources/sources.cpp
)
SET(ELEMENTS_SINKS_HEADERS
${CMAKE_SOURCE_DIR}/src/stream/elements/sink/rtmp.h
${CMAKE_SOURCE_DIR}/src/stream/elements/sink/udp.h
${CMAKE_SOURCE_DIR}/src/stream/elements/sink/file.h
${CMAKE_SOURCE_DIR}/src/stream/elements/sink/tcp.h
${CMAKE_SOURCE_DIR}/src/stream/elements/sink/srt.h
${CMAKE_SOURCE_DIR}/src/stream/elements/sink/http.h
${CMAKE_SOURCE_DIR}/src/stream/elements/sink/fake.h
${CMAKE_SOURCE_DIR}/src/stream/elements/sink/test.h
${CMAKE_SOURCE_DIR}/src/stream/elements/sink/screen.h
${CMAKE_SOURCE_DIR}/src/stream/elements/sink/build_output.h
${CMAKE_SOURCE_DIR}/src/stream/elements/sink/sink.h
)
SET(ELEMENTS_SINKS_SOURCES
${CMAKE_SOURCE_DIR}/src/stream/elements/sink/rtmp.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/sink/udp.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/sink/file.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/sink/tcp.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/sink/srt.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/sink/http.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/sink/fake.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/sink/test.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/sink/screen.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/sink/build_output.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/sink/sink.cpp
)
SET(ELEMENTS_ENCODERS_HEADERS
${CMAKE_SOURCE_DIR}/src/stream/elements/encoders/audio.h
${CMAKE_SOURCE_DIR}/src/stream/elements/encoders/video.h
)
SET(ELEMENTS_ENCODERS_SOURCES
${CMAKE_SOURCE_DIR}/src/stream/elements/encoders/audio.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/encoders/video.cpp
)
SET(ELEMENTS_PARSER_HEADERS
${CMAKE_SOURCE_DIR}/src/stream/elements/parser/video.h
${CMAKE_SOURCE_DIR}/src/stream/elements/parser/audio.h
${CMAKE_SOURCE_DIR}/src/stream/elements/parser/parser.h
)
SET(ELEMENTS_PARSER_SOURCES
${CMAKE_SOURCE_DIR}/src/stream/elements/parser/video.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/parser/audio.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/parser/parser.cpp
)
SET(ELEMENTS_PAY_HEADERS
${CMAKE_SOURCE_DIR}/src/stream/elements/pay/pay.h
${CMAKE_SOURCE_DIR}/src/stream/elements/pay/video.h
${CMAKE_SOURCE_DIR}/src/stream/elements/pay/audio.h
)
SET(ELEMENTS_PAY_SOURCES
${CMAKE_SOURCE_DIR}/src/stream/elements/pay/pay.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/pay/video.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/pay/audio.cpp
)
SET(ELEMENTS_DEPAY_HEADERS
${CMAKE_SOURCE_DIR}/src/stream/elements/depay/depay.h
${CMAKE_SOURCE_DIR}/src/stream/elements/depay/video.h
${CMAKE_SOURCE_DIR}/src/stream/elements/depay/audio.h
)
SET(ELEMENTS_DEPAY_SOURCES
${CMAKE_SOURCE_DIR}/src/stream/elements/depay/depay.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/depay/video.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/depay/audio.cpp
)
IF(MACHINE_LEARNING AND FASTOML_FOUND)
SET(ELEMENTS_DEEP_LEARNING_HEADERS
${CMAKE_SOURCE_DIR}/src/stream/elements/machine_learning/video_ml_filter.h
${CMAKE_SOURCE_DIR}/src/stream/elements/machine_learning/tinyyolov2.h
${CMAKE_SOURCE_DIR}/src/stream/elements/machine_learning/tinyyolov3.h
${CMAKE_SOURCE_DIR}/src/stream/elements/machine_learning/detectionoverlay.h
)
SET(ELEMENTS_DEEP_LEARNING_SOURCES
${CMAKE_SOURCE_DIR}/src/stream/elements/machine_learning/video_ml_filter.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/machine_learning/tinyyolov2.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/machine_learning/tinyyolov3.cpp
${CMAKE_SOURCE_DIR}/src/stream/elements/machine_learning/detectionoverlay.cpp
)
ENDIF(MACHINE_LEARNING AND FASTOML_FOUND)
SET(ELEMENTS_VIDEO_HEADERS ${CMAKE_SOURCE_DIR}/src/stream/elements/video/video.h)
SET(ELEMENTS_VIDEO_SOURCES ${CMAKE_SOURCE_DIR}/src/stream/elements/video/video.cpp)
SET(ELEMENTS_AUDIO_HEADERS ${CMAKE_SOURCE_DIR}/src/stream/elements/audio/audio.h)
SET(ELEMENTS_AUDIO_SOURCES ${CMAKE_SOURCE_DIR}/src/stream/elements/audio/audio.cpp)
SET(ELEMENTS_MUXER_HEADERS ${CMAKE_SOURCE_DIR}/src/stream/elements/muxer/muxer.h)
SET(ELEMENTS_MUXER_SOURCES ${CMAKE_SOURCE_DIR}/src/stream/elements/muxer/muxer.cpp)
SET(ELEMENTS_HEADERS
${ELEMENTS_DEEP_LEARNING_HEADERS}
${ELEMENTS_MUXER_HEADERS}
${ELEMENTS_PAY_HEADERS}
${ELEMENTS_DEPAY_HEADERS}
${ELEMENTS_PARSER_HEADERS}
${ELEMENTS_ENCODERS_HEADERS}
${ELEMENTS_SINKS_HEADERS}
${ELEMENTS_SOURCES_HEADERS}
${ELEMENTS_VIDEO_HEADERS}
${ELEMENTS_AUDIO_HEADERS}
)
SET(ELEMENTS_SOURCES
${ELEMENTS_DEEP_LEARNING_SOURCES}
${ELEMENTS_MUXER_SOURCES}
${ELEMENTS_PAY_SOURCES}
${ELEMENTS_DEPAY_SOURCES}
${ELEMENTS_PARSER_SOURCES}
${ELEMENTS_ENCODERS_SOURCES}
${ELEMENTS_SINKS_SOURCES}
${ELEMENTS_SOURCES_SOURCES}
${ELEMENTS_VIDEO_SOURCES}
${ELEMENTS_AUDIO_SOURCES}
)
SET(PAD_HEADERS
${CMAKE_SOURCE_DIR}/src/stream/pad/pad.h
)
SET(PAD_SOURCES
${CMAKE_SOURCE_DIR}/src/stream/pad/pad.cpp
)
SET(DUMPERS_HEADERS
${CMAKE_SOURCE_DIR}/src/stream/dumpers/idumper.h
${CMAKE_SOURCE_DIR}/src/stream/dumpers/htmldump.h
${CMAKE_SOURCE_DIR}/src/stream/dumpers/dumpers_factory.h
)
SET(DUMPERS_SOURCES
${CMAKE_SOURCE_DIR}/src/stream/dumpers/htmldump.cpp
${CMAKE_SOURCE_DIR}/src/stream/dumpers/dumpers_factory.cpp
${CMAKE_SOURCE_DIR}/src/stream/dumpers/idumper.cpp
)
FIND_PACKAGE(GLIB REQUIRED gobject)
FIND_PACKAGE(Gstreamer 1.8.0 REQUIRED)
IF(OS_WINDOWS)
SET(PLATFORM_HEADER)
SET(PLATFORM_SOURCES)
SET(PLATFORM_LIBRARIES ws2_32)
ELSEIF(OS_MACOSX)
FIND_LIBRARY(FOUNDATION_LIBRARY Foundation)
SET(PLATFORM_HEADER)
SET(PLATFORM_SOURCES)
SET(PLATFORM_LIBRARIES ${FOUNDATION_LIBRARY})
ELSEIF(OS_POSIX)
SET(PLATFORM_HEADER)
SET(PLATFORM_SOURCES)
SET(PLATFORM_LIBRARIES)
FIND_PACKAGE(X11 REQUIRED)
IF(X11_FOUND)
SET(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} ${X11_LIBRARIES})
SET(DEPENDENS_INCLUDE_DIRS ${DEPENDENS_INCLUDE_DIRS} ${X11_INCLUDE_DIR})
SET(PRIVATE_COMPILE_DEFINITIONS_CORE ${PRIVATE_COMPILE_DEFINITIONS_CORE} HAVE_X11)
ENDIF(X11_FOUND)
ENDIF(OS_WINDOWS)
IF(USE_PTHREAD)
IF(NOT OS_ANDROID)
SET(PLATFORM_LIBRARIES ${PLATFORM_LIBRARIES} pthread)
ENDIF(NOT OS_ANDROID)
ENDIF(USE_PTHREAD)
SET(CLIENT_SOURCES
${GLOBAL_HEADERS} ${GLOBAL_SOURCES}
${STREAMS_HEADERS} ${STREAMS_SOURCES}
${ELEMENTS_HEADERS} ${ELEMENTS_SOURCES}
${PAD_HEADERS} ${PAD_SOURCES}
${PLATFORM_HEADER} ${PLATFORM_SOURCES}
${DUMPERS_HEADERS} ${DUMPERS_SOURCES}
)
SET(CLIENT_LIBRARIES
${CLIENT_LIBRARIES}
${GLIB_LIBRARIES} ${GLIB_GOBJECT_LIBRARIES}
${GSTREAMER_LIBRARIES} ${GSTREAMER_APP_LIBRARY} ${GSTREAMER_VIDEO_LIBRARY}
${FASTOML_LIBRARIES}
${COMMON_LIBRARIES}
${STREAMER_COMMON}
${PLATFORM_LIBRARIES}
)
SET(PRIVATE_COMPILE_DEFINITIONS_CORE
${PRIVATE_COMPILE_DEFINITIONS_CORE}
)
SET(PRIVATE_INCLUDE_DIRECTORIES_CORE
${PRIVATE_INCLUDE_DIRECTORIES_CORE}
${CMAKE_SOURCE_DIR}/src
${GSTREAMER_INCLUDE_DIR}
${GLIB_INCLUDE_DIR}
${GLIBCONFIG_INCLUDE_DIR}
${DEPENDENS_INCLUDE_DIRS}
# ${JSONC_INCLUDE_DIRS}
${COMMON_INCLUDE_DIRS}
)
ADD_LIBRARY(${STREAMER_CORE} SHARED ${CLIENT_SOURCES})
TARGET_INCLUDE_DIRECTORIES(${STREAMER_CORE} PRIVATE ${PRIVATE_INCLUDE_DIRECTORIES_CORE})
TARGET_COMPILE_DEFINITIONS(${STREAMER_CORE} PRIVATE ${PRIVATE_COMPILE_DEFINITIONS_CORE})
TARGET_LINK_LIBRARIES(${STREAMER_CORE} ${CLIENT_LIBRARIES})
IF(PROJECT_BUILD_TYPE_VERSION STREQUAL "release")
STRIP_TARGET(${STREAMER_CORE})
ENDIF(PROJECT_BUILD_TYPE_VERSION STREQUAL "release")
INSTALL(TARGETS ${STREAMER_CORE} DESTINATION ${LIB_INSTALL_DESTINATION} COMPONENT APPLICATIONS)
IF (DEVELOPER_CHECK_STYLE)
SET(CHECK_SOURCES ${CLIENT_SOURCES})
REGISTER_CHECK_STYLE_TARGET(check_style_${STREAMER_CORE} "${CHECK_SOURCES}")
REGISTER_CHECK_INCLUDES_TARGET(${STREAMER_CORE})
ENDIF(DEVELOPER_CHECK_STYLE)
IF(DEVELOPER_ENABLE_TESTS)
FIND_PACKAGE(GTest REQUIRED)
## Unit tests
SET(PRIVATE_INCLUDE_DIRECTORIES_UNIT_TESTS
${PRIVATE_INCLUDE_DIRECTORIES_UNIT_TESTS}
${CMAKE_SOURCE_DIR}/src
${GSTREAMER_INCLUDE_DIR}
${GLIB_INCLUDE_DIR}
${GLIBCONFIG_INCLUDE_DIR}
)
SET(UNIT_TESTS_LIBS
${GTEST_BOTH_LIBRARIES}
${STREAMER_COMMON}
${PLATFORM_LIBRARIES} ${STREAMER_CORE})
SET(UNIT_TESTS unit_tests_stream)
ADD_EXECUTABLE(${UNIT_TESTS}
${CMAKE_SOURCE_DIR}/tests/stream/unit_test_link_gen.cpp
${CMAKE_SOURCE_DIR}/tests/stream/unit_test_types.cpp
${CMAKE_SOURCE_DIR}/tests/stream/unit_test_api.cpp
)
TARGET_INCLUDE_DIRECTORIES(${UNIT_TESTS} PRIVATE ${PRIVATE_INCLUDE_DIRECTORIES_UNIT_TESTS} ${JSONC_INCLUDE_DIRS})
TARGET_LINK_LIBRARIES(${UNIT_TESTS} ${UNIT_TESTS_LIBS})
ADD_TEST_TARGET(${UNIT_TESTS})
SET_PROPERTY(TARGET ${UNIT_TESTS} PROPERTY FOLDER "Unit tests")
## Mock tests
SET(PRIVATE_INCLUDE_DIRECTORIES_MOCK_TESTS
${PRIVATE_INCLUDE_DIRECTORIES_MOCK_TESTS}
${CMAKE_SOURCE_DIR}/src
${GSTREAMER_INCLUDE_DIR}
${GLIB_INCLUDE_DIR}
${GLIBCONFIG_INCLUDE_DIR}
)
SET(GMOCK_TESTS_LIBS ${GTEST_BOTH_LIBRARIES} gmock ${STREAMER_CORE})
ADD_EXECUTABLE(gmock_tests
${CMAKE_SOURCE_DIR}/tests/stream/mock_test_job.cpp
)
TARGET_INCLUDE_DIRECTORIES(gmock_tests PRIVATE ${PRIVATE_INCLUDE_DIRECTORIES_MOCK_TESTS})
TARGET_LINK_LIBRARIES(gmock_tests ${GMOCK_TESTS_LIBS})
ADD_TEST_TARGET(gmock_tests)
SET_PROPERTY(TARGET gmock_tests PROPERTY FOLDER "Mock tests")
# Workflow tests
SET(PRIVATE_INCLUDE_DIRECTORIES_WORKFLOW_TESTS
${PRIVATE_INCLUDE_DIRECTORIES_WORKFLOW_TESTS}
${CMAKE_SOURCE_DIR}/src
${GSTREAMER_INCLUDE_DIR}
${GLIB_INCLUDE_DIR}
${GLIBCONFIG_INCLUDE_DIR}
)
SET(WORKFLOW_TESTS_LIBS ${STREAMER_CORE})
ADD_EXECUTABLE(workflow_tests ${CMAKE_SOURCE_DIR}/tests/stream/workflow_tests.cpp)
TARGET_INCLUDE_DIRECTORIES(workflow_tests PRIVATE ${PRIVATE_INCLUDE_DIRECTORIES_WORKFLOW_TESTS})
TARGET_COMPILE_DEFINITIONS(workflow_tests PRIVATE -DPROJECT_TEST_SOURCES_DIR="${CMAKE_SOURCE_DIR}/tests")
TARGET_LINK_LIBRARIES(workflow_tests ${WORKFLOW_TESTS_LIBS})
SET_PROPERTY(TARGET workflow_tests PROPERTY FOLDER "Workflow tests")
ENDIF(DEVELOPER_ENABLE_TESTS)

View file

@ -0,0 +1,71 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "stream/commands_factory.h"
#include <string>
#include "stream_commands/commands.h"
namespace fastocloud {
common::Error ChangedSourcesStreamBroadcast(const ChangedSouresInfo& params, fastotv::protocol::request_t* req) {
if (!req) {
return common::make_error_inval();
}
std::string req_str;
common::Error err_ser = params.SerializeToString(&req_str);
if (err_ser) {
return err_ser;
}
*req = fastotv::protocol::request_t::MakeNotification(CHANGED_SOURCES_STREAM, req_str);
return common::Error();
}
common::Error StatisticStreamBroadcast(const StatisticInfo& params, fastotv::protocol::request_t* req) {
if (!req) {
return common::make_error_inval();
}
std::string req_str;
common::Error err_ser = params.SerializeToString(&req_str);
if (err_ser) {
return err_ser;
}
*req = fastotv::protocol::request_t::MakeNotification(STATISTIC_STREAM, req_str);
return common::Error();
}
#if defined(MACHINE_LEARNING)
common::Error NotificationMlStreamBroadcast(const fastotv::commands_info::ml::NotificationInfo& params,
fastotv::protocol::request_t* req) {
if (!req) {
return common::make_error_inval();
}
std::string req_str;
common::Error err_ser = params.SerializeToString(&req_str);
if (err_ser) {
return err_ser;
}
*req = fastotv::protocol::request_t::MakeNotification(ML_NOTIFICATION_STREAM, req_str);
return common::Error();
}
#endif
} // namespace fastocloud

View file

@ -0,0 +1,37 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <fastotv/protocol/types.h>
#include "stream_commands/commands_info/changed_sources_info.h"
#include "stream_commands/commands_info/statistic_info.h"
#if defined(MACHINE_LEARNING)
#include <fastotv/commands_info/ml/notification_info.h>
#endif
namespace fastocloud {
// Broadcast
common::Error ChangedSourcesStreamBroadcast(const ChangedSouresInfo& params, fastotv::protocol::request_t* req);
common::Error StatisticStreamBroadcast(const StatisticInfo& params, fastotv::protocol::request_t* req);
#if defined(MACHINE_LEARNING)
common::Error NotificationMlStreamBroadcast(const fastotv::commands_info::ml::NotificationInfo& params,
fastotv::protocol::request_t* req);
#endif
} // namespace fastocloud

66
src/stream/config.cpp Normal file
View file

@ -0,0 +1,66 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "stream/config.h"
namespace fastocloud {
namespace stream {
Config::Config(fastotv::StreamType type, size_t max_restart_attempts, const input_t& input, const output_t& output)
: type_(type), max_restart_attempts_(max_restart_attempts), ttl_sec_(), input_(input), output_(output) {}
Config::~Config() {}
fastotv::StreamType Config::GetType() const {
return type_;
}
input_t Config::GetInput() const {
return input_;
}
void Config::SetInput(const input_t& input) {
input_ = input;
}
output_t Config::GetOutput() const {
return output_;
}
void Config::SetOutput(const output_t& output) {
output_ = output;
}
size_t Config::GetMaxRestartAttempts() const {
return max_restart_attempts_;
}
void Config::SetMaxRestartAttempts(size_t attempts) {
max_restart_attempts_ = attempts;
}
const Config::ttl_t& Config::GetTimeToLifeStream() const {
return ttl_sec_;
}
void Config::SetTimeToLifeStream(const ttl_t& ttl) {
ttl_sec_ = ttl;
}
Config* Config::Clone() const {
return new Config(*this);
}
} // namespace stream
} // namespace fastocloud

57
src/stream/config.h Normal file
View file

@ -0,0 +1,57 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "base/types.h"
#include <fastotv/types/stream_ttl.h>
namespace fastocloud {
namespace stream {
class Config : public common::ClonableBase<Config> {
public:
enum { report_delay_sec = 10 };
typedef common::Optional<fastotv::StreamTTL> ttl_t;
Config(fastotv::StreamType type, size_t max_restart_attempts, const input_t& input, const output_t& output);
virtual ~Config();
fastotv::StreamType GetType() const;
input_t GetInput() const; // all except timeshift_play
void SetInput(const input_t& input);
output_t GetOutput() const; // all except timeshift_rec
void SetOutput(const output_t& output);
size_t GetMaxRestartAttempts() const;
void SetMaxRestartAttempts(size_t attempts);
const ttl_t& GetTimeToLifeStream() const;
void SetTimeToLifeStream(const ttl_t& ttl);
Config* Clone() const override;
private:
fastotv::StreamType type_;
size_t max_restart_attempts_;
ttl_t ttl_sec_;
input_t input_;
output_t output_;
};
} // namespace stream
} // namespace fastocloud

View file

@ -0,0 +1,315 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "stream/configs_factory.h"
#include <string>
#include <common/sprintf.h>
#include <fastotv/types/utils.h>
#include "base/config_fields.h"
#include "base/link_generator/ilink_generator.h"
#include "stream/streams/configs/encode_config.h"
#include "stream/streams/configs/relay_config.h"
namespace fastocloud {
namespace stream {
namespace {
const size_t kDefaultRestartAttempts = 10;
} // namespace
common::Error make_config(const StreamConfig& config_args, Config** config) {
if (!config_args || !config) {
return common::make_error_inval();
}
int64_t type;
common::Value* type_field = config_args->Find(TYPE_FIELD);
if (!type_field || !type_field->GetAsInteger64(&type)) {
return common::make_error("Define " TYPE_FIELD " variable and make it valid");
}
fastotv::StreamType stream_type = static_cast<fastotv::StreamType>(type);
if (stream_type == fastotv::PROXY || stream_type == fastotv::VOD_PROXY) {
return common::make_error("Proxy streams not handled for now");
}
const auto input_urls = ReadInput(config_args);
if (!input_urls) {
return common::make_error("Define " INPUT_FIELD " variable and make it valid");
}
const auto output_urls = ReadOutput(config_args);
if (!output_urls) {
return common::make_error("Define " OUTPUT_FIELD " variable and make it valid");
}
int64_t max_restart_attempts;
common::Value* restart_attempts_field = config_args->Find(RESTART_ATTEMPTS_FIELD);
if (!restart_attempts_field || restart_attempts_field->GetAsInteger64(&max_restart_attempts)) {
max_restart_attempts = kDefaultRestartAttempts;
}
CHECK(max_restart_attempts > 0) << "restart attempts must be grether than 0";
Config conf(static_cast<fastotv::StreamType>(stream_type), max_restart_attempts, *input_urls, *output_urls);
conf.SetTimeToLifeStream(GetTTL(config_args));
streams::AudioVideoConfig aconf(conf);
bool have_video;
common::Value* have_video_field = config_args->Find(HAVE_VIDEO_FIELD);
if (have_video_field && have_video_field->GetAsBoolean(&have_video)) {
aconf.SetHaveVideo(have_video);
}
bool have_audio;
common::Value* have_audio_field = config_args->Find(HAVE_AUDIO_FIELD);
if (have_audio_field && have_audio_field->GetAsBoolean(&have_audio)) {
aconf.SetHaveAudio(have_audio);
}
bool have_subtitle;
common::Value* have_subtitle_field = config_args->Find(HAVE_SUBTITLE_FIELD);
if (have_subtitle_field && have_subtitle_field->GetAsBoolean(&have_subtitle)) {
aconf.SetHaveSubtitle(have_subtitle);
}
int64_t audio_select;
common::Value* audio_select_field = config_args->Find(AUDIO_SELECT_FIELD);
if (audio_select_field && audio_select_field->GetAsInteger64(&audio_select)) {
aconf.SetAudioSelect(audio_select);
}
bool loop;
common::Value* loop_field = config_args->Find(LOOP_FIELD);
if (loop_field && loop_field->GetAsBoolean(&loop)) {
aconf.SetLoop(loop);
}
if (stream_type == fastotv::RELAY || stream_type == fastotv::TIMESHIFT_PLAYER || stream_type == fastotv::TEST_LIFE ||
stream_type == fastotv::VOD_RELAY || stream_type == fastotv::COD_RELAY) {
streams::RelayConfig* rconfig = new streams::RelayConfig(aconf);
std::string video_parser;
common::Value* video_parser_field = config_args->Find(VIDEO_PARSER_FIELD);
if (video_parser_field && video_parser_field->GetAsBasicString(&video_parser)) {
rconfig->SetVideoParser(video_parser);
}
std::string audio_parser;
common::Value* audio_parser_field = config_args->Find(AUDIO_PARSER_FIELD);
if (audio_parser_field && audio_parser_field->GetAsBasicString(&audio_parser)) {
rconfig->SetAudioParser(audio_parser);
}
if (stream_type == fastotv::VOD_RELAY) {
streams::VodRelayConfig* vconf = new streams::VodRelayConfig(*rconfig);
delete rconfig;
rconfig = vconf;
bool cleanup_ts;
common::Value* cleanup_ts_field = config_args->Find(CLEANUP_TS_FIELD);
if (cleanup_ts_field && cleanup_ts_field->GetAsBoolean(&cleanup_ts)) {
vconf->SetCleanupTS(cleanup_ts);
}
}
*config = rconfig;
return common::Error();
} else if (stream_type == fastotv::ENCODE || stream_type == fastotv::VOD_ENCODE ||
stream_type == fastotv::COD_ENCODE || stream_type == fastotv::EVENT) {
streams::EncodeConfig* econfig = new streams::EncodeConfig(aconf);
bool relay_audio;
common::Value* relay_audio_field = config_args->Find(RELAY_AUDIO_FIELD);
if (relay_audio_field && relay_audio_field->GetAsBoolean(&relay_audio)) {
econfig->SetRelayAudio(relay_audio);
}
bool relay_video;
common::Value* relay_video_field = config_args->Find(RELAY_VIDEO_FIELD);
if (relay_video_field && relay_video_field->GetAsBoolean(&relay_video)) {
econfig->SetRelayVideo(relay_video);
}
bool deinterlace;
common::Value* deinterlace_field = config_args->Find(DEINTERLACE_FIELD);
if (deinterlace_field && deinterlace_field->GetAsBoolean(&deinterlace)) {
econfig->SetDeinterlace(deinterlace);
}
common::media::Rational frame_rate;
common::Value* frame_field = config_args->Find(FRAME_RATE_FIELD);
std::string frame_str;
if (frame_field && frame_field->GetAsBasicString(&frame_str) && common::ConvertFromString(frame_str, &frame_rate)) {
econfig->SetFrameRate(frame_rate);
}
double volume;
common::Value* volume_field = config_args->Find(VOLUME_FIELD);
if (volume_field && volume_field->GetAsDouble(&volume)) {
econfig->SetVolume(volume);
}
std::string video_codec;
common::Value* video_codec_field = config_args->Find(VIDEO_CODEC_FIELD);
if (video_codec_field && video_codec_field->GetAsBasicString(&video_codec)) {
econfig->SetVideoEncoder(video_codec);
}
std::string audio_codec;
common::Value* audio_codec_field = config_args->Find(AUDIO_CODEC_FIELD);
if (audio_codec_field && audio_codec_field->GetAsBasicString(&audio_codec)) {
econfig->SetAudioEncoder(audio_codec);
}
int64_t audio_channels;
common::Value* audio_channels_field = config_args->Find(AUDIO_CHANNELS_FIELD);
if (audio_channels_field && audio_channels_field->GetAsInteger64(&audio_channels)) {
econfig->SetAudioChannelsCount(audio_channels);
}
common::HashValue* size_hash = nullptr;
common::Value* size_field = config_args->Find(SIZE_FIELD);
if (size_field && size_field->GetAsHash(&size_hash)) {
auto size = fastotv::MakeSize(size_hash);
econfig->SetSize(size);
}
int64_t v_bitrate;
common::Value* video_bitrate_field = config_args->Find(VIDEO_BIT_RATE_FIELD);
if (video_bitrate_field && video_bitrate_field->GetAsInteger64(&v_bitrate)) {
econfig->SetVideoBitrate(v_bitrate);
}
int64_t a_bitrate;
common::Value* audio_bitrate_field = config_args->Find(AUDIO_BIT_RATE_FIELD);
if (audio_bitrate_field && audio_bitrate_field->GetAsInteger64(&a_bitrate)) {
econfig->SetAudioBitrate(a_bitrate);
}
#if defined(MACHINE_LEARNING)
common::HashValue* deep_learning_hash = nullptr;
common::Value* deep_learning_field = config_args->Find(DEEP_LEARNING_FIELD);
if (deep_learning_field && deep_learning_field->GetAsHash(&deep_learning_hash)) {
auto deep_learning = machine_learning::DeepLearning::MakeDeepLearning(deep_learning_hash);
if (deep_learning) {
econfig->SetDeepLearning(*deep_learning);
}
}
common::HashValue* deep_learning_overlay_hash = nullptr;
common::Value* deep_learning_overlay_field = config_args->Find(DEEP_LEARNING_OVERLAY_FIELD);
if (deep_learning_overlay_field && deep_learning_overlay_field->GetAsHash(&deep_learning_overlay_hash)) {
auto deep_learning_overlay =
machine_learning::DeepLearningOverlay::MakeDeepLearningOverlay(deep_learning_overlay_hash);
if (deep_learning_overlay) {
econfig->SetDeepLearningOverlay(*deep_learning_overlay);
}
}
#endif
common::HashValue* logo_hash = nullptr;
common::Value* logo_field = config_args->Find(LOGO_FIELD);
if (logo_field && logo_field->GetAsHash(&logo_hash)) {
auto logo = fastotv::Logo::Make(logo_hash);
econfig->SetLogo(logo);
}
common::HashValue* rsvg_logo_hash = nullptr;
common::Value* rsvg_logo_field = config_args->Find(RSVG_LOGO_FIELD);
if (rsvg_logo_field && rsvg_logo_field->GetAsHash(&rsvg_logo_hash)) {
auto logo = fastotv::RSVGLogo::Make(rsvg_logo_hash);
econfig->SetRSVGLogo(logo);
}
common::HashValue* rat_hash = nullptr;
common::Value* rat_field = config_args->Find(ASPECT_RATIO_FIELD);
if (rat_field && rat_field->GetAsHash(&rat_hash)) {
auto rat = fastotv::MakeRational(rat_hash);
econfig->SetAspectRatio(rat);
}
int64_t decl_vm;
common::Value* decl_vm_field = config_args->Find(DECKLINK_VIDEO_MODE_FIELD);
if (decl_vm_field && decl_vm_field->GetAsInteger64(&decl_vm)) {
econfig->SetDecklinkMode(decl_vm);
}
if (stream_type == fastotv::VOD_ENCODE) {
streams::VodEncodeConfig* vconf = new streams::VodEncodeConfig(*econfig);
delete econfig;
econfig = vconf;
bool cleanup_ts;
common::Value* cleanup_ts_field = config_args->Find(CLEANUP_TS_FIELD);
if (cleanup_ts_field && cleanup_ts_field->GetAsBoolean(&cleanup_ts)) {
vconf->SetCleanupTS(cleanup_ts);
}
}
*config = econfig;
return common::Error();
} else if (stream_type == fastotv::TIMESHIFT_RECORDER || stream_type == fastotv::CATCHUP) {
streams::RelayConfig rel(aconf);
std::string video_parser;
common::Value* video_parser_field = config_args->Find(VIDEO_PARSER_FIELD);
if (video_parser_field && video_parser_field->GetAsBasicString(&video_parser)) {
rel.SetVideoParser(video_parser);
}
std::string audio_parser;
common::Value* audio_parser_field = config_args->Find(AUDIO_PARSER_FIELD);
if (audio_parser_field && audio_parser_field->GetAsBasicString(&audio_parser)) {
rel.SetAudioParser(audio_parser);
}
streams::TimeshiftConfig* tconf = new streams::TimeshiftConfig(rel);
int64_t timeshift_chunk_duration;
common::Value* timeshift_chunk_duration_field = config_args->Find(TIMESHIFT_CHUNK_DURATION_FIELD);
if (timeshift_chunk_duration_field && timeshift_chunk_duration_field->GetAsInteger64(&timeshift_chunk_duration)) {
tconf->SetTimeShiftChunkDuration(timeshift_chunk_duration);
}
CHECK(tconf->GetTimeShiftChunkDuration()) << "Avoid division by zero";
*config = tconf;
return common::Error();
}
return common::make_error(common::MemSPrintf("Unhandled stream type: %d", stream_type));
}
Config* make_config_copy(const Config* conf, const link_generator::ILinkGenerator* generator) {
Config* copy = conf->Clone();
if (generator) {
input_t input = copy->GetInput();
for (size_t i = 0; i < input.size(); ++i) {
fastotv::InputUri url;
if (generator->Generate(input[i], &url)) {
input[i] = url;
DEBUG_LOG() << "Generated url: " << url.GetUrl().spec();
}
}
copy->SetInput(input);
}
return copy;
}
} // namespace stream
} // namespace fastocloud

View file

@ -0,0 +1,31 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include "base/stream_config.h"
namespace fastocloud {
namespace link_generator {
class ILinkGenerator;
}
namespace stream {
class Config;
common::Error make_config(const StreamConfig& config_args, Config** config) WARN_UNUSED_RESULT;
Config* make_config_copy(const Config* conf, const link_generator::ILinkGenerator* generator) WARN_UNUSED_RESULT;
} // namespace stream
} // namespace fastocloud

View file

@ -0,0 +1,44 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#include "stream/dumpers/dumpers_factory.h"
#include <string>
#include <common/string_util.h>
#include "stream/dumpers/htmldump.h"
#define HTML_FORMAT "html"
namespace fastocloud {
namespace stream {
namespace dumper {
IDumper* DumpersFactory::CreateDumper(const common::file_system::ascii_file_string_path& path) {
if (!path.IsValid()) {
return nullptr;
}
std::string ext = path.GetExtension();
if (common::EqualsASCII(ext, HTML_FORMAT, false)) {
return new HtmlDump;
}
return new HtmlDump;
}
} // namespace dumper
} // namespace stream
} // namespace fastocloud

View file

@ -0,0 +1,34 @@
/* Copyright (C) 2014-2022 FastoGT. All right reserved.
This file is part of fastocloud.
fastocloud is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
fastocloud 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with fastocloud. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once
#include <common/patterns/singleton_pattern.h>
#include "stream/dumpers/idumper.h"
namespace fastocloud {
namespace stream {
namespace dumper {
class DumpersFactory : public common::patterns::LazySingleton<DumpersFactory> {
public:
friend class common::patterns::LazySingleton<DumpersFactory>;
IDumper* CreateDumper(const common::file_system::ascii_file_string_path& path);
};
} // namespace dumper
} // namespace stream
} // namespace fastocloud

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