19 #include <type_traits> 29 struct StringMapping {
34 const StringMapping kContainerMap[] = {
38 const StringMapping kCodecMap[] = {
39 {
"avc1",
"h264"}, {
"avc3",
"h264"}, {
"hev1",
"hevc"},
40 {
"hvc1",
"hevc"}, {
"vp09",
"vp9"}, {
"mp4a",
"aac"},
43 constexpr
const char* kWhitespaceCharacters =
" \f\n\r\t\v";
46 bool IsToken(
const std::string& token) {
47 return !token.empty() &&
48 token.find_first_of(R
"(()<>@,;:\"/[]?=)") == std::string::npos && 49 token.find_first_of(kWhitespaceCharacters) == std::string::npos; 52 std::string substr_end(const std::string&
source, std::string::size_type start,
53 std::string::size_type end) {
54 if (end == std::string::npos)
55 return source.substr(start);
57 return source.substr(start, end - start);
64 std::unordered_map<std::string, std::string>* params) {
66 const auto type_end = source.find(
'/');
67 if (type_end == std::string::npos)
69 std::string type_tmp =
71 if (!IsToken(type_tmp))
74 *type = std::move(type_tmp);
77 const auto subtype_end = source.find(
';', type_end);
78 std::string subtype_tmp =
80 if (!IsToken(subtype_tmp))
83 *subtype = std::move(subtype_tmp);
86 auto param_end = subtype_end;
87 while (param_end != std::string::npos) {
88 const auto name_end = source.find(
'=', param_end);
89 if (name_end == std::string::npos)
92 const std::string param_name =
94 if (!IsToken(param_name))
97 const auto value_start =
98 source.find_first_not_of(kWhitespaceCharacters, name_end + 1);
100 if (value_start == std::string::npos) {
101 param_end = std::string::npos;
103 }
else if (source[value_start] ==
'"') {
104 const auto str_end = source.find(
'"', value_start + 1);
105 if (str_end == std::string::npos)
107 value = substr_end(source, value_start + 1, str_end);
108 param_end = source.find(
';', str_end);
110 const std::string extra =
115 param_end = source.find(
';', name_end);
117 substr_end(source, name_end + 1, param_end));
129 for (
const auto& entry : kContainerMap)
130 if (container == entry.source)
136 const std::string simple_codec = codec.substr(0, codec.find(
'.'));
137 for (
const auto& entry : kCodecMap)
138 if (simple_codec == entry.source)
145 const std::vector<BufferedRanges>& sources) {
150 for (
auto&
source : sources) {
152 size_t acc_i = 0, source_i = 0;
154 while (acc_i < accumulated.size() && source_i <
source.size()) {
156 std::max(accumulated[acc_i].start,
source[source_i].start);
157 const double end = std::min(accumulated[acc_i].end,
source[source_i].end);
159 temp.emplace_back(start, end);
161 if (accumulated[acc_i].end <
source[source_i].end)
167 accumulated.swap(temp);
179 std::unordered_map<std::string, std::string> params;
181 info.
video.
width = std::atol(params[
"width"].c_str());
182 info.
video.
height = std::atol(params[
"height"].c_str());
186 static_cast<uint16_t
>(std::atoi(params[
"channels"].c_str()));
189 std::atoll(params[
"bitrate"].c_str());
197 return {UINT32_MAX, UINT32_MAX};
std::string ToAsciiLower(const std::string &source)
std::string TrimAsciiWhitespace(const std::string &source)