mediahandlerelement.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221
  1. /**
  2. * Copyright (c) 2020 Filip Klembara (in2core)
  3. *
  4. * This library is free software; you can redistribute it and/or
  5. * modify it under the terms of the GNU Lesser General Public
  6. * License as published by the Free Software Foundation; either
  7. * version 2.1 of the License, or (at your option) any later version.
  8. *
  9. * This library is distributed in the hope that it will be useful,
  10. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  12. * Lesser General Public License for more details.
  13. *
  14. * You should have received a copy of the GNU Lesser General Public
  15. * License along with this library; if not, write to the Free Software
  16. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  17. */
  18. #if RTC_ENABLE_MEDIA
  19. #include "mediahandlerelement.hpp"
  20. #include "impl/internals.hpp"
  21. #include <cassert>
  22. namespace rtc {
  23. ChainedMessagesProduct make_chained_messages_product() {
  24. return std::make_shared<std::vector<binary_ptr>>();
  25. }
  26. ChainedMessagesProduct make_chained_messages_product(message_ptr msg) {
  27. std::vector<binary_ptr> msgs = {msg};
  28. return std::make_shared<std::vector<binary_ptr>>(msgs);
  29. }
  30. ChainedOutgoingProduct::ChainedOutgoingProduct(ChainedMessagesProduct messages, message_ptr control)
  31. : messages(messages), control(control) {}
  32. ChainedIncomingProduct::ChainedIncomingProduct(ChainedMessagesProduct incoming,
  33. ChainedMessagesProduct outgoing)
  34. : incoming(incoming), outgoing(outgoing) {}
  35. ChainedIncomingControlProduct::ChainedIncomingControlProduct(
  36. message_ptr incoming, optional<ChainedOutgoingProduct> outgoing)
  37. : incoming(incoming), outgoing(outgoing) {}
  38. MediaHandlerElement::MediaHandlerElement() {}
  39. void MediaHandlerElement::removeFromChain() {
  40. if (upstream) {
  41. upstream->downstream = downstream;
  42. }
  43. if (downstream) {
  44. downstream->upstream = upstream;
  45. }
  46. upstream = nullptr;
  47. downstream = nullptr;
  48. }
  49. void MediaHandlerElement::recursiveRemoveChain() {
  50. if (downstream) {
  51. // `recursiveRemoveChain` removes last strong reference to downstream element
  52. // we need to keep strong reference to prevent deallocation of downstream element
  53. // during `recursiveRemoveChain`
  54. auto strongDownstreamPtr = downstream;
  55. downstream->recursiveRemoveChain();
  56. }
  57. removeFromChain();
  58. }
  59. optional<ChainedOutgoingProduct>
  60. MediaHandlerElement::processOutgoingResponse(ChainedOutgoingProduct messages) {
  61. if (messages.messages) {
  62. if (upstream) {
  63. auto msgs = upstream->formOutgoingBinaryMessage(
  64. ChainedOutgoingProduct(messages.messages, messages.control));
  65. if (msgs.has_value()) {
  66. return msgs.value();
  67. } else {
  68. LOG_ERROR << "Generating outgoing message failed";
  69. return nullopt;
  70. }
  71. } else {
  72. return messages;
  73. }
  74. } else if (messages.control) {
  75. if (upstream) {
  76. auto control = upstream->formOutgoingControlMessage(messages.control);
  77. if (control) {
  78. return ChainedOutgoingProduct(nullptr, control);
  79. } else {
  80. LOG_ERROR << "Generating outgoing control message failed";
  81. return nullopt;
  82. }
  83. } else {
  84. return messages;
  85. }
  86. } else {
  87. return ChainedOutgoingProduct();
  88. }
  89. }
  90. void MediaHandlerElement::prepareAndSendResponse(optional<ChainedOutgoingProduct> outgoing,
  91. std::function<bool(ChainedOutgoingProduct)> send) {
  92. if (outgoing.has_value()) {
  93. auto message = outgoing.value();
  94. auto response = processOutgoingResponse(message);
  95. if (response.has_value()) {
  96. if (!send(response.value())) {
  97. LOG_DEBUG << "Send failed";
  98. }
  99. } else {
  100. LOG_DEBUG << "No response to send";
  101. }
  102. }
  103. }
  104. message_ptr
  105. MediaHandlerElement::formIncomingControlMessage(message_ptr message,
  106. std::function<bool(ChainedOutgoingProduct)> send) {
  107. assert(message);
  108. auto product = processIncomingControlMessage(message);
  109. prepareAndSendResponse(product.outgoing, send);
  110. if (product.incoming) {
  111. if (downstream) {
  112. return downstream->formIncomingControlMessage(product.incoming, send);
  113. } else {
  114. return product.incoming;
  115. }
  116. } else {
  117. return nullptr;
  118. }
  119. }
  120. ChainedMessagesProduct
  121. MediaHandlerElement::formIncomingBinaryMessage(ChainedMessagesProduct messages,
  122. std::function<bool(ChainedOutgoingProduct)> send) {
  123. assert(messages && !messages->empty());
  124. auto product = processIncomingBinaryMessage(messages);
  125. prepareAndSendResponse(product.outgoing, send);
  126. if (product.incoming) {
  127. if (downstream) {
  128. return downstream->formIncomingBinaryMessage(product.incoming, send);
  129. } else {
  130. return product.incoming;
  131. }
  132. } else {
  133. return nullptr;
  134. }
  135. }
  136. message_ptr MediaHandlerElement::formOutgoingControlMessage(message_ptr message) {
  137. assert(message);
  138. auto newMessage = processOutgoingControlMessage(message);
  139. assert(newMessage);
  140. if (!newMessage) {
  141. LOG_ERROR << "Failed to generate outgoing message";
  142. return nullptr;
  143. }
  144. if (upstream) {
  145. return upstream->formOutgoingControlMessage(newMessage);
  146. } else {
  147. return newMessage;
  148. }
  149. }
  150. optional<ChainedOutgoingProduct>
  151. MediaHandlerElement::formOutgoingBinaryMessage(ChainedOutgoingProduct product) {
  152. assert(product.messages && !product.messages->empty());
  153. auto newProduct = processOutgoingBinaryMessage(product.messages, product.control);
  154. assert(!product.control || newProduct.control);
  155. assert(newProduct.messages && !newProduct.messages->empty());
  156. if (product.control && !newProduct.control) {
  157. LOG_ERROR << "Outgoing message must not remove control message";
  158. return nullopt;
  159. }
  160. if (!newProduct.messages || newProduct.messages->empty()) {
  161. LOG_ERROR << "Failed to generate message";
  162. return nullopt;
  163. }
  164. if (upstream) {
  165. return upstream->formOutgoingBinaryMessage(newProduct);
  166. } else {
  167. return newProduct;
  168. }
  169. }
  170. ChainedIncomingControlProduct
  171. MediaHandlerElement::processIncomingControlMessage(message_ptr messages) {
  172. return {messages};
  173. }
  174. message_ptr MediaHandlerElement::processOutgoingControlMessage(message_ptr messages) {
  175. return messages;
  176. }
  177. ChainedIncomingProduct
  178. MediaHandlerElement::processIncomingBinaryMessage(ChainedMessagesProduct messages) {
  179. return {messages};
  180. }
  181. ChainedOutgoingProduct
  182. MediaHandlerElement::processOutgoingBinaryMessage(ChainedMessagesProduct messages,
  183. message_ptr control) {
  184. return {messages, control};
  185. }
  186. shared_ptr<MediaHandlerElement>
  187. MediaHandlerElement::chainWith(shared_ptr<MediaHandlerElement> upstream) {
  188. assert(this->upstream == nullptr);
  189. assert(upstream->downstream == nullptr);
  190. this->upstream = upstream;
  191. upstream->downstream = shared_from_this();
  192. return upstream;
  193. }
  194. } // namespace rtc
  195. #endif /* RTC_ENABLE_MEDIA */