Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add _or_defaults versions of the format-specific parameters parsing functions #426

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 30 additions & 19 deletions Development/nmos/sdp_utils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1284,34 +1284,33 @@ namespace nmos
}

// Get additional "video/raw" parameters from the SDP parameters
video_raw_parameters get_video_raw_parameters(const sdp_parameters& sdp_params)
template <typename MissingRequiredParameter>
video_raw_parameters get_video_raw_parameters(const sdp_parameters& sdp_params, MissingRequiredParameter missing = MissingRequiredParameter{})
{
video_raw_parameters params;

if (sdp_params.fmtp.empty()) throw details::sdp_processing_error("missing attribute: fmtp");

// See SMPTE ST 2110-20:2017 Section 7.2 Required Media Type Parameters
// and Section 7.3 Media Type Parameters with default values

const auto sampling = details::find_fmtp(sdp_params.fmtp, sdp::fields::sampling);
if (sdp_params.fmtp.end() == sampling) throw details::sdp_processing_error("missing format parameter: sampling");
params.sampling = sdp::sampling{ sampling->second };
if (sdp_params.fmtp.end() != sampling) params.sampling = sdp::sampling{ sampling->second };
else missing(sdp::fields::sampling);

const auto depth = details::find_fmtp(sdp_params.fmtp, sdp::fields::depth);
if (sdp_params.fmtp.end() == depth) throw details::sdp_processing_error("missing format parameter: depth");
params.depth = utility::istringstreamed<uint32_t>(depth->second);
if (sdp_params.fmtp.end() != depth) params.depth = utility::istringstreamed<uint32_t>(depth->second);
else missing(sdp::fields::depth);

const auto width = details::find_fmtp(sdp_params.fmtp, sdp::fields::width);
if (sdp_params.fmtp.end() == width) throw details::sdp_processing_error("missing format parameter: width");
params.width = utility::istringstreamed<uint32_t>(width->second);
if (sdp_params.fmtp.end() != width) params.width = utility::istringstreamed<uint32_t>(width->second);
else missing(sdp::fields::width);

const auto height = details::find_fmtp(sdp_params.fmtp, sdp::fields::height);
if (sdp_params.fmtp.end() == height) throw details::sdp_processing_error("missing format parameter: height");
params.height = utility::istringstreamed<uint32_t>(height->second);
if (sdp_params.fmtp.end() != height) params.height = utility::istringstreamed<uint32_t>(height->second);
else missing(sdp::fields::height);

const auto exactframerate = details::find_fmtp(sdp_params.fmtp, sdp::fields::exactframerate);
if (sdp_params.fmtp.end() == exactframerate) throw details::sdp_processing_error("missing format parameter: exactframerate");
params.exactframerate = nmos::details::parse_exactframerate(exactframerate->second);
if (sdp_params.fmtp.end() != exactframerate) params.exactframerate = nmos::details::parse_exactframerate(exactframerate->second);
else missing(sdp::fields::exactframerate);

// optional
const auto interlace = details::find_fmtp(sdp_params.fmtp, sdp::fields::interlace);
Expand All @@ -1326,8 +1325,8 @@ namespace nmos
if (sdp_params.fmtp.end() != tcs) params.tcs = sdp::transfer_characteristic_system{ tcs->second };

const auto colorimetry = details::find_fmtp(sdp_params.fmtp, sdp::fields::colorimetry);
if (sdp_params.fmtp.end() == colorimetry) throw details::sdp_processing_error("missing format parameter: colorimetry");
params.colorimetry = sdp::colorimetry{ colorimetry->second };
if (sdp_params.fmtp.end() != colorimetry) params.colorimetry = sdp::colorimetry{ colorimetry->second };
else missing(sdp::fields::colorimetry);

// optional
const auto range = details::find_fmtp(sdp_params.fmtp, sdp::fields::range);
Expand All @@ -1338,12 +1337,12 @@ namespace nmos
if (sdp_params.fmtp.end() != par) params.par = nmos::details::parse_pixel_aspect_ratio(par->second);

const auto pm = details::find_fmtp(sdp_params.fmtp, sdp::fields::packing_mode);
if (sdp_params.fmtp.end() == pm) throw details::sdp_processing_error("missing format parameter: PM");
params.pm = sdp::packing_mode{ pm->second };
if (sdp_params.fmtp.end() != pm) params.pm = sdp::packing_mode{ pm->second };
else missing(sdp::fields::packing_mode);

const auto ssn = details::find_fmtp(sdp_params.fmtp, sdp::fields::smpte_standard_number);
if (sdp_params.fmtp.end() == ssn) throw details::sdp_processing_error("missing format parameter: SSN");
params.ssn = sdp::smpte_standard_number{ ssn->second };
if (sdp_params.fmtp.end() != ssn) params.ssn = sdp::smpte_standard_number{ ssn->second };
else missing(sdp::fields::smpte_standard_number);

// "Senders and Receivers compliant to [ST 2110-20] shall comply with the provisions of SMPTE ST 2110-21."
// See SMPTE ST 2110-20:2017 Section 6.1.1
Expand Down Expand Up @@ -1378,6 +1377,18 @@ namespace nmos
return params;
}

// Get additional "video/raw" parameters from the SDP parameters
video_raw_parameters get_video_raw_parameters(const sdp_parameters& sdp_params)
{
return get_video_raw_parameters<details::throw_missing_fmtp>(sdp_params);
}

// Get additional "video/raw" parameters from the SDP parameters
video_raw_parameters get_video_raw_parameters_or_defaults(const sdp_parameters& sdp_params)
{
return get_video_raw_parameters<>(sdp_params, [](const utility::string_t&) {});
}

// Get additional "audio/L" parameters from the SDP parameters
audio_L_parameters get_audio_L_parameters(const sdp_parameters& sdp_params)
{
Expand Down
10 changes: 10 additions & 0 deletions Development/nmos/sdp_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <stdexcept>
#include "bst/any.h"
#include "bst/optional.h"
#include "cpprest/basic_utils.h"
#include "sdp/json.h"
#include "sdp/ntp.h"
#include "nmos/did_sdid.h"
Expand Down Expand Up @@ -506,6 +507,7 @@ namespace nmos
sdp_parameters make_video_raw_sdp_parameters(const utility::string_t& session_name, const video_raw_parameters& params, uint64_t payload_type, const std::vector<utility::string_t>& media_stream_ids = {}, const std::vector<sdp_parameters::ts_refclk_t>& ts_refclk = {});
// Get additional "video/raw" parameters from the SDP parameters
video_raw_parameters get_video_raw_parameters(const sdp_parameters& sdp_params);
video_raw_parameters get_video_raw_parameters_or_defaults(const sdp_parameters& sdp_params);

// Construct additional "audio/L" parameters from the IS-04 resources, using default values for unspecified items
audio_L_parameters make_audio_L_parameters(const web::json::value& node, const web::json::value& source, const web::json::value& flow, const web::json::value& sender, bst::optional<double> packet_time);
Expand Down Expand Up @@ -582,6 +584,14 @@ namespace nmos
return std::runtime_error{ "sdp processing error - " + message };
}

struct throw_missing_fmtp
{
void operator()(const utility::string_t& name) const
{
throw details::sdp_processing_error("missing format parameter: " + utility::us2s(name));
}
};

inline sdp_parameters::fmtp_t::const_iterator find_fmtp(const sdp_parameters::fmtp_t& fmtp, const utility::string_t& name)
{
return std::find_if(fmtp.begin(), fmtp.end(), [&](const sdp_parameters::fmtp_t::value_type& param)
Expand Down
19 changes: 16 additions & 3 deletions Development/nmos/video_jxsv.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,13 +186,14 @@ namespace nmos
}

// Get additional "video/jxsv" parameters from the SDP parameters
video_jxsv_parameters get_video_jxsv_parameters(const sdp_parameters& sdp_params)
template <typename MissingRequiredParameter>
video_jxsv_parameters get_video_jxsv_parameters(const sdp_parameters& sdp_params, MissingRequiredParameter missing = MissingRequiredParameter{})
{
video_jxsv_parameters params;

const auto packetmode = details::find_fmtp(sdp_params.fmtp, sdp::video_jxsv::fields::packetmode);
if (sdp_params.fmtp.end() == packetmode) throw details::sdp_processing_error("missing format parameter: packetmode");
params.packetmode = (sdp::video_jxsv::packetization_mode)utility::istringstreamed<uint32_t>(packetmode->second);
if (sdp_params.fmtp.end() != packetmode) params.packetmode = (sdp::video_jxsv::packetization_mode)utility::istringstreamed<uint32_t>(packetmode->second);
else missing(sdp::video_jxsv::fields::packetmode);

// optional
const auto transmode = details::find_fmtp(sdp_params.fmtp, sdp::video_jxsv::fields::transmode);
Expand Down Expand Up @@ -286,6 +287,18 @@ namespace nmos
return params;
}

// Get additional "video/jxsv" parameters from the SDP parameters
video_jxsv_parameters get_video_jxsv_parameters(const sdp_parameters& sdp_params)
{
return get_video_jxsv_parameters<details::throw_missing_fmtp>(sdp_params);
}

// Get additional "video/jxsv" parameters from the SDP parameters
video_jxsv_parameters get_video_jxsv_parameters_or_defaults(const sdp_parameters& sdp_params)
{
return get_video_jxsv_parameters<>(sdp_params, [](const utility::string_t&) {});
}

// Calculate the format bit rate (kilobits/second) from the specified frame rate, dimensions and bits per pixel
uint64_t get_video_jxsv_bit_rate(const nmos::rational& grain_rate, uint32_t frame_width, uint32_t frame_height, double bits_per_pixel)
{
Expand Down
1 change: 1 addition & 0 deletions Development/nmos/video_jxsv.h
Original file line number Diff line number Diff line change
Expand Up @@ -353,6 +353,7 @@ namespace nmos
sdp_parameters make_video_jxsv_sdp_parameters(const utility::string_t& session_name, const video_jxsv_parameters& params, uint64_t payload_type, const std::vector<utility::string_t>& media_stream_ids = {}, const std::vector<sdp_parameters::ts_refclk_t>& ts_refclk = {});
// Get additional "video/jxsv" parameters from the SDP parameters
video_jxsv_parameters get_video_jxsv_parameters(const sdp_parameters& sdp_params);
video_jxsv_parameters get_video_jxsv_parameters_or_defaults(const sdp_parameters& sdp_params);

// Construct SDP parameters for "video/jxsv"
inline sdp_parameters make_sdp_parameters(const utility::string_t& session_name, const video_jxsv_parameters& params, uint64_t payload_type, const std::vector<utility::string_t>& media_stream_ids = {}, const std::vector<sdp_parameters::ts_refclk_t>& ts_refclk = {})
Expand Down
Loading