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:
Johannes Willbold 2018-07-02 15:10:19 -07:00
Родитель c34d1a7a92
Коммит c420368865
9 изменённых файлов: 496 добавлений и 147 удалений

Просмотреть файл

@ -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 = &current_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 = &current_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()