- Added support for the placeholder <client_ip_address> for ADD and REMOVE commands resolving to the client ip address of the AMCP connection.
}
}
-bool parameters::has(std::wstring const& parameter) const
+void parameters::replace_placeholders(
+ const std::wstring& placeholder, const std::wstring& replacement)
+{
+ for (size_t i = 0; i < params_.size(); ++i)
+ {
+ auto& param = params_.at(i);
+ auto& param_original = params_original_.at(i);
+
+ if (boost::contains(param, placeholder))
+ {
+ boost::replace_all(
+ param, placeholder, boost::to_upper_copy(replacement));
+ boost::ireplace_all(param_original, placeholder, replacement);
+ }
+ }
+}
+
+bool parameters::has(const std::wstring& parameter) const
{
return boost::range::find(params_, parameter) != params_.end();
}
-bool parameters::remove_if_exists(std::wstring const& key)
+bool parameters::remove_if_exists(const std::wstring& key)
{
auto iter = boost::range::find(params_, key);
return true;
}
-std::vector<std::wstring> parameters::protocol_split(std::wstring const& s)
+std::vector<std::wstring> parameters::protocol_split(const std::wstring& s)
{
std::vector<std::wstring> result;
size_t pos;
return result;
}
-std::wstring parameters::get(std::wstring const& key, std::wstring const& default_value) const
+std::wstring parameters::get(
+ const std::wstring& key, const std::wstring& default_value) const
{
auto it = std::find(std::begin(params_), std::end(params_), key);
if (it == params_.end() || ++it == params_.end())
return params_original_.at(i);
}
-void parameters::set(size_t index, std::wstring const& value)
+void parameters::set(size_t index, const std::wstring& value)
{
if (index < params_.size())
{
public:
parameters() {}
- explicit parameters(std::vector<std::wstring> const& params);
+ explicit parameters(const std::vector<std::wstring>& params);
- std::vector<std::wstring> const& get_params() const {
+ const std::vector<std::wstring>& get_params() const {
return params_;
}
- static std::vector<std::wstring> protocol_split(std::wstring const& s);
+ static std::vector<std::wstring> protocol_split(const std::wstring& s);
void to_upper();
+
+ void replace_placeholders(
+ const std::wstring& placeholder, const std::wstring& replacement);
- bool has(std::wstring const& key) const;
- bool remove_if_exists(std::wstring const& key);
+ bool has(const std::wstring& key) const;
+ bool remove_if_exists(const std::wstring& key);
template<typename C>
- typename std::enable_if<!std::is_convertible<C, std::wstring>::value, typename std::decay<C>::type>::type get(std::wstring const& key, C default_value = C()) const
+ typename std::enable_if<!std::is_convertible<C, std::wstring>::value, typename std::decay<C>::type>::type get(const std::wstring& key, C default_value = C()) const
{
auto it = std::find(std::begin(params_), std::end(params_), key);
if(it == params_.end() || ++it == params_.end())
return value;
}
- std::wstring get(std::wstring const& key, std::wstring const& default_value = L"") const;
+ std::wstring get(const std::wstring& key, const std::wstring& default_value = L"") const;
std::wstring get_original_string(int num_skip = 0) const;
const std::wstring& at_original(size_t i) const;
- void set(size_t index, std::wstring const& value);
+ void set(size_t index, const std::wstring& value);
const std::vector<std::wstring>& get_original() const
{
}
// Compatibility method
- void push_back(std::wstring const& s)
+ void push_back(const std::wstring& s)
{
params_.push_back(s);
params_original_.push_back(s);
}
// Compatibility method
- std::wstring const& at(int i) const
+ const std::wstring& at(int i) const
{
return params_.at(i);
}
// Compatibility method
- std::wstring const& back() const
+ const std::wstring& back() const
{
return params_.back();
}
}
// Compatibility method
- std::wstring const& operator [] (size_t i) const
+ const std::wstring& operator [] (size_t i) const
{
return params_[i];
}
#include <boost/format.hpp>
#include <boost/algorithm/string/predicate.hpp>
+#pragma warning(push)
+#pragma warning(disable: 4244)
+#pragma warning(disable: 4245)
+#include <boost/crc.hpp>
+#pragma warning(pop)
+
#include <tbb/atomic.h>
#include <tbb/concurrent_queue.h>
#include <tbb/parallel_invoke.h>
using namespace Concurrency;
namespace caspar { namespace ffmpeg {
-
+
+int crc16(const std::string& str)
+{
+ boost::crc_16_type result;
+
+ result.process_bytes(str.data(), str.length());
+
+ return result.checksum();
+}
+
class streaming_consumer sealed : public core::frame_consumer
{
public:
private:
boost::filesystem::path path_;
+ int consumer_index_offset_;
std::map<std::string, std::string> options_;
streaming_consumer(
std::string path,
std::string options)
- : path_(std::move(path))
+ : path_(path)
+ , consumer_index_offset_(crc16(path))
, video_pts_(0)
, audio_pts_(0)
, executor_(print())
int index() const override
{
- return 200;
+ return 100000 + consumer_index_offset_;
}
int64_t presentation_frame_age_millis() const override
//Perform loading of the clip\r
try\r
{\r
+ _parameters.replace_placeholders(\r
+ L"<CLIENT_IP_ADDRESS>",\r
+ this->GetClientInfo()->print());\r
+\r
auto consumer = create_consumer(_parameters);\r
GetChannel()->output()->add(GetLayerIndex(consumer->index()), consumer);\r
\r
try\r
{\r
auto index = GetLayerIndex(std::numeric_limits<int>::min());\r
- if(index == std::numeric_limits<int>::min())\r
+\r
+ if (index == std::numeric_limits<int>::min())\r
+ {\r
+ _parameters.replace_placeholders(\r
+ L"<CLIENT_IP_ADDRESS>",\r
+ this->GetClientInfo()->print());\r
+\r
index = create_consumer(_parameters)->index();\r
+ }\r
\r
GetChannel()->output()->remove(index);\r
\r