whip-utils.h 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #pragma once
  2. #include <obs.h>
  3. #include <string>
  4. #include <random>
  5. #include <sstream>
  6. #define do_log(level, format, ...) \
  7. blog(level, "[obs-webrtc] [whip_output: '%s'] " format, obs_output_get_name(output), ##__VA_ARGS__)
  8. static uint32_t generate_random_u32()
  9. {
  10. std::random_device rd;
  11. std::mt19937 gen(rd());
  12. std::uniform_int_distribution<uint32_t> dist(1, (UINT32_MAX - 1));
  13. return dist(gen);
  14. }
  15. static std::string trim_string(const std::string &source)
  16. {
  17. std::string ret(source);
  18. ret.erase(0, ret.find_first_not_of(" \n\r\t"));
  19. ret.erase(ret.find_last_not_of(" \n\r\t") + 1);
  20. return ret;
  21. }
  22. static std::string value_for_header(const std::string &header, const std::string &val)
  23. {
  24. if (val.size() <= header.size() || astrcmpi_n(header.c_str(), val.c_str(), header.size()) != 0) {
  25. return "";
  26. }
  27. auto delimiter = val.find_first_of(" ");
  28. if (delimiter == std::string::npos) {
  29. return "";
  30. }
  31. return val.substr(delimiter + 1);
  32. }
  33. static size_t curl_writefunction(char *data, size_t size, size_t nmemb, void *priv_data)
  34. {
  35. auto read_buffer = static_cast<std::string *>(priv_data);
  36. size_t real_size = size * nmemb;
  37. read_buffer->append(data, real_size);
  38. return real_size;
  39. }
  40. static size_t curl_header_function(char *data, size_t size, size_t nmemb, void *priv_data)
  41. {
  42. auto header_buffer = static_cast<std::vector<std::string> *>(priv_data);
  43. header_buffer->push_back(trim_string(std::string(data, size * nmemb)));
  44. return size * nmemb;
  45. }
  46. static inline std::string generate_user_agent()
  47. {
  48. #ifdef _WIN64
  49. #define OS_NAME "Windows x86_64"
  50. #elif __APPLE__
  51. #define OS_NAME "Mac OS X"
  52. #elif __OpenBSD__
  53. #define OS_NAME "OpenBSD"
  54. #elif __FreeBSD__
  55. #define OS_NAME "FreeBSD"
  56. #elif __linux__ && __LP64__
  57. #define OS_NAME "Linux x86_64"
  58. #else
  59. #define OS_NAME "Linux"
  60. #endif
  61. // Build the user-agent string
  62. std::stringstream ua;
  63. // User agent header prefix
  64. ua << "User-Agent: Mozilla/5.0 ";
  65. // OBS version info
  66. ua << "(OBS-Studio/" << obs_get_version_string() << "; ";
  67. // Operating system version info
  68. ua << OS_NAME << "; " << obs_get_locale() << ")";
  69. return ua.str();
  70. }
  71. static size_t simulcast_layers_in_answer(std::string answer)
  72. {
  73. auto layersStart = answer.find("a=simulcast");
  74. if (layersStart == std::string::npos) {
  75. return 0;
  76. }
  77. auto layersEnd = answer.find("\r\n", layersStart);
  78. if (layersEnd == std::string::npos) {
  79. return 0;
  80. }
  81. size_t layersAccepted = 1;
  82. for (auto i = layersStart; i < layersEnd; i++) {
  83. if (answer[i] == ';') {
  84. layersAccepted++;
  85. }
  86. }
  87. return layersAccepted;
  88. }