wrtc 0.0.2__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (365) hide show
  1. {wrtc-0.0.2 → wrtc-0.2.0}/CHANGES.md +84 -0
  2. {wrtc-0.0.2 → wrtc-0.2.0}/CMakeLists.txt +3 -0
  3. {wrtc-0.0.2 → wrtc-0.2.0}/Makefile +8 -5
  4. {wrtc-0.0.2 → wrtc-0.2.0}/PKG-INFO +26 -6
  5. {wrtc-0.0.2 → wrtc-0.2.0}/README.md +22 -4
  6. {wrtc-0.0.2 → wrtc-0.2.0}/THIRD_PARTY_LICENSES.md +28 -1
  7. {wrtc-0.0.2 → wrtc-0.2.0}/cmake/libcxx/update.py +53 -23
  8. {wrtc-0.0.2 → wrtc-0.2.0}/cmake/libwebrtc.cmake +31 -0
  9. wrtc-0.2.0/cmake/libwebrtc_windows.cmake +46 -0
  10. {wrtc-0.0.2 → wrtc-0.2.0}/cmake/openh264.cmake +0 -31
  11. {wrtc-0.0.2 → wrtc-0.2.0}/pyproject.toml +21 -6
  12. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/CMakeLists.txt +4 -1
  13. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/NATIVE.md +15 -5
  14. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/codecs/openh264_decoder.cpp +11 -5
  15. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/codecs/openh264_decoder.h +5 -0
  16. wrtc-0.2.0/python-webrtc/cpp/src/codecs/video_codec_factories.cpp +101 -0
  17. wrtc-0.2.0/python-webrtc/cpp/src/codecs/video_codec_factories.h +24 -0
  18. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/codecs/videotoolbox.mm +119 -32
  19. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/media_stream_track.cpp +11 -5
  20. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/peer_connection_factory.cpp +70 -54
  21. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/peer_connection_factory.h +6 -1
  22. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_audio_track_source.cpp +5 -3
  23. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_audio_track_source.h +3 -1
  24. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_data_channel.cpp +60 -25
  25. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_data_channel.h +12 -8
  26. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_dtls_transport.cpp +5 -0
  27. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_dtmf_sender.cpp +39 -32
  28. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_dtmf_sender.h +8 -4
  29. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_ice_transport.cpp +153 -47
  30. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_ice_transport.h +14 -5
  31. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_peer_connection/create_session_description_observer.cpp +5 -2
  32. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_peer_connection/descriptions.cpp +125 -31
  33. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_peer_connection/ice.cpp +132 -49
  34. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_peer_connection/rtc_peer_connection.cpp +60 -30
  35. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_peer_connection/rtc_peer_connection.h +61 -14
  36. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_peer_connection/rtp.cpp +81 -11
  37. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_peer_connection/stats_collector_callback.h +6 -2
  38. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_rtp_sender.cpp +28 -17
  39. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_rtp_sender.h +4 -4
  40. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_rtp_transceiver.cpp +18 -4
  41. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_rtp_transceiver.h +3 -0
  42. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_sctp_transport.cpp +19 -5
  43. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_sctp_transport.h +3 -2
  44. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_video_track_source.cpp +21 -26
  45. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_video_track_source.h +5 -1
  46. wrtc-0.2.0/python-webrtc/cpp/src/interfaces/transceiver_state.h +36 -0
  47. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/encoded_frame.cpp +4 -10
  48. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/encoded_frame.h +2 -1
  49. wrtc-0.2.0/python-webrtc/cpp/src/media/frame_adaptation.h +47 -0
  50. wrtc-0.2.0/python-webrtc/cpp/src/media/frame_buffer_pool.h +102 -0
  51. wrtc-0.2.0/python-webrtc/cpp/src/media/local_video_sink.h +60 -0
  52. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/media_stream_track_processor.cpp +5 -1
  53. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/media_stream_track_processor.h +3 -2
  54. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/relayed_video_track.cpp +13 -2
  55. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/relayed_video_track.h +8 -1
  56. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/rtc_rtp_script_transform.cpp +7 -10
  57. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/rtc_rtp_script_transform.h +1 -1
  58. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/track_generator.cpp +18 -5
  59. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/track_generator.h +5 -0
  60. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/track_monitor.h +3 -1
  61. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/video_frame_buffer.cpp +72 -19
  62. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/python_webrtc/rtc_configuration.cpp +1 -0
  63. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/python_webrtc/rtc_configuration.h +1 -0
  64. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/testing.cpp +84 -0
  65. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/buffer.h +5 -0
  66. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/dispatcher.cpp +8 -0
  67. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/field_trials.h +2 -0
  68. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/libwebrtc_thread.h +19 -0
  69. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/mailbox.cpp +6 -2
  70. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/mailbox.h +39 -9
  71. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/native_object.h +23 -4
  72. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/network_socket_server.cpp +297 -20
  73. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/network_socket_server.h +18 -1
  74. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/port_allocator.cpp +15 -5
  75. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/port_allocator.h +3 -2
  76. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/surfaced.h +11 -2
  77. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/__init__.py +1 -0
  78. wrtc-0.2.0/python-webrtc/python/webrtc/aiortc/_alias.py +27 -0
  79. wrtc-0.2.0/python-webrtc/python/webrtc/aiortc/_ice_servers.py +124 -0
  80. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/_utils.py +17 -5
  81. wrtc-0.2.0/python-webrtc/python/webrtc/aiortc/clock.py +57 -0
  82. wrtc-0.2.0/python-webrtc/python/webrtc/aiortc/jitterbuffer.py +152 -0
  83. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/rtcdatachannel.py +7 -4
  84. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/rtcdtlstransport.py +6 -2
  85. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/rtcicetransport.py +9 -1
  86. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/rtcpeerconnection.py +215 -91
  87. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/rtcrtpreceiver.py +159 -20
  88. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/rtcrtpsender.py +84 -26
  89. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/rtcrtptransceiver.py +10 -4
  90. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/rtcsctptransport.py +2 -0
  91. wrtc-0.2.0/python-webrtc/python/webrtc/aiortc/rtp.py +818 -0
  92. wrtc-0.2.0/python-webrtc/python/webrtc/aiortc/utils.py +82 -0
  93. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/base.py +3 -0
  94. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/exceptions.py +7 -9
  95. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/field_trials.py +6 -2
  96. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/media_devices.py +13 -6
  97. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/media_stream.py +4 -1
  98. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/media_stream_track.py +75 -34
  99. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/media_stream_track_processor.py +25 -20
  100. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/rtc_data_channel.py +17 -10
  101. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/rtc_dtmf_sender.py +9 -2
  102. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/rtc_ice_transport.py +15 -10
  103. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/rtc_peer_connection.py +81 -69
  104. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/rtc_rtp_receiver.py +50 -5
  105. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/rtc_rtp_script_transform.py +40 -23
  106. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/rtc_rtp_sender.py +30 -11
  107. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/rtc_rtp_transceiver.py +3 -2
  108. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/rtc_sctp_transport.py +3 -3
  109. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/sframe_transform.py +13 -8
  110. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/track_generator.py +11 -5
  111. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/loopback.py +1 -1
  112. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/audio_data.py +24 -13
  113. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/blob.py +21 -6
  114. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/events.py +1 -1
  115. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/media_track_constraints.py +3 -3
  116. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/rtc_certificate.py +13 -5
  117. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/rtc_configuration.py +32 -18
  118. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/rtc_encoded_frame.py +23 -13
  119. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/rtc_ice_candidate.py +30 -12
  120. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/rtc_stats.py +72 -29
  121. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/rtp_parameters.py +48 -19
  122. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/rtp_source.py +13 -9
  123. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/video_frame.py +136 -67
  124. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/openh264.py +34 -18
  125. wrtc-0.2.0/python-webrtc/python/webrtc/pipecat/__init__.py +22 -0
  126. wrtc-0.2.0/python-webrtc/python/webrtc/pipecat/_alias.py +26 -0
  127. wrtc-0.2.0/python-webrtc/python/webrtc/pipecat/_media.py +524 -0
  128. wrtc-0.2.0/python-webrtc/python/webrtc/pipecat/connection.py +694 -0
  129. wrtc-0.2.0/python-webrtc/python/webrtc/pipecat/request_handler.py +294 -0
  130. wrtc-0.2.0/python-webrtc/python/webrtc/pipecat/transport.py +703 -0
  131. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/streams.py +161 -106
  132. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/utils/events.py +95 -32
  133. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/utils/lifetime.py +3 -1
  134. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/utils/loops.py +190 -91
  135. wrtc-0.2.0/python-webrtc/python/webrtc/utils/module_alias.py +92 -0
  136. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/utils/names.py +9 -2
  137. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/utils/operations.py +69 -28
  138. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/utils/strings.py +8 -0
  139. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/utils/transfer.py +7 -2
  140. {wrtc-0.0.2 → wrtc-0.2.0}/scripts/debug/cover.py +60 -24
  141. {wrtc-0.0.2 → wrtc-0.2.0}/scripts/debug/hunt.py +140 -59
  142. {wrtc-0.0.2 → wrtc-0.2.0}/scripts/debug/stacks.py +27 -7
  143. {wrtc-0.0.2 → wrtc-0.2.0}/scripts/debug/triage.py +66 -25
  144. {wrtc-0.0.2 → wrtc-0.2.0}/stubs/wrtc/__init__.pyi +18 -11
  145. {wrtc-0.0.2 → wrtc-0.2.0}/stubs/wrtc/_testing.pyi +15 -0
  146. wrtc-0.0.2/python-webrtc/python/webrtc/aiortc/rtp.py → wrtc-0.2.0/tests/aiortc/conftest.py +5 -1
  147. wrtc-0.2.0/tests/aiortc/test_alias.py +89 -0
  148. {wrtc-0.0.2 → wrtc-0.2.0}/tests/aiortc/test_codecs.py +33 -23
  149. wrtc-0.2.0/tests/aiortc/test_downstream_names.py +445 -0
  150. {wrtc-0.0.2 → wrtc-0.2.0}/tests/aiortc/test_media.py +417 -29
  151. {wrtc-0.0.2 → wrtc-0.2.0}/tests/aiortc/test_peer_connection.py +18 -34
  152. {wrtc-0.0.2 → wrtc-0.2.0}/tests/chaos.py +175 -110
  153. {wrtc-0.0.2 → wrtc-0.2.0}/tests/conftest.py +23 -9
  154. {wrtc-0.0.2 → wrtc-0.2.0}/tests/fuzz/fuzz_audio_data.py +16 -3
  155. {wrtc-0.0.2 → wrtc-0.2.0}/tests/fuzz/fuzz_encoded_frame.py +47 -14
  156. {wrtc-0.0.2 → wrtc-0.2.0}/tests/fuzz/fuzz_generator.py +27 -19
  157. {wrtc-0.0.2 → wrtc-0.2.0}/tests/fuzz/fuzz_native_buffers.py +58 -28
  158. {wrtc-0.0.2 → wrtc-0.2.0}/tests/fuzz/fuzz_sframe.py +42 -16
  159. {wrtc-0.0.2 → wrtc-0.2.0}/tests/fuzz/fuzz_sframe_stream.py +16 -3
  160. {wrtc-0.0.2 → wrtc-0.2.0}/tests/fuzz/fuzz_video_frame.py +20 -6
  161. {wrtc-0.0.2 → wrtc-0.2.0}/tests/h264.py +43 -13
  162. {wrtc-0.0.2 → wrtc-0.2.0}/tests/helpers.py +168 -51
  163. {wrtc-0.0.2 → wrtc-0.2.0}/tests/idl/__main__.py +15 -5
  164. {wrtc-0.0.2 → wrtc-0.2.0}/tests/idl/child.py +2 -0
  165. {wrtc-0.0.2 → wrtc-0.2.0}/tests/idl/compare.py +53 -20
  166. {wrtc-0.0.2 → wrtc-0.2.0}/tests/idl/expectations.json +2 -1
  167. {wrtc-0.0.2 → wrtc-0.2.0}/tests/idl/expectations.py +3 -3
  168. {wrtc-0.0.2 → wrtc-0.2.0}/tests/idl/spec.py +21 -13
  169. {wrtc-0.0.2 → wrtc-0.2.0}/tests/isolation.py +18 -7
  170. wrtc-0.2.0/tests/pipecat/_audio.py +33 -0
  171. wrtc-0.2.0/tests/pipecat/_client.py +129 -0
  172. wrtc-0.2.0/tests/pipecat/_stun.py +100 -0
  173. {wrtc-0.0.2/tests/aiortc → wrtc-0.2.0/tests/pipecat}/conftest.py +4 -4
  174. wrtc-0.2.0/tests/pipecat/test_alias.py +151 -0
  175. wrtc-0.2.0/tests/pipecat/test_connection.py +829 -0
  176. wrtc-0.2.0/tests/pipecat/test_decimator.py +118 -0
  177. wrtc-0.2.0/tests/pipecat/test_media.py +481 -0
  178. wrtc-0.2.0/tests/pipecat/test_pipecat_names.py +199 -0
  179. wrtc-0.2.0/tests/pipecat/test_request_handler.py +312 -0
  180. wrtc-0.2.0/tests/pipecat/test_transport.py +928 -0
  181. {wrtc-0.0.2 → wrtc-0.2.0}/tests/rtc_peer_connection/test_add_track.py +7 -16
  182. {wrtc-0.0.2 → wrtc-0.2.0}/tests/rtc_peer_connection/test_add_transceiver.py +17 -29
  183. wrtc-0.2.0/tests/rtc_rtp_transceiver/__init__.py +6 -0
  184. {wrtc-0.0.2 → wrtc-0.2.0}/tests/rtc_rtp_transceiver/test_direction.py +7 -2
  185. {wrtc-0.0.2 → wrtc-0.2.0}/tests/rtc_rtp_transceiver/test_stop.py +18 -33
  186. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_audio_data.py +77 -30
  187. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_blob.py +10 -1
  188. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_configuration.py +77 -21
  189. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_connection_states.py +73 -11
  190. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_data_channel.py +309 -24
  191. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_docstrings.py +19 -6
  192. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_e2e.py +8 -11
  193. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_encoded_transform.py +164 -77
  194. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_enums.py +11 -2
  195. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_events.py +199 -14
  196. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_field_trials.py +133 -15
  197. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_free_threading.py +6 -0
  198. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_helpers.py +8 -1
  199. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_ice_transport.py +280 -65
  200. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_lifetime.py +113 -27
  201. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_lifetime_model.py +52 -32
  202. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_lifetime_transforms.py +89 -24
  203. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_loopback.py +5 -1
  204. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_loops.py +95 -23
  205. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_mailbox.py +76 -37
  206. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_media_devices.py +25 -4
  207. wrtc-0.2.0/tests/test_media_e2e.py +661 -0
  208. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_media_stream_track_processor.py +156 -85
  209. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_media_stress.py +35 -19
  210. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_native_calls.py +14 -3
  211. wrtc-0.2.0/tests/test_native_rules.py +225 -0
  212. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_network.py +93 -11
  213. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_network_stress.py +102 -29
  214. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_openh264.py +68 -12
  215. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_openh264_encoder.py +30 -10
  216. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_openh264_interop.py +68 -45
  217. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_operations.py +90 -24
  218. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_package.py +20 -2
  219. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_robustness_chaos.py +8 -2
  220. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_robustness_exit.py +3 -0
  221. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_robustness_media.py +18 -13
  222. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_robustness_threads.py +112 -16
  223. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_robustness_transforms.py +23 -21
  224. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_rtp_sender_receiver.py +169 -59
  225. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_sdp_munging.py +41 -18
  226. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_session_description.py +25 -8
  227. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_sframe.py +241 -117
  228. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_stats.py +33 -7
  229. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_streams.py +146 -18
  230. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_track_settings.py +53 -31
  231. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_tracks.py +65 -14
  232. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_video.py +26 -25
  233. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_video_frame.py +152 -133
  234. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_videotoolbox.py +65 -49
  235. {wrtc-0.0.2 → wrtc-0.2.0}/uv.lock +2563 -79
  236. wrtc-0.0.2/tests/test_media_e2e.py +0 -301
  237. wrtc-0.0.2/tests/test_native_rules.py +0 -95
  238. {wrtc-0.0.2 → wrtc-0.2.0}/.clang-format +0 -0
  239. {wrtc-0.0.2 → wrtc-0.2.0}/.clang-tidy +0 -0
  240. {wrtc-0.0.2 → wrtc-0.2.0}/.gitignore +0 -0
  241. {wrtc-0.0.2 → wrtc-0.2.0}/.mailmap +0 -0
  242. {wrtc-0.0.2 → wrtc-0.2.0}/.readthedocs.yaml +0 -0
  243. {wrtc-0.0.2 → wrtc-0.2.0}/CONTRIBUTING.md +0 -0
  244. {wrtc-0.0.2 → wrtc-0.2.0}/LICENSE.md +0 -0
  245. {wrtc-0.0.2 → wrtc-0.2.0}/SECURITY.md +0 -0
  246. {wrtc-0.0.2 → wrtc-0.2.0}/cmake/libcxx/README.md +0 -0
  247. {wrtc-0.0.2 → wrtc-0.2.0}/cmake/libcxx/config.sha256 +0 -0
  248. {wrtc-0.0.2 → wrtc-0.2.0}/cmake/libcxx/headers.sha256 +0 -0
  249. {wrtc-0.0.2 → wrtc-0.2.0}/cmake/libcxx/runtime.sha256 +0 -0
  250. {wrtc-0.0.2 → wrtc-0.2.0}/cmake/libwebrtc_linux_fixups.cpp +0 -0
  251. {wrtc-0.0.2 → wrtc-0.2.0}/cmake/openh264.sha256 +0 -0
  252. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/codecs/openh264.cpp +0 -0
  253. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/codecs/openh264.h +0 -0
  254. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/codecs/videotoolbox.h +0 -0
  255. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/enums/enums.cpp +0 -0
  256. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/enums/enums.h +0 -0
  257. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/exceptions.cpp +0 -0
  258. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/exceptions.h +0 -0
  259. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/functions/functions.cpp +0 -0
  260. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/functions/functions.h +0 -0
  261. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/functions/get_user_media.cpp +0 -0
  262. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/functions/get_user_media.h +0 -0
  263. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/interfaces.cpp +0 -0
  264. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/interfaces.h +0 -0
  265. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/media_stream.cpp +0 -0
  266. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/media_stream.h +0 -0
  267. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/media_stream_track.h +0 -0
  268. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_dtls_transport.h +0 -0
  269. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_peer_connection/create_session_description_observer.h +0 -0
  270. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_peer_connection/sdp.cpp +0 -0
  271. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_peer_connection/sdp.h +0 -0
  272. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_peer_connection/set_session_description_observer.h +0 -0
  273. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_rtp_receiver.cpp +0 -0
  274. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/interfaces/rtc_rtp_receiver.h +0 -0
  275. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/audio_samples.cpp +0 -0
  276. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/audio_samples.h +0 -0
  277. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/boringssl.h +0 -0
  278. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/frame_transformer_bridge.cpp +0 -0
  279. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/frame_transformer_bridge.h +0 -0
  280. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/media.cpp +0 -0
  281. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/media.h +0 -0
  282. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/playout_audio_device.cpp +0 -0
  283. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/playout_audio_device.h +0 -0
  284. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/sframe.cpp +0 -0
  285. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/sframe.h +0 -0
  286. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/sframe_transform.cpp +0 -0
  287. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/sframe_transform.h +0 -0
  288. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/source_control.h +0 -0
  289. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/media/video_frame_buffer.h +0 -0
  290. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/models.cpp +0 -0
  291. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/models.h +0 -0
  292. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/python_webrtc/rtc_certificate.cpp +0 -0
  293. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/python_webrtc/rtc_certificate.h +0 -0
  294. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/python_webrtc/rtc_ice_candidate.cpp +0 -0
  295. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/python_webrtc/rtc_ice_candidate.h +0 -0
  296. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/python_webrtc/rtc_session_description.cpp +0 -0
  297. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/python_webrtc/rtc_session_description.h +0 -0
  298. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/python_webrtc/rtc_session_description_init.cpp +0 -0
  299. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/python_webrtc/rtc_session_description_init.h +0 -0
  300. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/webrtc/rtp_parameters.cpp +0 -0
  301. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/webrtc/rtp_parameters.h +0 -0
  302. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/models/webrtc/rtp_transceiver_init.h +0 -0
  303. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/module.cpp +0 -0
  304. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/testing.h +0 -0
  305. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/absl_optional.h +0 -0
  306. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/dispatcher.h +0 -0
  307. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/gil.h +0 -0
  308. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/held_events.h +0 -0
  309. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/locked_function.h +0 -0
  310. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/paced_thread.h +0 -0
  311. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/parking.h +0 -0
  312. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/registry.h +0 -0
  313. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/task_queue_factory.cpp +0 -0
  314. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/cpp/src/utils/task_queue_factory.h +0 -0
  315. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/__init__.py +0 -0
  316. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/codecs/__init__.py +0 -0
  317. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/codecs/h264.py +0 -0
  318. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/codecs/vpx.py +0 -0
  319. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/contrib/__init__.py +0 -0
  320. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/contrib/media.py +0 -0
  321. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/contrib/signaling.py +0 -0
  322. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/events.py +0 -0
  323. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/exceptions.py +0 -0
  324. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/mediastreams.py +0 -0
  325. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/rtcconfiguration.py +0 -0
  326. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/rtcrtpparameters.py +0 -0
  327. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/rtcsessiondescription.py +0 -0
  328. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/sdp.py +0 -0
  329. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/aiortc/stats.py +0 -0
  330. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/enums.py +0 -0
  331. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/__init__.py +0 -0
  332. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/interfaces/rtc_dtls_transport.py +0 -0
  333. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/__init__.py +0 -0
  334. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/closable.py +0 -0
  335. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/dictionary.py +0 -0
  336. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/rtc_offer_answer_options.py +0 -0
  337. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/rtc_rtp_transceiver_init.py +0 -0
  338. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/rtc_session_description.py +0 -0
  339. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/rtc_session_description_init.py +0 -0
  340. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/models/sframe_transform_options.py +0 -0
  341. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/openh264_license.txt +0 -0
  342. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/py.typed +0 -0
  343. {wrtc-0.0.2 → wrtc-0.2.0}/python-webrtc/python/webrtc/utils/__init__.py +0 -0
  344. {wrtc-0.0.2 → wrtc-0.2.0}/scripts/__init__.py +0 -0
  345. {wrtc-0.0.2 → wrtc-0.2.0}/scripts/debug/README.md +0 -0
  346. {wrtc-0.0.2 → wrtc-0.2.0}/scripts/debug/__init__.py +0 -0
  347. {wrtc-0.0.2 → wrtc-0.2.0}/scripts/debug/cores.entitlements +0 -0
  348. {wrtc-0.0.2 → wrtc-0.2.0}/scripts/debug/synthetic.py +0 -0
  349. {wrtc-0.0.2 → wrtc-0.2.0}/tests/__init__.py +0 -0
  350. {wrtc-0.0.2 → wrtc-0.2.0}/tests/aiortc/__init__.py +0 -0
  351. {wrtc-0.0.2 → wrtc-0.2.0}/tests/fuzz/README.md +0 -0
  352. {wrtc-0.0.2 → wrtc-0.2.0}/tests/fuzz/__init__.py +0 -0
  353. {wrtc-0.0.2 → wrtc-0.2.0}/tests/fuzz/inputs.py +0 -0
  354. {wrtc-0.0.2 → wrtc-0.2.0}/tests/idl/LICENSE-W3C.md +0 -0
  355. {wrtc-0.0.2 → wrtc-0.2.0}/tests/idl/README.md +0 -0
  356. {wrtc-0.0.2 → wrtc-0.2.0}/tests/idl/__init__.py +0 -0
  357. {wrtc-0.0.2 → wrtc-0.2.0}/tests/idl/test_compare.py +0 -0
  358. {wrtc-0.0.2 → wrtc-0.2.0}/tests/idl/test_idl.py +0 -0
  359. {wrtc-0.0.2 → wrtc-0.2.0}/tests/idl/webrtc-extensions.idl +0 -0
  360. {wrtc-0.0.2/tests/rtc_peer_connection → wrtc-0.2.0/tests/pipecat}/__init__.py +0 -0
  361. {wrtc-0.0.2/tests/rtc_rtp_transceiver → wrtc-0.2.0/tests/rtc_peer_connection}/__init__.py +0 -0
  362. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_isolation.py +0 -0
  363. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_robustness_exit_handlers.py +0 -0
  364. {wrtc-0.0.2 → wrtc-0.2.0}/tests/test_task_queues.py +0 -0
  365. {wrtc-0.0.2 → wrtc-0.2.0}/tests/timing.py +0 -0
@@ -1,5 +1,89 @@
1
1
  # Change Log
2
2
 
3
+ ## Version 0.2.0
4
+
5
+ **02.11.2026**
6
+
7
+ **🤖 Pipecat bots run on the engine: install `wrtc[pipecat]` and change the imports, and clients stay as they are. See [Use with Pipecat](https://wrtc.marshal.dev/guides/pipecat/)**
8
+
9
+ **🧩 More libraries built on aiortc run on the compat layer unchanged, with `webrtc.aiortc.install_alias()`**
10
+
11
+ **🔌 Clients that can't use UDP reach a server over TCP, without TURN, with `RTCConfiguration.tcp_listen`. See [Clients without UDP](https://wrtc.marshal.dev/guides/connections/#clients-without-udp)**
12
+
13
+ * Add `webrtc.pipecat`, Pipecat's SmallWebRTC transport on the native API, installed with `wrtc[pipecat]`, with `install_alias()` for Pipecat's development runner by [@MarshalX](https://github.com/MarshalX) in [#277](https://github.com/MarshalX/python-webrtc/pull/277)
14
+ * Add a Pipecat voice bot example, with an echo that needs no keys by [@MarshalX](https://github.com/MarshalX) in [#277](https://github.com/MarshalX/python-webrtc/pull/277)
15
+ * Add `webrtc.aiortc.install_alias()`, which makes `import aiortc` give the compat layer, for libraries that import aiortc themselves by [@MarshalX](https://github.com/MarshalX) in [#276](https://github.com/MarshalX/python-webrtc/pull/276)
16
+ * Add aiortc's `rtp`, `jitterbuffer`, `utils` and `clock` modules and the ICE server helpers of `rtcicetransport` to the compat layer by [@MarshalX](https://github.com/MarshalX) in [#276](https://github.com/MarshalX/python-webrtc/pull/276)
17
+ * Drop a compat layer track's buffered frames when its receiver's `_enabled` is set to `False`, and add the track's `_queue`, for libraries that skip stale frames by [@MarshalX](https://github.com/MarshalX) in [#276](https://github.com/MarshalX/python-webrtc/pull/276)
18
+ * Add `RTCConfiguration.tcp_listen` for clients without UDP, also on `webrtc.pipecat`'s connection and request handler by [@MarshalX](https://github.com/MarshalX) in [#278](https://github.com/MarshalX/python-webrtc/pull/278)
19
+ * Add a library comparison guide, a README demo and copy-page actions to the docs by [@MarshalX](https://github.com/MarshalX) in [#271](https://github.com/MarshalX/python-webrtc/pull/271)
20
+ * Fix a video frame leak in the compat layer when a sender's track is replaced or stopped by [@MarshalX](https://github.com/MarshalX) in [#278](https://github.com/MarshalX/python-webrtc/pull/278)
21
+ * Fix compat layer audio `pts` falling behind after dropped audio by [@MarshalX](https://github.com/MarshalX) in [#278](https://github.com/MarshalX/python-webrtc/pull/278)
22
+ * Fix a cancelled stream read losing the next chunk by [@MarshalX](https://github.com/MarshalX) in [#278](https://github.com/MarshalX/python-webrtc/pull/278)
23
+ * Fix ICE and DTLS transport states changing before their events by [@MarshalX](https://github.com/MarshalX) in [#278](https://github.com/MarshalX/python-webrtc/pull/278)
24
+ * Fix the docs' contrast, mobile overflow and dead API links by [@MarshalX](https://github.com/MarshalX) in [#275](https://github.com/MarshalX/python-webrtc/pull/275)
25
+
26
+ ## Version 0.1.0
27
+
28
+ **24.10.2026**
29
+
30
+ **🧪 The first beta: the API follows the specifications and is ready to build on, while compatibility between versions isn't guaranteed until 1.0.0**
31
+
32
+ **⚡ Data channels move 1.2–2.1 Gbps, 7.7–14.6x aiortc's throughput at 10–15% of its CPU per MB. See the [benchmarks](https://wrtc.marshal.dev/benchmarks/)**
33
+
34
+ **🚀 A data channel opens 3.5 ms after `createOffer`, 7–8x faster than aiortc, and `getStats` takes 1.7 instead of 4.2 ms**
35
+
36
+ **🎥 Simulcast for every encoder, and H.264 on macOS that recovers from encoder faults and falls back to OpenH264**
37
+
38
+ **🧭 Transceiver, ICE, SCTP and track state change with the events that report them, as in browsers**
39
+
40
+ **🧩 [Examples](https://wrtc.marshal.dev/examples/) of a server for a browser page, a Gemini Live voice agent, and WHIP/WHEP streams**
41
+
42
+ * Add simulcast for every encoder, on Windows too: each layer is sent in the negotiated codec at its scaled size, whether or not the encoder does simulcast itself. VP9 and AV1 need a `scalabilityMode` such as `L1T1` for each layer by [@MarshalX](https://github.com/MarshalX) in [#254](https://github.com/MarshalX/python-webrtc/pull/254)
43
+ * Fall back to OpenH264, once `await webrtc.openh264.install()` has run, when VideoToolbox can't encode or decode by [@MarshalX](https://github.com/MarshalX) in [#254](https://github.com/MarshalX/python-webrtc/pull/254)
44
+ * Show transceiver, ICE, SCTP and track state with the events that change them: `mid`, `currentDirection` and the selected candidate pair change when their event fires, not before by [@MarshalX](https://github.com/MarshalX) in [#259](https://github.com/MarshalX/python-webrtc/pull/259)
45
+ * Add a Python server for a browser page example: your camera comes back in grayscale, and Python answers a chat over a data channel by [@MarshalX](https://github.com/MarshalX) in [#268](https://github.com/MarshalX/python-webrtc/pull/268)
46
+ * Add a Gemini Live voice agent example, with the API key kept on the server by [@MarshalX](https://github.com/MarshalX) in [#268](https://github.com/MarshalX/python-webrtc/pull/268)
47
+ * Add a WHIP/WHEP example that plays a live stream in the terminal or publishes one by [@MarshalX](https://github.com/MarshalX) in [#268](https://github.com/MarshalX/python-webrtc/pull/268)
48
+ * Add llms.txt, Markdown versions of the docs pages and Context7 and DeepWiki configs by [@MarshalX](https://github.com/MarshalX) in [#265](https://github.com/MarshalX/python-webrtc/pull/265)
49
+ * Credit node-webrtc in the third-party licences by [@MarshalX](https://github.com/MarshalX) in [#262](https://github.com/MarshalX/python-webrtc/pull/262)
50
+ * Speed up connection setup: keep libsrtp initialized and the network list updated, start the network manager and create port allocators without waiting on the network thread by [@MarshalX](https://github.com/MarshalX) in [#261](https://github.com/MarshalX/python-webrtc/pull/261)
51
+ * Speed up the first connection by running libsrtp's self-tests on their own thread by [@MarshalX](https://github.com/MarshalX) in [#261](https://github.com/MarshalX/python-webrtc/pull/261)
52
+ * Gather a candidate pool without waits between phases, and add ICE candidates in one signaling task by [@MarshalX](https://github.com/MarshalX) in [#261](https://github.com/MarshalX/python-webrtc/pull/261)
53
+ * Cut thread hops from negotiation and `getStats`, and share concurrent `getStats` calls: 20 of them take 5.7 instead of 80.9 ms, renegotiation 22% less time and warm setup with trickle 18% less by [@MarshalX](https://github.com/MarshalX) in [#255](https://github.com/MarshalX/python-webrtc/pull/255)
54
+ * Cut signaling-thread waits from getters: `transceiver.mid` takes 1.0 instead of 9.8 µs, `sender.track` 38% less time, `getSelectedCandidatePair()` 46% less and renegotiation 15% less by [@MarshalX](https://github.com/MarshalX) in [#259](https://github.com/MarshalX/python-webrtc/pull/259)
55
+ * Speed up data channels on macOS and Linux with a second, connected socket for a busy peer. Set the `PythonWebRTC-ConnectedSockets` field trial to `Disabled` to turn it off by [@MarshalX](https://github.com/MarshalX) in [#261](https://github.com/MarshalX/python-webrtc/pull/261)
56
+ * Speed up data channel sends with one network-thread task per send, and skip the local address lookup on every UDP packet by [@MarshalX](https://github.com/MarshalX) in [#261](https://github.com/MarshalX/python-webrtc/pull/261)
57
+ * Convert received data channel messages once and deliver them with less Python per message by [@MarshalX](https://github.com/MarshalX) in [#261](https://github.com/MarshalX/python-webrtc/pull/261)
58
+ * Copy data channel messages once: 10–11% more throughput and 7–11% less CPU per MB for 1 KB messages by [@MarshalX](https://github.com/MarshalX) in [#252](https://github.com/MarshalX/python-webrtc/pull/252)
59
+ * Speed up event delivery, skip wake-ups while the event loop drains, and cache session descriptions between the events that change them by [@MarshalX](https://github.com/MarshalX) in [#261](https://github.com/MarshalX/python-webrtc/pull/261)
60
+ * Drop the unused audio processing and video render smoothing, which cost CPU on every received stream by [@MarshalX](https://github.com/MarshalX) in [#249](https://github.com/MarshalX/python-webrtc/pull/249)
61
+ * Send VP8 and H.264 at 720p with 6–9% less CPU per frame by [@MarshalX](https://github.com/MarshalX) in [#256](https://github.com/MarshalX/python-webrtc/pull/256)
62
+ * Wrap NV12 frames without copies, pass NV12 to VideoToolbox as it is, and pool frame buffers by [@MarshalX](https://github.com/MarshalX) in [#257](https://github.com/MarshalX/python-webrtc/pull/257)
63
+ * Copy video frame data once into pooled buffers, and convert VideoToolbox output to I420 in one pass by [@MarshalX](https://github.com/MarshalX) in [#261](https://github.com/MarshalX/python-webrtc/pull/261)
64
+ * Copy encoded frames less and cache RTP sources: 14% less CPU per transformed frame, `getSynchronizationSources()` in 1.3 instead of 14.8 µs. A transform now queues up to 60 unread frames instead of 120 by [@MarshalX](https://github.com/MarshalX) in [#258](https://github.com/MarshalX/python-webrtc/pull/258)
65
+ * Fix sockets raising SIGPIPE on macOS, which kills the process where its default handler is restored by [@MarshalX](https://github.com/MarshalX) in [#267](https://github.com/MarshalX/python-webrtc/pull/267)
66
+ * Fix data channel stalls under load: UDP sockets get a receive buffer of at least 8 MB, which `WebRTC-SetSocketReceiveBuffer` overrides. On Linux, raise `net.core.rmem_max` to allow it. See [Field trials](https://wrtc.marshal.dev/guides/field-trials/) by [@MarshalX](https://github.com/MarshalX) in [#261](https://github.com/MarshalX/python-webrtc/pull/261)
67
+ * Fix a VideoToolbox frame that fails after the encoder took it: the session restarts with a key frame by [@MarshalX](https://github.com/MarshalX) in [#254](https://github.com/MarshalX/python-webrtc/pull/254)
68
+ * Fix a connection kept alive after `close()` by the event loop it was bound to while closing by [@MarshalX](https://github.com/MarshalX) in [#261](https://github.com/MarshalX/python-webrtc/pull/261)
69
+ * Fix the operations of a closed event loop keeping their connections alive by [@MarshalX](https://github.com/MarshalX) in [#261](https://github.com/MarshalX/python-webrtc/pull/261)
70
+ * Fix the next operation starting before the code awaiting the previous one resumes, as in browsers by [@MarshalX](https://github.com/MarshalX) in [#259](https://github.com/MarshalX/python-webrtc/pull/259)
71
+ * Fix `addIceCandidate` without a remote description rejecting late; it now rejects at once by [@MarshalX](https://github.com/MarshalX) in [#261](https://github.com/MarshalX/python-webrtc/pull/261)
72
+ * Fix sends that fail as the remote end closes: they fire `error` with `data-channel-failure`, and their bytes stay in `bufferedAmount` by [@MarshalX](https://github.com/MarshalX) in [#252](https://github.com/MarshalX/python-webrtc/pull/252)
73
+ * Fix remote data channels collected before their `open` event by [@MarshalX](https://github.com/MarshalX) in [#259](https://github.com/MarshalX/python-webrtc/pull/259)
74
+ * Fix DTMF tones and gaps raised to longer minimums than the specification's by [@MarshalX](https://github.com/MarshalX) in [#253](https://github.com/MarshalX/python-webrtc/pull/253)
75
+ * Fix standalone ICE gathering waiting 1 s between phases and gathering passive TCP candidates, and gather IPv6 where the host has it by [@MarshalX](https://github.com/MarshalX) in [#253](https://github.com/MarshalX/python-webrtc/pull/253)
76
+ * Fix the end of candidates of an earlier remote description shown after an ICE restart by [@MarshalX](https://github.com/MarshalX) in [#253](https://github.com/MarshalX/python-webrtc/pull/253)
77
+ * Fix the audio capture time, so the jitter doesn't jump after a send pause by [@MarshalX](https://github.com/MarshalX) in [#253](https://github.com/MarshalX/python-webrtc/pull/253)
78
+ * Fix `VideoTrackGenerator` frames written back to back dropped as duplicates by [@MarshalX](https://github.com/MarshalX) in [#256](https://github.com/MarshalX/python-webrtc/pull/256)
79
+ * Fix relayed remote video not scaled down for its encoder at low bitrates, and a sent track's own sinks getting the encoder's smaller frames by [@MarshalX](https://github.com/MarshalX) in [#256](https://github.com/MarshalX/python-webrtc/pull/256)
80
+ * Fix encoded frames a transform drops staying in memory while the event loop is busy or closed by [@MarshalX](https://github.com/MarshalX) in [#260](https://github.com/MarshalX/python-webrtc/pull/260)
81
+ * Fix writes to a writable stream slowing down as its queue grows by [@MarshalX](https://github.com/MarshalX) in [#264](https://github.com/MarshalX/python-webrtc/pull/264)
82
+ * Fix the empty reason in the OpenAI example's connection error by [@MarshalX](https://github.com/MarshalX) in [#264](https://github.com/MarshalX/python-webrtc/pull/264)
83
+ * Fix the OpenAI example printing the API key in `--help` by [@MarshalX](https://github.com/MarshalX) in [#268](https://github.com/MarshalX/python-webrtc/pull/268)
84
+ * Fix the memory benchmark table when a run stops early at the memory limit, and benchmark charts crashing on a zero value or baseline by [@MarshalX](https://github.com/MarshalX) in [#264](https://github.com/MarshalX/python-webrtc/pull/264)
85
+ * Fix the connections guide's advice to wait for complete ICE gathering, which can take about 40 seconds with a STUN server by [@MarshalX](https://github.com/MarshalX) in [#268](https://github.com/MarshalX/python-webrtc/pull/268)
86
+
3
87
  ## Version 0.0.2
4
88
 
5
89
  **15.10.2026**
@@ -33,5 +33,8 @@ find_package(Python 3.9 REQUIRED COMPONENTS Interpreter Development.Module)
33
33
  find_package(pybind11 CONFIG REQUIRED)
34
34
 
35
35
  include(cmake/openh264.cmake)
36
+ if(WIN32)
37
+ include(cmake/libwebrtc_windows.cmake)
38
+ endif()
36
39
 
37
40
  add_subdirectory(python-webrtc/cpp)
@@ -2,6 +2,9 @@
2
2
 
3
3
  # pinned to the clang-tidy of .github/scripts/tidy.sh
4
4
  CLANG_FORMAT := uvx clang-format==22.1.8
5
+ # pinned so a new release can't break lint; bump together with .github/workflows/ci.yml
6
+ RUFF := uvx ruff==0.17.1
7
+ PYREFLY := uvx pyrefly==1.3.2
5
8
  CPP_SRC = $(shell find python-webrtc/cpp/src -name '*.cpp' -o -name '*.h' -o -name '*.mm')
6
9
 
7
10
  # editable install; the extension is rebuilt automatically on import after C++ changes
@@ -50,15 +53,15 @@ stacks:
50
53
  uv run --no-sync python -m scripts.debug.stacks $(PID) $(O)
51
54
 
52
55
  lint: format-check
53
- uvx ruff check
54
- uvx ruff format --check
56
+ $(RUFF) check
57
+ $(RUFF) format --check
55
58
 
56
59
  typecheck:
57
- uvx pyrefly check
60
+ $(PYREFLY) check
58
61
 
59
62
  format:
60
- uvx ruff check --fix
61
- uvx ruff format
63
+ $(RUFF) check --fix
64
+ $(RUFF) format
62
65
  $(CLANG_FORMAT) -i $(CPP_SRC)
63
66
 
64
67
  format-check:
@@ -1,13 +1,13 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: wrtc
3
- Version: 0.0.2
3
+ Version: 0.2.0
4
4
  Summary: Chrome's WebRTC engine (libwebrtc M152), with the browser API, in Python
5
5
  Keywords: webrtc,libwebrtc,rtc,peer-to-peer,data-channel,video,audio,voip,asyncio,w3c
6
6
  Author-Email: "Ilya (Marshal)" <ilya@marshal.dev>
7
7
  License-Expression: BSD-3-Clause
8
8
  License-File: LICENSE.md
9
9
  License-File: THIRD_PARTY_LICENSES.md
10
- Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Development Status :: 4 - Beta
11
11
  Classifier: Natural Language :: English
12
12
  Classifier: Intended Audience :: Developers
13
13
  Classifier: Framework :: AsyncIO
@@ -51,6 +51,8 @@ Requires-Dist: typing_extensions>=4.10
51
51
  Provides-Extra: aiortc
52
52
  Requires-Dist: pyee<15,>=13; extra == "aiortc"
53
53
  Requires-Dist: av<18,>=14; extra == "aiortc"
54
+ Provides-Extra: pipecat
55
+ Requires-Dist: pipecat-ai<2,>=1.15; python_version >= "3.11" and extra == "pipecat"
54
56
  Description-Content-Type: text/markdown
55
57
 
56
58
  <p align="center">
@@ -73,6 +75,15 @@ Description-Content-Type: text/markdown
73
75
  <a href="https://pypi.org/project/wrtc/">PyPI</a>
74
76
  </p>
75
77
 
78
+ <p align="center">
79
+ <picture>
80
+ <source media="(prefers-color-scheme: dark)" type="image/avif" srcset="https://github.com/MarshalX/python-webrtc/raw/main/docs/source/_static/img/demo-dark.avif">
81
+ <source type="image/avif" srcset="https://github.com/MarshalX/python-webrtc/raw/main/docs/source/_static/img/demo-light.avif">
82
+ <source media="(prefers-color-scheme: dark)" srcset="https://github.com/MarshalX/python-webrtc/raw/main/docs/source/_static/img/demo-dark.gif">
83
+ <img src="https://github.com/MarshalX/python-webrtc/raw/main/docs/source/_static/img/demo-light.gif" alt="A browser page sends its camera to a Python server, which sends it back in grayscale and answers a chat message over a data channel">
84
+ </picture>
85
+ </p>
86
+
76
87
  ---
77
88
 
78
89
  Python WebRTC binds **libwebrtc M152**, the engine inside Chrome, and exposes it through the **W3C APIs you
@@ -153,11 +164,13 @@ equal to the strings of the specification, dictionaries are typed dataclasses, a
153
164
  | Browser API (`RTCPeerConnection`, `createOffer`, …) | ✅ | similar | ❌ rooms | ❌ GObject signals |
154
165
  | Media path | native | Python | native | native |
155
166
  | VP9 and AV1 | ✅ | ❌ | ✅ | ✅ |
156
- | `pip install` on Linux, macOS and Windows | ✅ | ✅ | ✅ | ❌ system packages |
167
+ | `pip install` on Linux, macOS and Windows | ✅ | ✅ | ✅ | ❌ no Linux wheels |
157
168
 
158
- Against aiortc, it opens connections 5–7x faster, moves 4.5–9x more data through a data channel and spends less CPU on
159
- audio. See the [benchmarks](https://wrtc.marshal.dev/benchmarks/), which also measure Pion, libdatachannel and
160
- webrtc-rs.
169
+ Against aiortc, it opens connections 7.3–8.3x faster, moves 7.7–14.6x more data through a data channel and spends
170
+ less CPU on audio. See the [benchmarks](https://wrtc.marshal.dev/benchmarks/), which also measure Pion, libdatachannel
171
+ and webrtc-rs.
172
+
173
+ The full comparison, and when another library is the better choice: [Choosing a Python WebRTC library](https://wrtc.marshal.dev/guides/comparison/).
161
174
 
162
175
  ## Codecs
163
176
 
@@ -194,6 +207,13 @@ Complete programs, ready to copy. The ones with dependencies declare them inline
194
207
  uv run https://raw.githubusercontent.com/MarshalX/python-webrtc/main/examples/janus_streaming.py
195
208
  ```
196
209
 
210
+ ## Pipecat
211
+
212
+ Install `wrtc[pipecat]` and import the SmallWebRTC transport from `webrtc.pipecat`, and your
213
+ [Pipecat](https://www.pipecat.ai) bot runs on Chrome's engine, with its clients unchanged. For Pipecat's development
214
+ runner, call `webrtc.pipecat.install_alias()`. See [Use with Pipecat](https://wrtc.marshal.dev/guides/pipecat/) and the
215
+ [voice bot example](https://github.com/MarshalX/python-webrtc/blob/main/examples/pipecat_bot.py).
216
+
197
217
  ## Status
198
218
 
199
219
  Pre-1.0: the API follows the specifications, but compatibility between versions isn't guaranteed until 1.0.0. See
@@ -18,6 +18,15 @@
18
18
  <a href="https://pypi.org/project/wrtc/">PyPI</a>
19
19
  </p>
20
20
 
21
+ <p align="center">
22
+ <picture>
23
+ <source media="(prefers-color-scheme: dark)" type="image/avif" srcset="https://github.com/MarshalX/python-webrtc/raw/main/docs/source/_static/img/demo-dark.avif">
24
+ <source type="image/avif" srcset="https://github.com/MarshalX/python-webrtc/raw/main/docs/source/_static/img/demo-light.avif">
25
+ <source media="(prefers-color-scheme: dark)" srcset="https://github.com/MarshalX/python-webrtc/raw/main/docs/source/_static/img/demo-dark.gif">
26
+ <img src="https://github.com/MarshalX/python-webrtc/raw/main/docs/source/_static/img/demo-light.gif" alt="A browser page sends its camera to a Python server, which sends it back in grayscale and answers a chat message over a data channel">
27
+ </picture>
28
+ </p>
29
+
21
30
  ---
22
31
 
23
32
  Python WebRTC binds **libwebrtc M152**, the engine inside Chrome, and exposes it through the **W3C APIs you
@@ -98,11 +107,13 @@ equal to the strings of the specification, dictionaries are typed dataclasses, a
98
107
  | Browser API (`RTCPeerConnection`, `createOffer`, …) | ✅ | similar | ❌ rooms | ❌ GObject signals |
99
108
  | Media path | native | Python | native | native |
100
109
  | VP9 and AV1 | ✅ | ❌ | ✅ | ✅ |
101
- | `pip install` on Linux, macOS and Windows | ✅ | ✅ | ✅ | ❌ system packages |
110
+ | `pip install` on Linux, macOS and Windows | ✅ | ✅ | ✅ | ❌ no Linux wheels |
102
111
 
103
- Against aiortc, it opens connections 5–7x faster, moves 4.5–9x more data through a data channel and spends less CPU on
104
- audio. See the [benchmarks](https://wrtc.marshal.dev/benchmarks/), which also measure Pion, libdatachannel and
105
- webrtc-rs.
112
+ Against aiortc, it opens connections 7.3–8.3x faster, moves 7.7–14.6x more data through a data channel and spends
113
+ less CPU on audio. See the [benchmarks](https://wrtc.marshal.dev/benchmarks/), which also measure Pion, libdatachannel
114
+ and webrtc-rs.
115
+
116
+ The full comparison, and when another library is the better choice: [Choosing a Python WebRTC library](https://wrtc.marshal.dev/guides/comparison/).
106
117
 
107
118
  ## Codecs
108
119
 
@@ -139,6 +150,13 @@ Complete programs, ready to copy. The ones with dependencies declare them inline
139
150
  uv run https://raw.githubusercontent.com/MarshalX/python-webrtc/main/examples/janus_streaming.py
140
151
  ```
141
152
 
153
+ ## Pipecat
154
+
155
+ Install `wrtc[pipecat]` and import the SmallWebRTC transport from `webrtc.pipecat`, and your
156
+ [Pipecat](https://www.pipecat.ai) bot runs on Chrome's engine, with its clients unchanged. For Pipecat's development
157
+ runner, call `webrtc.pipecat.install_alias()`. See [Use with Pipecat](https://wrtc.marshal.dev/guides/pipecat/) and the
158
+ [voice bot example](https://github.com/MarshalX/python-webrtc/blob/main/examples/pipecat_bot.py).
159
+
142
160
  ## Status
143
161
 
144
162
  Pre-1.0: the API follows the specifications, but compatibility between versions isn't guaranteed until 1.0.0. See
@@ -242,7 +242,8 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
242
242
 
243
243
  # aiortc
244
244
  The code of webrtc/aiortc/sdp.py, mediastreams.py, rtcconfiguration.py, rtcrtpparameters.py,
245
- rtcsessiondescription.py, stats.py, contrib/media.py and contrib/signaling.py, copied from it:
245
+ rtcsessiondescription.py, stats.py, rtp.py, jitterbuffer.py, utils.py, clock.py, _ice_servers.py, contrib/media.py and
246
+ contrib/signaling.py, copied from it:
246
247
  ```
247
248
  Copyright (c) Jeremy Lainé.
248
249
  All rights reserved.
@@ -2185,6 +2186,32 @@ SPDX-License-Identifier: BSD-2-Clause
2185
2186
 
2186
2187
  ```
2187
2188
 
2189
+ # node-webrtc
2190
+ The first versions of the C++ bindings (2022) were derived from it:
2191
+ ```
2192
+ Copyright (c) 2019 The node-webrtc project authors. All rights reserved.
2193
+
2194
+ Redistribution and use in source and binary forms, with or without modification,
2195
+ are permitted provided that the following conditions are met:
2196
+
2197
+ 1. Redistributions of source code must retain the above copyright notice, this
2198
+ list of conditions and the following disclaimer.
2199
+ 2. Redistributions in binary form must reproduce the above copyright notice,
2200
+ this list of conditions and the following disclaimer in the documentation
2201
+ and/or other materials provided with the distribution.
2202
+
2203
+ THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
2204
+ ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
2205
+ WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
2206
+ DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
2207
+ FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2208
+ DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
2209
+ SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
2210
+ CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
2211
+ TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
2212
+ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
2213
+ ```
2214
+
2188
2215
  # ooura
2189
2216
  ```
2190
2217
  /*
@@ -37,19 +37,27 @@ import subprocess
37
37
  import tempfile
38
38
  from concurrent.futures import ThreadPoolExecutor
39
39
  from pathlib import Path
40
- from typing import TypedDict
40
+ from typing import NamedTuple, TypedDict
41
+
42
+
43
+ class LlvmDir(NamedTuple):
44
+ """How WebRTC pins a directory of llvm-project."""
45
+
46
+ deps_path: str
47
+ cmake_variable: str
48
+
41
49
 
42
50
  REPO = 'repos/llvm/llvm-project'
43
51
  CHROMIUM_CONFIG = ('__config_site', '__assertion_handler')
44
- # llvm-project dir -> (its DEPS path in WebRTC, CMake variable of its commit)
45
52
  LLVM_DIRS = {
46
- 'libcxx': ('src/third_party/libc++/src', 'LIBCXX_LLVM_COMMIT'),
47
- 'libcxxabi': ('src/third_party/libc++abi/src', 'LIBCXXABI_LLVM_COMMIT'),
48
- 'libc': ('src/third_party/llvm-libc/src', 'LLVM_LIBC_COMMIT'),
53
+ 'libcxx': LlvmDir('src/third_party/libc++/src', 'LIBCXX_LLVM_COMMIT'),
54
+ 'libcxxabi': LlvmDir('src/third_party/libc++abi/src', 'LIBCXXABI_LLVM_COMMIT'),
55
+ 'libc': LlvmDir('src/third_party/llvm-libc/src', 'LLVM_LIBC_COMMIT'),
49
56
  }
50
57
  # llvm-project dirs the runtime sources include from: their own trees, and llvm-libc (-I libc)
51
58
  RUNTIME_TREES = ('libcxx/src', 'libcxxabi/src', 'libc')
52
59
  INCLUDE = re.compile(rb'^\s*#\s*include\s*[<"]([^>"]+)[>"]', re.MULTILINE)
60
+ GITHUB_TIME = '%Y-%m-%dT%H:%M:%SZ'
53
61
 
54
62
 
55
63
  class TreeEntry(TypedDict):
@@ -90,7 +98,8 @@ def gh(path: str) -> bytes:
90
98
 
91
99
  def git_tree(sha: str, *, recursive: bool = False) -> Tree:
92
100
  """A git tree of llvm-project."""
93
- tree: Tree = json.loads(gh(f'{REPO}/git/trees/{sha}' + ('?recursive=1' if recursive else '')))
101
+ query = '?recursive=1' if recursive else ''
102
+ tree: Tree = json.loads(gh(f'{REPO}/git/trees/{sha}{query}'))
94
103
  return tree
95
104
 
96
105
 
@@ -141,22 +150,32 @@ def git_fetch(url: str, ref: str, repo: str) -> str:
141
150
  return subprocess.check_output([git, '-C', repo, 'rev-parse', 'FETCH_HEAD'], text=True).strip()
142
151
 
143
152
 
153
+ def commits_near(name: str, committed: str) -> list[Commit]:
154
+ """The llvm-project commits that changed a directory within a day of an ISO 8601 commit time."""
155
+ date = dt.datetime.fromisoformat(committed).astimezone(dt.timezone.utc)
156
+ since = (date - dt.timedelta(days=1)).strftime(GITHUB_TIME)
157
+ until = (date + dt.timedelta(days=1)).strftime(GITHUB_TIME)
158
+ commits: list[Commit] = json.loads(gh(f'{REPO}/commits?path={name}&since={since}&until={until}&per_page=100'))
159
+ return commits
160
+
161
+
144
162
  def resolve_llvm(deps: str, name: str) -> str:
145
163
  """Chromium mirrors each llvm-project dir as its own repo: finds the llvm-project commit with the same tree."""
146
- match = re.search(rf"'{re.escape(LLVM_DIRS[name][0])}':\s*'([^'@]+)@([0-9a-f]+)'", deps)
164
+ deps_path = LLVM_DIRS[name].deps_path
165
+ match = re.search(rf"'{re.escape(deps_path)}':\s*'([^'@]+)@([0-9a-f]+)'", deps)
147
166
  if match is None:
148
- msg = f'{LLVM_DIRS[name][0]} is not in the WebRTC DEPS'
167
+ msg = f'{deps_path} is not in the WebRTC DEPS'
149
168
  raise SystemExit(msg)
169
+
150
170
  url, revision = match.groups()
151
171
  with tempfile.TemporaryDirectory() as repo:
152
172
  git_fetch(url, revision, repo)
153
- tree, committed = subprocess.check_output(
173
+ log = subprocess.check_output(
154
174
  [tool('git'), '-C', repo, 'log', '-1', '--format=%T %cI', 'FETCH_HEAD'], text=True
155
- ).split()
156
- date = dt.datetime.fromisoformat(committed).astimezone(dt.timezone.utc)
157
- since, until = ((date + dt.timedelta(days=d)).strftime('%Y-%m-%dT%H:%M:%SZ') for d in (-1, 1))
158
- commits: list[Commit] = json.loads(gh(f'{REPO}/commits?path={name}&since={since}&until={until}&per_page=100'))
159
- for commit in commits:
175
+ )
176
+ tree, committed = log.split()
177
+
178
+ for commit in commits_near(name, committed):
160
179
  if tree_sha(commit['sha'], name) == tree:
161
180
  return commit['sha']
162
181
  msg = f'no llvm-project commit has the {name} tree of {url}@{revision}'
@@ -167,10 +186,14 @@ def runtime_sources(tag: str) -> list[str]:
167
186
  """The libc++ and libc++abi sources of Chromium's Linux build, as llvm-project paths."""
168
187
  sources: list[str] = []
169
188
  for gn, llvm in (('libc%2B%2B', 'libcxx'), ('libc%2B%2Babi', 'libcxxabi')):
170
- for line in chromium(f'buildtools/third_party/{gn}/BUILD.gn', tag).decode().splitlines():
189
+ build_gn = chromium(f'buildtools/third_party/{gn}/BUILD.gn', tag).decode()
190
+ for line in build_gn.splitlines():
171
191
  match = re.search(r'"//third_party/libc\+\+(?:abi)?/src/src/([^"]+\.cpp)"', line)
172
- if match is not None and not line.lstrip().startswith('#') and 'win32' not in match[1]:
173
- sources.append(f'{llvm}/src/{match[1]}')
192
+ if match is None or line.lstrip().startswith('#'):
193
+ continue
194
+ source = match[1]
195
+ if 'win32' not in source:
196
+ sources.append(f'{llvm}/src/{source}')
174
197
  return sorted(set(sources))
175
198
 
176
199
 
@@ -189,20 +212,27 @@ def pin_runtime(commits: dict[str, str], tag: str) -> None:
189
212
  """Pins the runtime sources and, transitively, every file they include from RUNTIME_TREES."""
190
213
  tree: dict[str, str] = {}
191
214
  for root in RUNTIME_TREES:
192
- tree.update({f'{root}/{e["path"]}': e['sha'] for e in subtree(commits[root.split('/')[0]], root)})
215
+ llvm_dir = root.split('/')[0]
216
+ tree.update({f'{root}/{e["path"]}': e['sha'] for e in subtree(commits[llvm_dir], root)})
217
+
193
218
  sources = runtime_sources(tag)
194
219
  pinned: dict[str, bytes] = {}
195
220
  queue = list(sources)
196
221
  with ThreadPoolExecutor(8) as pool:
197
222
  while len(queue) > 0:
198
- pinned.update(zip(queue, pool.map(blob, [tree[p] for p in queue])))
199
- found = set[str]().union(*(includes(path, pinned[path]) for path in queue))
223
+ contents = pool.map(blob, [tree[path] for path in queue])
224
+ pinned.update(zip(queue, contents))
225
+ found: set[str] = set()
226
+ for path in queue:
227
+ found |= includes(path, pinned[path])
200
228
  queue = sorted(c for c in found if c in tree and c not in pinned)
229
+
201
230
  # CMake compiles every pinned libcxx/libcxxabi .cpp, so only the sources may be among them
202
231
  stray = [p for p in pinned if p.endswith('.cpp') and p not in sources and not p.startswith('libc/')]
203
232
  if len(stray) > 0:
204
233
  msg = f'sources include other .cpp files: {stray}'
205
234
  raise SystemExit(msg)
235
+
206
236
  lines = [f'{hashlib.sha256(data).hexdigest()} {path}\n' for path, data in sorted(pinned.items())]
207
237
  (Path(__file__).parent / 'runtime.sha256').write_text(''.join(lines))
208
238
  print(f'{len(sources)} runtime sources, {len(lines)} files pinned')
@@ -227,7 +257,7 @@ def pin_headers(commit: str, headers: Path) -> None:
227
257
  msg = f'the prebuilt headers differ from llvm-project@{commit}: {mismatches[:10]}'
228
258
  raise SystemExit(msg)
229
259
 
230
- missing = [e for e in tree if e['path'] not in local and '.' not in e['path'].rsplit('/', 1)[-1]]
260
+ missing = [e for e in tree if e['path'] not in local and '.' not in posixpath.basename(e['path'])]
231
261
 
232
262
  def sha256(entry: TreeEntry) -> str:
233
263
  data = blob(entry['sha'])
@@ -262,8 +292,8 @@ def main() -> None:
262
292
  pin_config(args.chromium_tag)
263
293
  pin_runtime(commits, args.chromium_tag)
264
294
 
265
- for name, (_, variable) in LLVM_DIRS.items():
266
- print(f'set({variable} {commits[name]})')
295
+ for name, llvm_dir in LLVM_DIRS.items():
296
+ print(f'set({llvm_dir.cmake_variable} {commits[name]})')
267
297
  print(f'set(LIBCXX_CHROMIUM_TAG {args.chromium_tag})')
268
298
 
269
299
 
@@ -69,6 +69,37 @@ function(_fetch_pinned manifest base_url dest)
69
69
  endforeach()
70
70
  endfunction()
71
71
 
72
+ # Downloads a file of libwebrtc at LIBWEBRTC_COMMIT; googlesource serves files only base64-encoded
73
+ function(_fetch_webrtc path sha256 dest)
74
+ set(_encoded "${dest}.b64")
75
+ foreach(_attempt RANGE 1 4)
76
+ file(DOWNLOAD "https://webrtc.googlesource.com/src/+/${LIBWEBRTC_COMMIT}/${path}?format=TEXT"
77
+ "${_encoded}" STATUS _status TLS_VERIFY ON)
78
+ list(GET _status 0 _code)
79
+ if(_code EQUAL 0)
80
+ execute_process(
81
+ COMMAND "${Python_EXECUTABLE}" -c
82
+ "import base64, pathlib, sys; p = pathlib.Path(sys.argv[2]); p.parent.mkdir(parents=True, exist_ok=True); p.write_bytes(base64.b64decode(pathlib.Path(sys.argv[1]).read_bytes()))"
83
+ "${_encoded}" "${dest}"
84
+ RESULT_VARIABLE _decoded)
85
+ if(_decoded EQUAL 0)
86
+ file(SHA256 "${dest}" _actual)
87
+ if(_actual STREQUAL sha256)
88
+ file(REMOVE "${_encoded}")
89
+ return()
90
+ endif()
91
+ set(_status "SHA256 mismatch: ${_actual}")
92
+ else()
93
+ set(_status "can't decode it")
94
+ endif()
95
+ endif()
96
+ if(_attempt EQUAL 4)
97
+ message(FATAL_ERROR "Failed to fetch ${path} at ${LIBWEBRTC_COMMIT}: ${_status}")
98
+ endif()
99
+ execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep ${_attempt})
100
+ endforeach()
101
+ endfunction()
102
+
72
103
  # Header directories (relative to include/) needed to compile against the public API.
73
104
  set(LIBWEBRTC_HEADER_DIRS
74
105
  api audio call common_audio common_video logging media modules net p2p pc
@@ -0,0 +1,46 @@
1
+ # Fetches the libwebrtc sources the Windows prebuilt compiles out: the simulcast encoder adapter, and the encoder
2
+ # fallback wrapper it creates.
3
+ #
4
+ # Sets LIBWEBRTC_WINDOWS_SRC.
5
+
6
+ set(_sources
7
+ "media/engine/simulcast_encoder_adapter.cc"
8
+ "0fac2e2e51e3bf0a595d10b3ce5e197b1c40e4d11cbd8852d84e1fcf104a6e45"
9
+ "api/video_codecs/video_encoder_software_fallback_wrapper.cc"
10
+ "52251651cb273455adcc8db4dfe1dc654a243e709beb5a528bdbb0279f614908")
11
+
12
+ if(LIBWEBRTC_CACHE_DIR)
13
+ set(_dir "${LIBWEBRTC_CACHE_DIR}/libwebrtc-windows-src-${LIBWEBRTC_VERSION}")
14
+ else()
15
+ set(_dir "${CMAKE_BINARY_DIR}/libwebrtc-windows-src")
16
+ endif()
17
+
18
+ set(LIBWEBRTC_WINDOWS_SRC "")
19
+ set(_stamp "${_dir}/.complete")
20
+ set(_stamp_content "${LIBWEBRTC_COMMIT};${_sources}")
21
+ set(_stamp_current "")
22
+ if(EXISTS "${_stamp}")
23
+ file(READ "${_stamp}" _stamp_current)
24
+ endif()
25
+ set(_fetch FALSE)
26
+ if(NOT _stamp_current STREQUAL _stamp_content)
27
+ message(STATUS "Fetching libwebrtc's simulcast encoder adapter, which the Windows prebuilt lacks")
28
+ file(REMOVE_RECURSE "${_dir}")
29
+ set(_fetch TRUE)
30
+ endif()
31
+
32
+ list(LENGTH _sources _count)
33
+ math(EXPR _last "${_count} - 1")
34
+ foreach(_i RANGE 0 ${_last} 2)
35
+ math(EXPR _j "${_i} + 1")
36
+ list(GET _sources ${_i} _path)
37
+ list(GET _sources ${_j} _sha)
38
+ if(_fetch)
39
+ _fetch_webrtc("${_path}" "${_sha}" "${_dir}/${_path}")
40
+ endif()
41
+ list(APPEND LIBWEBRTC_WINDOWS_SRC "${_dir}/${_path}")
42
+ endforeach()
43
+
44
+ if(_fetch)
45
+ file(WRITE "${_stamp}" "${_stamp_content}")
46
+ endif()
@@ -16,37 +16,6 @@ endif()
16
16
  set(OPENH264_INCLUDE_DIR "${_dir}/include")
17
17
  set(OPENH264_ENCODER_SRC "${_dir}/webrtc/${_encoder}.cc")
18
18
 
19
- # Downloads a file of libwebrtc at LIBWEBRTC_COMMIT; googlesource serves files only base64-encoded
20
- function(_fetch_webrtc path sha256 dest)
21
- set(_encoded "${dest}.b64")
22
- foreach(_attempt RANGE 1 4)
23
- file(DOWNLOAD "https://webrtc.googlesource.com/src/+/${LIBWEBRTC_COMMIT}/${path}?format=TEXT"
24
- "${_encoded}" STATUS _status TLS_VERIFY ON)
25
- list(GET _status 0 _code)
26
- if(_code EQUAL 0)
27
- execute_process(
28
- COMMAND "${Python_EXECUTABLE}" -c
29
- "import base64, pathlib, sys; p = pathlib.Path(sys.argv[2]); p.parent.mkdir(parents=True, exist_ok=True); p.write_bytes(base64.b64decode(pathlib.Path(sys.argv[1]).read_bytes()))"
30
- "${_encoded}" "${dest}"
31
- RESULT_VARIABLE _decoded)
32
- if(_decoded EQUAL 0)
33
- file(SHA256 "${dest}" _actual)
34
- if(_actual STREQUAL sha256)
35
- file(REMOVE "${_encoded}")
36
- return()
37
- endif()
38
- set(_status "SHA256 mismatch: ${_actual}")
39
- else()
40
- set(_status "can't decode it")
41
- endif()
42
- endif()
43
- if(_attempt EQUAL 4)
44
- message(FATAL_ERROR "Failed to fetch ${path} at ${LIBWEBRTC_COMMIT}: ${_status}")
45
- endif()
46
- execute_process(COMMAND "${CMAKE_COMMAND}" -E sleep ${_attempt})
47
- endforeach()
48
- endfunction()
49
-
50
19
  file(SHA256 "${CMAKE_CURRENT_LIST_DIR}/openh264.sha256" _manifest_hash)
51
20
  set(_stamp "${_dir}/.complete")
52
21
  set(_stamp_content