使用std :: string作为通用uint8_t缓冲区

时间:2018-11-25 18:42:33

标签: c++

我正在浏览Chromium的源代码,以研究他们如何实现MediaRecorder API,该API将原始麦克风输入流编码/记录为特定格式。

我遇到了interesting codes from their source。简而言之:

matriu # matrix with cells in either state (0,1,2,3)
colors  <- colorRampPalette(c("green", "red", "white", "blue"))
graph   <- levelplot(matriu, col.regions = colors, cuts = 3)
print(graph)

因此,bool DoEncode(float* data_in, std::string* data_out) { ... data_out->resize(MAX_DATA_BTYES_OR_SOMETHING); opus_encode_float( data_in, reinterpret_cast<uint8_t*>(base::data(*data_out)) ); ... } (C ++方法)在这里接受一个float数组并将其转换为编码的字节流,并且实际操作是在DoEncode(这是一个纯C函数)中完成的。

有趣的部分是Google Chromium团队使用opus_encode_float()而不是std::string来存储字节数组,甚至将它们手动转换为uint8_t缓冲区。

为什么Google Chromium团队的成员会这样,并且有这样一种情况,对于通用字节缓冲区,使用std::vector<uint_8>比使用std::string这样的缓冲区更有用?

2 个答案:

答案 0 :(得分:4)

Chromium编码样式(请参见下文)禁止无正当理由使用无符号整数类型。外部API不是这种原因。有符号和无符号字符的大小为1,为什么不这样。

我查看了opus编码器API,似乎早期版本使用的是签名char:

[out]   data    char*: Output payload (at least max_data_bytes long)

尽管API现在使用未签名的字符,但是描述仍然引用已签名的字符。因此,std::string for chars对于较早的API更加方便,Chromium团队在更新API后并未更改已使用的容器,而是在一行中使用强制转换而不是在其他几行中进行更新。

整数类型

除非有正当的理由(例如表示位模式而不是数字),否则您不应使用诸如uint32_t之类的无符号整数类型,或者您需要定义溢出模2^N。特别是,请勿使用无符号类型来表示数字永远不会为负数。而是为此使用断言。

如果您的代码是一个返回大小的容器,请确保使用可容纳该容器的任何可能使用的类型。如有疑问,请使用较大的类型而不是较小的类型。

转换整数类型时要小心。整数转换和升级可能导致不确定的行为,从而导致安全漏洞和其他问题。

关于无符号整数

无符号整数非常适合表示位字段和模块化算术。由于历史上的意外,C ++标准还使用无符号整数来表示容器的大小-标准主体的许多成员认为这是一个错误,但实际上目前无法修复。无符号算术不能对简单整数的行为进行建模,而是由标准定义以对模块化算术进行建模(对上溢/下溢进行环绕),这一事实意味着编译器无法诊断出大量的错误。在其他情况下,定义的行为会阻碍优化。

也就是说,混合整数类型的符号性会导致同样大类的问题。我们可以提供的最佳建议:尝试使用迭代器和容器而不是指针和大小,尝试不混合有符号性,并避免使用无符号类型(表示位域或模块化算术除外)。不要仅使用无符号类型来断言变量是非负的。

答案 1 :(得分:1)

我们只能理论化。

我的推测:他们想使用std::string中存在的内置SSO优化,但可能不适用于std::vector<uint8_t>