зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1432930: Part 2: Added C++/Rust glue code for imageattr, r=bwc
Added C++/Rust glue code for imageattr. Added U32vec interface Added F32vec interface Enabled C++ unit test CheckMalformedImageattr Removed redundant parsing code with "Bug 1469702" MozReview-Commit-ID: Lwj8len4xPR --HG-- extra : rebase_source : a260799c0a3146b5bf2f461762c9b7db0849a266
This commit is contained in:
Родитель
c34d1a7a92
Коммит
c420368865
|
@ -3750,7 +3750,6 @@ const std::string kMalformedImageattr =
|
|||
|
||||
TEST_P(NewSdpTest, CheckMalformedImageattr)
|
||||
{
|
||||
SKIP_TEST_WITH_RUST_PARSER; // See Bug 1432930
|
||||
if (::testing::get<0>(GetParam())) {
|
||||
// Don't do a parse/serialize before running this test
|
||||
return;
|
||||
|
|
|
@ -1023,6 +1023,65 @@ RsdparsaSdpAttributeList::LoadSimulcast(RustAttributeList* attributeList)
|
|||
}
|
||||
}
|
||||
|
||||
SdpImageattrAttributeList::XYRange
|
||||
LoadImageattrXYRange(const RustSdpAttributeImageAttrXYRange& rustXYRange)
|
||||
{
|
||||
SdpImageattrAttributeList::XYRange xyRange;
|
||||
|
||||
if (!rustXYRange.discrete_values) {
|
||||
xyRange.min = rustXYRange.min;
|
||||
xyRange.max = rustXYRange.max;
|
||||
xyRange.step = rustXYRange.step;
|
||||
|
||||
} else {
|
||||
xyRange.discreteValues = convertU32Vec(rustXYRange.discrete_values);
|
||||
}
|
||||
|
||||
return xyRange;
|
||||
}
|
||||
|
||||
std::vector<SdpImageattrAttributeList::Set>
|
||||
LoadImageattrSets(const RustSdpAttributeImageAttrSetVec* rustSets)
|
||||
{
|
||||
std::vector<SdpImageattrAttributeList::Set> sets;
|
||||
|
||||
size_t rustSetCount = sdp_imageattr_get_set_count(rustSets);
|
||||
if (!rustSetCount) {
|
||||
return sets;
|
||||
}
|
||||
|
||||
auto rustSetArray = MakeUnique<RustSdpAttributeImageAttrSet[]>(rustSetCount);
|
||||
sdp_imageattr_get_sets(rustSets, rustSetCount, rustSetArray.get());
|
||||
|
||||
for(size_t i = 0; i < rustSetCount; i++) {
|
||||
const RustSdpAttributeImageAttrSet& rustSet = rustSetArray[i];
|
||||
SdpImageattrAttributeList::Set set;
|
||||
|
||||
set.xRange = LoadImageattrXYRange(rustSet.x);
|
||||
set.yRange = LoadImageattrXYRange(rustSet.y);
|
||||
|
||||
if (rustSet.has_sar) {
|
||||
if (!rustSet.sar.discrete_values) {
|
||||
set.sRange.min = rustSet.sar.min;
|
||||
set.sRange.max = rustSet.sar.max;
|
||||
} else {
|
||||
set.sRange.discreteValues = convertF32Vec(rustSet.sar.discrete_values);
|
||||
}
|
||||
}
|
||||
|
||||
if (rustSet.has_par) {
|
||||
set.pRange.min = rustSet.par.min;
|
||||
set.pRange.max = rustSet.par.max;
|
||||
}
|
||||
|
||||
set.qValue = rustSet.q;
|
||||
|
||||
sets.push_back(set);
|
||||
}
|
||||
|
||||
return sets;
|
||||
}
|
||||
|
||||
void
|
||||
RsdparsaSdpAttributeList::LoadImageattr(RustAttributeList* attributeList)
|
||||
{
|
||||
|
@ -1030,17 +1089,31 @@ RsdparsaSdpAttributeList::LoadImageattr(RustAttributeList* attributeList)
|
|||
if (numImageattrs == 0) {
|
||||
return;
|
||||
}
|
||||
auto rustImageattrs = MakeUnique<StringView[]>(numImageattrs);
|
||||
auto rustImageattrs = MakeUnique<RustSdpAttributeImageAttr[]>(numImageattrs);
|
||||
sdp_get_imageattrs(attributeList, numImageattrs, rustImageattrs.get());
|
||||
auto imageattrList = MakeUnique<SdpImageattrAttributeList>();
|
||||
for(size_t i = 0; i < numImageattrs; i++) {
|
||||
StringView& imageAttr = rustImageattrs[i];
|
||||
std::string image = convertStringView(imageAttr);
|
||||
std::string error;
|
||||
size_t errorPos;
|
||||
if (!imageattrList->PushEntry(image, &error, &errorPos)) {
|
||||
// TODO: handle error, see Bug 1438237
|
||||
const RustSdpAttributeImageAttr& rustImageAttr = rustImageattrs[i];
|
||||
|
||||
SdpImageattrAttributeList::Imageattr imageAttr;
|
||||
|
||||
if (rustImageAttr.payloadType != std::numeric_limits<uint32_t>::max()) {
|
||||
imageAttr.pt = Some(rustImageAttr.payloadType);
|
||||
}
|
||||
|
||||
if (rustImageAttr.send.sets) {
|
||||
imageAttr.sendSets = LoadImageattrSets(rustImageAttr.send.sets);
|
||||
} else {
|
||||
imageAttr.sendAll = true;
|
||||
}
|
||||
|
||||
if (rustImageAttr.recv.sets) {
|
||||
imageAttr.recvSets = LoadImageattrSets(rustImageAttr.recv.sets);
|
||||
} else {
|
||||
imageAttr.recvAll = true;
|
||||
}
|
||||
|
||||
imageattrList->mImageattrs.push_back(imageAttr);
|
||||
}
|
||||
SetAttribute(imageattrList.release());
|
||||
}
|
||||
|
|
|
@ -73,4 +73,32 @@ std::vector<uint16_t> convertU16Vec(U16Vec* vec)
|
|||
return ret;
|
||||
}
|
||||
|
||||
std::vector<uint32_t> convertU32Vec(U32Vec* vec)
|
||||
{
|
||||
std::vector<std::uint32_t> ret;
|
||||
|
||||
size_t len = u32_vec_len(vec);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
uint32_t num;
|
||||
u32_vec_get(vec, i, &num);
|
||||
ret.push_back(num);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<float> convertF32Vec(F32Vec* vec)
|
||||
{
|
||||
std::vector<float> ret;
|
||||
|
||||
size_t len = f32_vec_len(vec);
|
||||
for (size_t i = 0; i < len; i++) {
|
||||
float flt;
|
||||
f32_vec_get(vec, i, &flt);
|
||||
ret.push_back(flt);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -26,6 +26,8 @@ std::vector<std::string> convertStringVec(StringVec* vec);
|
|||
sdp::AddrType convertAddressType(RustSdpAddrType addr);
|
||||
std::vector<uint8_t> convertU8Vec(U8Vec* vec);
|
||||
std::vector<uint16_t> convertU16Vec(U16Vec* vec);
|
||||
std::vector<uint32_t> convertU32Vec(U32Vec* vec);
|
||||
std::vector<float> convertF32Vec(F32Vec* vec);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -20,6 +20,7 @@ struct StringVec;
|
|||
struct U8Vec;
|
||||
struct U32Vec;
|
||||
struct U16Vec;
|
||||
struct F32Vec;
|
||||
struct RustHeapString;
|
||||
|
||||
enum class RustSdpAddrType {
|
||||
|
@ -131,6 +132,45 @@ struct RustSdpAttributeRid {
|
|||
StringVec* depends;
|
||||
};
|
||||
|
||||
struct RustSdpAttributeImageAttrXYRange {
|
||||
uint32_t min;
|
||||
uint32_t max;
|
||||
uint32_t step;
|
||||
U32Vec* discrete_values;
|
||||
};
|
||||
|
||||
struct RustSdpAttributeImageAttrSRange {
|
||||
float min;
|
||||
float max;
|
||||
F32Vec* discrete_values;
|
||||
};
|
||||
|
||||
struct RustSdpAttributeImageAttrPRange {
|
||||
float min;
|
||||
float max;
|
||||
};
|
||||
|
||||
struct RustSdpAttributeImageAttrSet {
|
||||
RustSdpAttributeImageAttrXYRange x;
|
||||
RustSdpAttributeImageAttrXYRange y;
|
||||
bool has_sar;
|
||||
RustSdpAttributeImageAttrSRange sar;
|
||||
bool has_par;
|
||||
RustSdpAttributeImageAttrPRange par;
|
||||
float q;
|
||||
};
|
||||
|
||||
struct RustSdpAttributeImageAttrSetVec;
|
||||
struct RustSdpAttributeImageAttrSetList {
|
||||
RustSdpAttributeImageAttrSetVec* sets;
|
||||
};
|
||||
|
||||
struct RustSdpAttributeImageAttr {
|
||||
uint32_t payloadType;
|
||||
RustSdpAttributeImageAttrSetList send;
|
||||
RustSdpAttributeImageAttrSetList recv;
|
||||
};
|
||||
|
||||
struct RustSdpAttributeFmtpParameters {
|
||||
// H264
|
||||
uint32_t packetization_mode;
|
||||
|
@ -254,6 +294,9 @@ size_t string_vec_len(const StringVec* vec);
|
|||
nsresult string_vec_get_view(const StringVec* vec, size_t index,
|
||||
StringView* str);
|
||||
|
||||
size_t f32_vec_len(const F32Vec* vec);
|
||||
nsresult f32_vec_get(const F32Vec* vec, size_t index, float* ret);
|
||||
|
||||
size_t u32_vec_len(const U32Vec* vec);
|
||||
nsresult u32_vec_get(const U32Vec* vec, size_t index, uint32_t* ret);
|
||||
|
||||
|
@ -375,7 +418,11 @@ void sdp_get_rtcpfbs(const RustAttributeList* aList, size_t listSize,
|
|||
|
||||
size_t sdp_get_imageattr_count(const RustAttributeList* aList);
|
||||
void sdp_get_imageattrs(const RustAttributeList* aList, size_t listSize,
|
||||
StringView* ret);
|
||||
RustSdpAttributeImageAttr* ret);
|
||||
|
||||
size_t sdp_imageattr_get_set_count(const RustSdpAttributeImageAttrSetVec* sets);
|
||||
void sdp_imageattr_get_sets(const RustSdpAttributeImageAttrSetVec* sets,
|
||||
size_t listSize, RustSdpAttributeImageAttrSet* ret);
|
||||
|
||||
size_t sdp_get_sctpmap_count(const RustAttributeList* aList);
|
||||
void sdp_get_sctpmaps(const RustAttributeList* aList, size_t listSize,
|
||||
|
|
|
@ -721,9 +721,13 @@ public:
|
|||
public:
|
||||
XYRange() : min(0), max(0), step(1) {}
|
||||
void Serialize(std::ostream& os) const;
|
||||
// TODO: Remove this Bug 1469702
|
||||
bool Parse(std::istream& is, std::string* error);
|
||||
// TODO: Remove this Bug 1469702
|
||||
bool ParseAfterBracket(std::istream& is, std::string* error);
|
||||
// TODO: Remove this Bug 1469702
|
||||
bool ParseAfterMin(std::istream& is, std::string* error);
|
||||
// TODO: Remove this Bug 1469702
|
||||
bool ParseDiscreteValues(std::istream& is, std::string* error);
|
||||
std::vector<uint32_t> discreteValues;
|
||||
// min/max are used iff discreteValues is empty
|
||||
|
@ -737,9 +741,13 @@ public:
|
|||
public:
|
||||
SRange() : min(0), max(0) {}
|
||||
void Serialize(std::ostream& os) const;
|
||||
// TODO: Remove this Bug 1469702
|
||||
bool Parse(std::istream& is, std::string* error);
|
||||
// TODO: Remove this Bug 1469702
|
||||
bool ParseAfterBracket(std::istream& is, std::string* error);
|
||||
// TODO: Remove this Bug 1469702
|
||||
bool ParseAfterMin(std::istream& is, std::string* error);
|
||||
// TODO: Remove this Bug 1469702
|
||||
bool ParseDiscreteValues(std::istream& is, std::string* error);
|
||||
bool IsSet() const
|
||||
{
|
||||
|
@ -756,6 +764,7 @@ public:
|
|||
public:
|
||||
PRange() : min(0), max(0) {}
|
||||
void Serialize(std::ostream& os) const;
|
||||
// TODO: Remove this Bug 1469702
|
||||
bool Parse(std::istream& is, std::string* error);
|
||||
bool IsSet() const
|
||||
{
|
||||
|
@ -770,6 +779,7 @@ public:
|
|||
public:
|
||||
Set() : qValue(-1) {}
|
||||
void Serialize(std::ostream& os) const;
|
||||
// TODO: Remove this Bug 1469702
|
||||
bool Parse(std::istream& is, std::string* error);
|
||||
XYRange xRange;
|
||||
XYRange yRange;
|
||||
|
@ -783,7 +793,9 @@ public:
|
|||
public:
|
||||
Imageattr() : pt(), sendAll(false), recvAll(false) {}
|
||||
void Serialize(std::ostream& os) const;
|
||||
// TODO: Remove this Bug 1469702
|
||||
bool Parse(std::istream& is, std::string* error);
|
||||
// TODO: Remove this Bug 1469702
|
||||
bool ParseSets(std::istream& is, std::string* error);
|
||||
// If not set, this means all payload types
|
||||
Maybe<uint16_t> pt;
|
||||
|
@ -794,6 +806,8 @@ public:
|
|||
};
|
||||
|
||||
virtual void Serialize(std::ostream& os) const override;
|
||||
|
||||
// TODO: Remove this Bug 1469702
|
||||
bool PushEntry(const std::string& raw, std::string* error, size_t* errorPos);
|
||||
|
||||
std::vector<Imageattr> mImageattrs;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
use std::net::IpAddr;
|
||||
use std::str::FromStr;
|
||||
use std::fmt;
|
||||
use std::iter;
|
||||
|
||||
use SdpType;
|
||||
use error::SdpParserInternalError;
|
||||
|
@ -293,16 +294,14 @@ pub struct SdpAttributeFingerprint {
|
|||
#[cfg_attr(feature="serialize", derive(Serialize))]
|
||||
pub enum SdpAttributeImageAttrXYRange {
|
||||
Range(u32,u32,Option<u32>), // min, max, step
|
||||
DiscrateValues(Vec<u32>),
|
||||
Value(u32)
|
||||
DiscreteValues(Vec<u32>),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
#[cfg_attr(feature="serialize", derive(Serialize))]
|
||||
pub enum SdpAttributeImageAttrSRange {
|
||||
Range(f32,f32), // min, max
|
||||
DiscrateValues(Vec<f32>),
|
||||
Value(f32)
|
||||
DiscreteValues(Vec<f32>),
|
||||
}
|
||||
|
||||
#[derive(Debug, PartialEq, Clone)]
|
||||
|
@ -1222,17 +1221,50 @@ fn parse_ice_options(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalEr
|
|||
Ok(SdpAttribute::IceOptions(to_parse.split_whitespace().map(|x| x.to_string()).collect()))
|
||||
}
|
||||
|
||||
fn parse_image_attr_xyrange(to_parse: &str) -> Result<SdpAttributeImageAttrXYRange, SdpParserInternalError> {
|
||||
if to_parse.starts_with("[") {
|
||||
if !to_parse.ends_with("]") {
|
||||
return Err(SdpParserInternalError::Generic(
|
||||
"imageattr's xyrange has no closing tag ']'".to_string()
|
||||
))
|
||||
fn parse_imageattr_tokens(to_parse: &str, separator: char) -> Vec<String> {
|
||||
let mut tokens = Vec::new();
|
||||
let mut open_braces_counter = 0;
|
||||
let mut current_tokens = Vec::new();
|
||||
|
||||
for token in to_parse.split(separator) {
|
||||
if token.contains("[") {
|
||||
open_braces_counter+=1;
|
||||
}
|
||||
if token.contains("]") {
|
||||
open_braces_counter-=1;
|
||||
}
|
||||
|
||||
current_tokens.push(token.to_string());
|
||||
|
||||
if open_braces_counter == 0 {
|
||||
tokens.push(current_tokens.join(&separator.to_string()));
|
||||
current_tokens = Vec::new();
|
||||
}
|
||||
}
|
||||
|
||||
tokens
|
||||
}
|
||||
|
||||
fn parse_imagettr_braced_token(to_parse: &str) -> Option<&str> {
|
||||
if !to_parse.ends_with("]") {
|
||||
return None;
|
||||
}
|
||||
|
||||
Some(&to_parse[1..to_parse.len()-1])
|
||||
}
|
||||
|
||||
fn parse_image_attr_xyrange(to_parse: &str) -> Result<SdpAttributeImageAttrXYRange,
|
||||
SdpParserInternalError> {
|
||||
if to_parse.starts_with("[") {
|
||||
let value_tokens = parse_imagettr_braced_token(to_parse).ok_or(
|
||||
SdpParserInternalError::Generic(
|
||||
"imageattr's xyrange has no closing tag ']'".to_string()
|
||||
)
|
||||
)?;
|
||||
|
||||
if to_parse.contains(":") {
|
||||
// Range values
|
||||
let range_tokens:Vec<&str> = to_parse[1..to_parse.len()-1].split(":").collect();
|
||||
let range_tokens:Vec<&str> = value_tokens.split(":").collect();
|
||||
|
||||
if range_tokens.len() == 3 {
|
||||
Ok(SdpAttributeImageAttrXYRange::Range(
|
||||
|
@ -1253,57 +1285,31 @@ fn parse_image_attr_xyrange(to_parse: &str) -> Result<SdpAttributeImageAttrXYRan
|
|||
}
|
||||
} else {
|
||||
// Discrete values
|
||||
let values = to_parse[1..to_parse.len()-1]
|
||||
.split(",")
|
||||
.map(|x| x.parse::<u32>())
|
||||
.collect::<Result<Vec<u32>, _>>()?;
|
||||
let values = value_tokens.split(",")
|
||||
.map(|x| x.parse::<u32>())
|
||||
.collect::<Result<Vec<u32>, _>>()?;
|
||||
|
||||
if values.len() == 0 {
|
||||
if values.len() < 2 {
|
||||
return Err(SdpParserInternalError::Generic(
|
||||
"imageattr's discrete value list is empty".to_string()
|
||||
"imageattr's discrete value list must have at least two elements".to_string()
|
||||
))
|
||||
}
|
||||
|
||||
Ok(SdpAttributeImageAttrXYRange::DiscrateValues(values))
|
||||
Ok(SdpAttributeImageAttrXYRange::DiscreteValues(values))
|
||||
}
|
||||
|
||||
} else {
|
||||
Ok(SdpAttributeImageAttrXYRange::Value(to_parse.parse::<u32>()?))
|
||||
Ok(SdpAttributeImageAttrXYRange::DiscreteValues(vec![to_parse.parse::<u32>()?]))
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_image_attr_set(to_parse: &str) -> Result<SdpAttributeImageAttrSet, SdpParserInternalError> {
|
||||
let result_from_option = |opt, error_msg: &str| {
|
||||
match opt {
|
||||
Some(x) => Ok(x),
|
||||
None => Err(SdpParserInternalError::Generic(error_msg.to_string()))
|
||||
}
|
||||
};
|
||||
fn parse_image_attr_set(to_parse: &str) -> Result<SdpAttributeImageAttrSet,
|
||||
SdpParserInternalError> {
|
||||
let mut tokens = parse_imageattr_tokens(to_parse, ',').into_iter();
|
||||
|
||||
let mut tokens = Vec::new();
|
||||
let mut currently_in_braces = false;
|
||||
let mut current_tokens = Vec::new();
|
||||
|
||||
for token in to_parse.split(",") {
|
||||
if token.contains("[") {
|
||||
currently_in_braces = true;
|
||||
}
|
||||
if token.contains("]") {
|
||||
currently_in_braces = false;
|
||||
}
|
||||
|
||||
current_tokens.push(token.to_string());
|
||||
|
||||
if !currently_in_braces {
|
||||
tokens.push(current_tokens.join(","));
|
||||
current_tokens = Vec::new();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
let mut tokens = tokens.into_iter();
|
||||
|
||||
let x_token = result_from_option(tokens.next(),"imageattr set is missing the 'x=' token")?;
|
||||
let x_token = tokens.next().ok_or(SdpParserInternalError::Generic(
|
||||
"imageattr set is missing the 'x=' token".to_string()
|
||||
))?;
|
||||
if !x_token.starts_with("x=") {
|
||||
return Err(SdpParserInternalError::Generic(
|
||||
"The first token in an imageattr set must begin with 'x='".to_string()
|
||||
|
@ -1312,7 +1318,9 @@ fn parse_image_attr_set(to_parse: &str) -> Result<SdpAttributeImageAttrSet, SdpP
|
|||
let x = parse_image_attr_xyrange(&x_token[2..])?;
|
||||
|
||||
|
||||
let y_token = result_from_option(tokens.next(),"imageattr set is missing the 'y=' token")?;
|
||||
let y_token = tokens.next().ok_or(SdpParserInternalError::Generic(
|
||||
"imageattr set is missing the 'y=' token".to_string()
|
||||
))?;
|
||||
if !y_token.starts_with("y=") {
|
||||
return Err(SdpParserInternalError::Generic(
|
||||
"The second token in an imageattr set must begin with 'y='".to_string()
|
||||
|
@ -1324,22 +1332,17 @@ fn parse_image_attr_set(to_parse: &str) -> Result<SdpAttributeImageAttrSet, SdpP
|
|||
let mut par = None;
|
||||
let mut q = None;
|
||||
|
||||
let parse_ps_range = |x: &str| -> Result<(f32, f32), SdpParserInternalError> {
|
||||
let range_tokens = &x[1..x.len()-1];
|
||||
let parse_ps_range = |resolution_range: &str| -> Result<(f32, f32), SdpParserInternalError> {
|
||||
let minmax_pair:Vec<&str> = resolution_range.split("-").collect();
|
||||
|
||||
let parse_prange_value = |maybe_next: Option<&str>| -> Result<f32, SdpParserInternalError> {
|
||||
match maybe_next {
|
||||
Some(x) => Ok(x.parse::<f32>()?),
|
||||
None => Err(SdpParserInternalError::Generic(
|
||||
"imageattr's par and sar ranges must have two components"
|
||||
.to_string()))
|
||||
}
|
||||
};
|
||||
if minmax_pair.len() != 2 {
|
||||
return Err(SdpParserInternalError::Generic(
|
||||
"imageattr's par and sar ranges must have two components".to_string()
|
||||
))
|
||||
}
|
||||
|
||||
let mut minmax_pair = range_tokens.split("-");
|
||||
|
||||
let min = parse_prange_value(minmax_pair.next())?;
|
||||
let max = parse_prange_value(minmax_pair.next())?;
|
||||
let min = minmax_pair[0].parse::<f32>()?;
|
||||
let max = minmax_pair[1].parse::<f32>()?;
|
||||
|
||||
if min >= max {
|
||||
return Err(SdpParserInternalError::Generic(
|
||||
|
@ -1354,26 +1357,26 @@ fn parse_image_attr_set(to_parse: &str) -> Result<SdpAttributeImageAttrSet, SdpP
|
|||
if current_token.starts_with("sar=") {
|
||||
let value_token = ¤t_token[4..];
|
||||
if value_token.starts_with("[") {
|
||||
if !value_token.ends_with("]") {
|
||||
return Err(SdpParserInternalError::Generic(
|
||||
let sar_values = parse_imagettr_braced_token(value_token).ok_or(
|
||||
SdpParserInternalError::Generic(
|
||||
"imageattr's sar value is missing closing tag ']'".to_string()
|
||||
))
|
||||
}
|
||||
)
|
||||
)?;
|
||||
|
||||
if value_token.contains("-") {
|
||||
// Range
|
||||
let range = parse_ps_range(&value_token)?;
|
||||
let range = parse_ps_range(sar_values)?;
|
||||
sar = Some(SdpAttributeImageAttrSRange::Range(range.0,range.1))
|
||||
} else if value_token.contains(",") {
|
||||
// Discrete values
|
||||
let values = value_token[1..value_token.len()-1]
|
||||
.split(",")
|
||||
.map(|x| x.parse::<f32>())
|
||||
.collect::<Result<Vec<f32>, _>>()?;
|
||||
let values = sar_values.split(",")
|
||||
.map(|x| x.parse::<f32>())
|
||||
.collect::<Result<Vec<f32>, _>>()?;
|
||||
|
||||
if values.len() == 0 {
|
||||
if values.len() < 2 {
|
||||
return Err(SdpParserInternalError::Generic(
|
||||
"imageattr's sar discrete value list is empty".to_string()
|
||||
"imageattr's sar discrete value list must have at least two values"
|
||||
.to_string()
|
||||
))
|
||||
}
|
||||
|
||||
|
@ -1388,31 +1391,33 @@ fn parse_image_attr_set(to_parse: &str) -> Result<SdpAttributeImageAttrSet, SdpP
|
|||
}
|
||||
last_value = *value;
|
||||
}
|
||||
sar = Some(SdpAttributeImageAttrSRange::DiscrateValues(values))
|
||||
sar = Some(SdpAttributeImageAttrSRange::DiscreteValues(values))
|
||||
}
|
||||
} else {
|
||||
sar = Some(SdpAttributeImageAttrSRange::Value(value_token.parse::<f32>()?))
|
||||
sar = Some(SdpAttributeImageAttrSRange::DiscreteValues(
|
||||
vec![value_token.parse::<f32>()?])
|
||||
)
|
||||
}
|
||||
} else if current_token.starts_with("par=") {
|
||||
let braced_value_token = ¤t_token[4..];
|
||||
if !braced_value_token.starts_with("[") || !braced_value_token.ends_with("]") {
|
||||
if !braced_value_token.starts_with("[") {
|
||||
return Err(SdpParserInternalError::Generic(
|
||||
"imageattr's par value is missing braces".to_string()
|
||||
"imageattr's par value must start with '['".to_string()
|
||||
))
|
||||
}
|
||||
|
||||
let range = parse_ps_range(&braced_value_token)?;
|
||||
let par_values = parse_imagettr_braced_token(braced_value_token).ok_or(
|
||||
SdpParserInternalError::Generic(
|
||||
"imageattr's par value must be enclosed with ']'".to_string()
|
||||
)
|
||||
)?;
|
||||
let range = parse_ps_range(par_values)?;
|
||||
par = Some(SdpAttributeImageAttrPRange {
|
||||
min: range.0,
|
||||
max: range.1,
|
||||
})
|
||||
} else if current_token.starts_with("q=") {
|
||||
q = Some(current_token[2..].parse::<f32>()?);
|
||||
} else {
|
||||
return Err(SdpParserInternalError::Generic(
|
||||
format!("imageattr set contains unknown value token '{:?}'", current_token)
|
||||
.to_string()
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1425,70 +1430,62 @@ fn parse_image_attr_set(to_parse: &str) -> Result<SdpAttributeImageAttrSet, SdpP
|
|||
})
|
||||
}
|
||||
|
||||
fn parse_image_attr(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> {
|
||||
let result_from_option = |opt, error_msg: &str| {
|
||||
match opt {
|
||||
Some(x) => Ok(x),
|
||||
None => Err(SdpParserInternalError::Generic(error_msg.to_string()))
|
||||
}
|
||||
};
|
||||
let mut tokens = to_parse.split(' ').peekable();
|
||||
|
||||
let pt = parse_payload_type(result_from_option(tokens.next(),
|
||||
"imageattr's requires a payload token")?)?;
|
||||
let first_direction = parse_single_direction(result_from_option(tokens.next(), "")?)?;
|
||||
|
||||
fn parse_image_attr_set_list<I>(tokens: &mut iter::Peekable<I>)
|
||||
-> Result<SdpAttributeImageAttrSetList, SdpParserInternalError>
|
||||
where I: Iterator<Item = String> + Clone {
|
||||
let parse_set = |set_token:&str| -> Result<SdpAttributeImageAttrSet, SdpParserInternalError> {
|
||||
Ok(parse_image_attr_set(&set_token[1..set_token.len()-1])?)
|
||||
Ok(parse_image_attr_set(parse_imagettr_braced_token(set_token).ok_or(
|
||||
SdpParserInternalError::Generic(
|
||||
"imageattr sets must be enclosed by ']'".to_string()
|
||||
))?)?)
|
||||
};
|
||||
|
||||
let first_set_list = match result_from_option(tokens.next(),
|
||||
"imageattr must have at least one parameter set")? {
|
||||
"*" => SdpAttributeImageAttrSetList::Wildcard,
|
||||
x @ _ => {
|
||||
match tokens.next().ok_or(SdpParserInternalError::Generic(
|
||||
"imageattr must have a parameter set after a direction token".to_string()
|
||||
))?.as_str() {
|
||||
"*" => Ok(SdpAttributeImageAttrSetList::Wildcard),
|
||||
x => {
|
||||
let mut sets = vec![parse_set(x)?];
|
||||
while let Some(set_str) = tokens.clone().peek() {
|
||||
if set_str.starts_with("[") && set_str.ends_with("]") {
|
||||
sets.push(parse_set(tokens.next().unwrap())?);
|
||||
if set_str.starts_with("[") {
|
||||
sets.push(parse_set(&tokens.next().unwrap())?);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SdpAttributeImageAttrSetList::Sets(sets)
|
||||
Ok(SdpAttributeImageAttrSetList::Sets(sets))
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_image_attr(to_parse: &str) -> Result<SdpAttribute, SdpParserInternalError> {
|
||||
let mut tokens = parse_imageattr_tokens(to_parse, ' ').into_iter().peekable();
|
||||
|
||||
let pt = parse_payload_type(tokens.next().ok_or(SdpParserInternalError::Generic(
|
||||
"imageattr requires a payload token".to_string()
|
||||
))?.as_str())?;
|
||||
let first_direction = parse_single_direction(tokens.next().ok_or(
|
||||
SdpParserInternalError::Generic(
|
||||
"imageattr's second token must be a direction token".to_string()
|
||||
))?.as_str())?;
|
||||
|
||||
let first_set_list = parse_image_attr_set_list(&mut tokens)?;
|
||||
|
||||
let mut second_set_list = SdpAttributeImageAttrSetList::Sets(Vec::new());
|
||||
|
||||
// Check if there is a second direction defined
|
||||
if let Some(x) = tokens.next() {
|
||||
if parse_single_direction(x)? == first_direction {
|
||||
if let Some(direction_token) = tokens.next() {
|
||||
if parse_single_direction(direction_token.as_str())? == first_direction {
|
||||
return Err(SdpParserInternalError::Generic(
|
||||
"image-attr's second direction token must be different from the first one"
|
||||
"imageattr's second direction token must be different from the first one"
|
||||
.to_string()
|
||||
))
|
||||
}
|
||||
|
||||
second_set_list = match result_from_option(tokens.next(),
|
||||
"imageattr must have a parameter set after a direction token")? {
|
||||
"*" => SdpAttributeImageAttrSetList::Wildcard,
|
||||
x @ _ => {
|
||||
let mut sets = vec![parse_set(x)?];
|
||||
while let Some(set_str) = tokens.clone().peek() {
|
||||
if set_str.starts_with("[") && set_str.ends_with("]") {
|
||||
sets.push(parse_set(tokens.next().unwrap())?);
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
SdpAttributeImageAttrSetList::Sets(sets)
|
||||
}
|
||||
};
|
||||
second_set_list = parse_image_attr_set_list(&mut tokens)?;
|
||||
}
|
||||
|
||||
|
||||
if let Some(_) = tokens.next() {
|
||||
return Err(SdpParserInternalError::Generic(
|
||||
"imageattr must not contain any token after the second set list".to_string()
|
||||
|
@ -2242,10 +2239,10 @@ fn test_parse_attribute_imageattr() {
|
|||
assert_eq!(sets.len(), 1);
|
||||
|
||||
let set = &sets[0];
|
||||
assert_eq!(set.x, SdpAttributeImageAttrXYRange::Value(800));
|
||||
assert_eq!(set.y, SdpAttributeImageAttrXYRange::DiscrateValues(vec![50,80,30]));
|
||||
assert_eq!(set.x, SdpAttributeImageAttrXYRange::DiscreteValues(vec![800]));
|
||||
assert_eq!(set.y, SdpAttributeImageAttrXYRange::DiscreteValues(vec![50,80,30]));
|
||||
assert_eq!(set.par, None);
|
||||
assert_eq!(set.sar, Some(SdpAttributeImageAttrSRange::Value(1.1)));
|
||||
assert_eq!(set.sar, Some(SdpAttributeImageAttrSRange::DiscreteValues(vec![1.1])));
|
||||
assert_eq!(set.q, None);
|
||||
|
||||
},
|
||||
|
@ -2256,10 +2253,10 @@ fn test_parse_attribute_imageattr() {
|
|||
assert_eq!(sets.len(), 1);
|
||||
|
||||
let set = &sets[0];
|
||||
assert_eq!(set.x, SdpAttributeImageAttrXYRange::Value(330));
|
||||
assert_eq!(set.y, SdpAttributeImageAttrXYRange::Value(250));
|
||||
assert_eq!(set.x, SdpAttributeImageAttrXYRange::DiscreteValues(vec![330]));
|
||||
assert_eq!(set.y, SdpAttributeImageAttrXYRange::DiscreteValues(vec![250]));
|
||||
assert_eq!(set.par, None);
|
||||
assert_eq!(set.sar, Some(SdpAttributeImageAttrSRange::DiscrateValues(vec![1.1,1.3,1.9])));
|
||||
assert_eq!(set.sar, Some(SdpAttributeImageAttrSRange::DiscreteValues(vec![1.1,1.3,1.9])));
|
||||
assert_eq!(set.q, Some(0.1));
|
||||
},
|
||||
_ => { unreachable!(); }
|
||||
|
@ -2273,7 +2270,7 @@ fn test_parse_attribute_imageattr() {
|
|||
|
||||
let first_set = &sets[0];
|
||||
assert_eq!(first_set.x, SdpAttributeImageAttrXYRange::Range(480, 800, Some(16)));
|
||||
assert_eq!(first_set.y, SdpAttributeImageAttrXYRange::DiscrateValues(vec![100, 200, 300]));
|
||||
assert_eq!(first_set.y, SdpAttributeImageAttrXYRange::DiscreteValues(vec![100, 200, 300]));
|
||||
assert_eq!(first_set.par, Some(SdpAttributeImageAttrPRange {
|
||||
min: 1.2,
|
||||
max: 1.3
|
||||
|
@ -2282,10 +2279,10 @@ fn test_parse_attribute_imageattr() {
|
|||
assert_eq!(first_set.q, Some(0.6));
|
||||
|
||||
let second_set = &sets[1];
|
||||
assert_eq!(second_set.x, SdpAttributeImageAttrXYRange::Value(1080));
|
||||
assert_eq!(second_set.x, SdpAttributeImageAttrXYRange::DiscreteValues(vec![1080]));
|
||||
assert_eq!(second_set.y, SdpAttributeImageAttrXYRange::Range(144, 176, None));
|
||||
assert_eq!(second_set.par, None);
|
||||
assert_eq!(second_set.sar, Some(SdpAttributeImageAttrSRange::Range(0.5, 0.7)));
|
||||
assert_eq!(second_set.sar, Some(SdpAttributeImageAttrSRange::Range(0.5, 0.7)));
|
||||
assert_eq!(second_set.q, None);
|
||||
},
|
||||
_ => { unreachable!(); }
|
||||
|
@ -2294,6 +2291,8 @@ fn test_parse_attribute_imageattr() {
|
|||
|
||||
assert!(parse_attribute("imageattr:99 send [x=320,y=240]").is_ok());
|
||||
assert!(parse_attribute("imageattr:100 recv [x=320,y=240]").is_ok());
|
||||
assert!(parse_attribute("imageattr:97 recv [x=800,y=640,sar=1.1,foo=[123,456],q=0.5] send [x=330,y=250,bar=foo,sar=[20-40]]").is_ok());
|
||||
assert!(parse_attribute("imageattr:97 recv [x=800,y=640,sar=1.1,foo=abc xyz,q=0.5] send [x=330,y=250,bar=foo,sar=[20-40]]").is_ok());
|
||||
|
||||
assert!(parse_attribute("imageattr:").is_err());
|
||||
assert!(parse_attribute("imageattr:100").is_err());
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use std::slice;
|
||||
use libc::{size_t, uint8_t, uint16_t, uint32_t, int64_t, uint64_t};
|
||||
use libc::{size_t, uint8_t, uint16_t, uint32_t, int64_t, uint64_t, c_float};
|
||||
use std::ptr;
|
||||
|
||||
use rsdparsa::SdpSession;
|
||||
use rsdparsa::attribute_type::*;
|
||||
|
@ -743,12 +744,178 @@ pub unsafe extern "C" fn sdp_get_rtcpfbs(attributes: *const Vec<SdpAttribute>, r
|
|||
rtcpfbs.clone_from_slice(attrs.as_slice());
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct RustSdpAttributeImageAttrXYRange {
|
||||
// range
|
||||
pub min: uint32_t,
|
||||
pub max: uint32_t,
|
||||
pub step: uint32_t,
|
||||
|
||||
// discrete values
|
||||
pub discrete_values: *const Vec<u32>,
|
||||
}
|
||||
|
||||
impl<'a> From<&'a SdpAttributeImageAttrXYRange > for RustSdpAttributeImageAttrXYRange {
|
||||
fn from(other: &SdpAttributeImageAttrXYRange) -> Self {
|
||||
match other {
|
||||
&SdpAttributeImageAttrXYRange::Range(min, max, step) => {
|
||||
RustSdpAttributeImageAttrXYRange {
|
||||
min,
|
||||
max,
|
||||
step: step.unwrap_or(1),
|
||||
discrete_values: ptr::null(),
|
||||
}
|
||||
},
|
||||
&SdpAttributeImageAttrXYRange::DiscreteValues(ref discrete_values) => {
|
||||
RustSdpAttributeImageAttrXYRange {
|
||||
min: 0,
|
||||
max: 1,
|
||||
step: 1,
|
||||
discrete_values,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct RustSdpAttributeImageAttrSRange {
|
||||
// range
|
||||
pub min: c_float,
|
||||
pub max: c_float,
|
||||
|
||||
// discrete values
|
||||
pub discrete_values: *const Vec<c_float>,
|
||||
}
|
||||
|
||||
impl<'a> From<&'a SdpAttributeImageAttrSRange> for RustSdpAttributeImageAttrSRange {
|
||||
fn from(other: &SdpAttributeImageAttrSRange) -> Self {
|
||||
match other {
|
||||
&SdpAttributeImageAttrSRange::Range(min, max) => {
|
||||
RustSdpAttributeImageAttrSRange {
|
||||
min,
|
||||
max,
|
||||
discrete_values: ptr::null(),
|
||||
}
|
||||
},
|
||||
&SdpAttributeImageAttrSRange::DiscreteValues(ref discrete_values) => {
|
||||
RustSdpAttributeImageAttrSRange {
|
||||
min: 0.0,
|
||||
max: 1.0,
|
||||
discrete_values,
|
||||
}
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct RustSdpAttributeImageAttrPRange {
|
||||
pub min: c_float,
|
||||
pub max: c_float,
|
||||
}
|
||||
|
||||
impl<'a> From<&'a SdpAttributeImageAttrPRange > for RustSdpAttributeImageAttrPRange {
|
||||
fn from(other: &SdpAttributeImageAttrPRange) -> Self {
|
||||
RustSdpAttributeImageAttrPRange {
|
||||
min: other.min,
|
||||
max: other.max
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct RustSdpAttributeImageAttrSet {
|
||||
pub x: RustSdpAttributeImageAttrXYRange,
|
||||
pub y: RustSdpAttributeImageAttrXYRange,
|
||||
|
||||
pub has_sar: bool,
|
||||
pub sar: RustSdpAttributeImageAttrSRange,
|
||||
|
||||
pub has_par: bool,
|
||||
pub par: RustSdpAttributeImageAttrPRange,
|
||||
|
||||
pub q: c_float,
|
||||
}
|
||||
|
||||
impl<'a> From<&'a SdpAttributeImageAttrSet > for RustSdpAttributeImageAttrSet {
|
||||
fn from(other: &SdpAttributeImageAttrSet) -> Self {
|
||||
RustSdpAttributeImageAttrSet {
|
||||
x: RustSdpAttributeImageAttrXYRange::from(&other.x),
|
||||
y: RustSdpAttributeImageAttrXYRange::from(&other.y),
|
||||
|
||||
has_sar: other.sar.is_some(),
|
||||
sar: match other.sar {
|
||||
Some(ref x) => RustSdpAttributeImageAttrSRange::from(x),
|
||||
// This is just any valid value accepted by rust,
|
||||
// it might as well by uninitilized
|
||||
None => RustSdpAttributeImageAttrSRange::from(
|
||||
&SdpAttributeImageAttrSRange::DiscreteValues(vec![]))
|
||||
},
|
||||
|
||||
has_par: other.par.is_some(),
|
||||
par: match other.par {
|
||||
Some(ref x) => RustSdpAttributeImageAttrPRange::from(x),
|
||||
// This is just any valid value accepted by rust,
|
||||
// it might as well by uninitilized
|
||||
None => RustSdpAttributeImageAttrPRange {
|
||||
min: 0.0,
|
||||
max: 1.0,
|
||||
}
|
||||
},
|
||||
|
||||
q: other.q.unwrap_or(0.5),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct RustSdpAttributeImageAttrSetList {
|
||||
pub sets: *const Vec<SdpAttributeImageAttrSet>
|
||||
}
|
||||
|
||||
impl<'a> From<&'a SdpAttributeImageAttrSetList > for RustSdpAttributeImageAttrSetList {
|
||||
fn from(other: &SdpAttributeImageAttrSetList) -> Self {
|
||||
match other {
|
||||
&SdpAttributeImageAttrSetList::Wildcard =>
|
||||
RustSdpAttributeImageAttrSetList{
|
||||
sets: ptr::null(),
|
||||
},
|
||||
&SdpAttributeImageAttrSetList::Sets(ref sets) =>
|
||||
RustSdpAttributeImageAttrSetList {
|
||||
sets: sets,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn sdp_imageattr_get_set_count(sets: *const Vec<SdpAttributeImageAttrSet>)
|
||||
-> size_t {
|
||||
(*sets).len()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn sdp_imageattr_get_sets(sets: *const Vec<SdpAttributeImageAttrSet>,
|
||||
ret_size: size_t,
|
||||
ret: *mut RustSdpAttributeImageAttrSet) {
|
||||
let rust_sets: Vec<_> = (*sets).iter().map(RustSdpAttributeImageAttrSet::from).collect();
|
||||
let sets = slice::from_raw_parts_mut(ret, ret_size);
|
||||
sets.clone_from_slice(rust_sets.as_slice());
|
||||
}
|
||||
|
||||
|
||||
#[repr(C)]
|
||||
#[derive(Clone, Copy)]
|
||||
pub struct RustSdpAttributeImageAttr {
|
||||
pub pt: u32,
|
||||
pub send: RustSdpAttributeImageAttrSetList,
|
||||
pub recv: RustSdpAttributeImageAttrSetList,
|
||||
}
|
||||
|
||||
impl<'a> From<&'a SdpAttributeImageAttr> for RustSdpAttributeImageAttr {
|
||||
|
@ -758,6 +925,8 @@ impl<'a> From<&'a SdpAttributeImageAttr> for RustSdpAttributeImageAttr {
|
|||
SdpAttributePayloadType::Wildcard => u32::max_value(),
|
||||
SdpAttributePayloadType::PayloadType(x) => x as u32,
|
||||
},
|
||||
send: RustSdpAttributeImageAttrSetList::from(&other.send),
|
||||
recv: RustSdpAttributeImageAttrSetList::from(&other.recv),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,6 +76,24 @@ pub unsafe extern "C" fn string_vec_get_view(vec: *const Vec<String>,
|
|||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f32_vec_len(vec: *const Vec<f32>) -> size_t {
|
||||
(*vec).len()
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn f32_vec_get(vec: *const Vec<f32>,
|
||||
index: size_t,
|
||||
ret: *mut f32) -> nsresult {
|
||||
match (*vec).get(index) {
|
||||
Some(val) => {
|
||||
*ret = *val;
|
||||
NS_OK
|
||||
},
|
||||
None => NS_ERROR_INVALID_ARG
|
||||
}
|
||||
}
|
||||
|
||||
#[no_mangle]
|
||||
pub unsafe extern "C" fn u32_vec_len(vec: *const Vec<u32>) -> size_t {
|
||||
(*vec).len()
|
||||
|
|
Загрузка…
Ссылка в новой задаче