libdatachannel-py 2025.1.0.dev6__tar.gz → 2025.1.0.dev8__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.
- {libdatachannel_py-2025.1.0.dev6/src/libdatachannel_py.egg-info → libdatachannel_py-2025.1.0.dev8}/PKG-INFO +1 -1
- libdatachannel_py-2025.1.0.dev8/VERSION +1 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/buildbase.py +123 -2
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/pyproject.toml +5 -5
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/run.py +79 -0
- libdatachannel_py-2025.1.0.dev8/src/libdatachannel/libdatachannel_ext.cpython-313-darwin.so +0 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/src/libdatachannel/libdatachannel_ext.pyi +2 -210
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8/src/libdatachannel_py.egg-info}/PKG-INFO +1 -1
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/src/libdatachannel_py.egg-info/SOURCES.txt +2 -0
- libdatachannel_py-2025.1.0.dev8/tests/test_audio_codec.py +72 -0
- libdatachannel_py-2025.1.0.dev8/tests/test_libyuv.py +200 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/tests/test_video_codec.py +45 -13
- libdatachannel_py-2025.1.0.dev6/VERSION +0 -1
- libdatachannel_py-2025.1.0.dev6/src/libdatachannel/libdatachannel_ext.cpython-313-darwin.so +0 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/LICENSE +0 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/MANIFEST.in +0 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/README.md +0 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/pypath.py +0 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/setup.cfg +0 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/setup.py +0 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/src/libdatachannel/__init__.py +0 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/src/libdatachannel/py.typed +0 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/src/libdatachannel_py.egg-info/dependency_links.txt +0 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/src/libdatachannel_py.egg-info/top_level.txt +0 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/tests/test_candidate.py +0 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/tests/test_configuration.py +0 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/tests/test_description.py +0 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/tests/test_frameinfo.py +0 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/tests/test_h265nalunit.py +0 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/tests/test_mediahandler.py +0 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/tests/test_message.py +0 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/tests/test_nalunit.py +0 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/tests/test_packetizationconfig.py +0 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/tests/test_peerconnection.py +0 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/tests/test_reliability.py +0 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/tests/test_rtppacketizer.py +0 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/tests/test_websocket.py +0 -0
- {libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/tests/test_websocketserver.py +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2025.1.0.dev8
|
|
@@ -702,8 +702,8 @@ def build_and_install_boost(
|
|
|
702
702
|
):
|
|
703
703
|
version_underscore = version.replace(".", "_")
|
|
704
704
|
archive = download(
|
|
705
|
-
#
|
|
706
|
-
f"https://
|
|
705
|
+
# 公式サイトに負荷をかけないための時雨堂によるミラー
|
|
706
|
+
f"https://oss-mirrors.shiguredo.jp/boost_{version_underscore}.tar.gz",
|
|
707
707
|
# Boost 公式のミラー
|
|
708
708
|
# f"https://archives.boost.io/release/{version}/source/boost_{version_underscore}.tar.gz",
|
|
709
709
|
source_dir,
|
|
@@ -1748,6 +1748,7 @@ def install_opus(
|
|
|
1748
1748
|
"cmake",
|
|
1749
1749
|
f"-DCMAKE_INSTALL_PREFIX={cmake_path(opus_install_dir)}",
|
|
1750
1750
|
f"-DCMAKE_BUILD_TYPE={configuration}",
|
|
1751
|
+
"-DCMAKE_POSITION_INDEPENDENT_CODE=ON",
|
|
1751
1752
|
"-DOPUS_BUILD_SHARED_LIBRARY=OFF",
|
|
1752
1753
|
"-DOPUS_BUILD_TESTING=OFF",
|
|
1753
1754
|
"-DOPUS_BUILD_PROGRAMS=OFF",
|
|
@@ -1841,6 +1842,126 @@ def install_mbedtls(version, source_dir, build_dir, install_dir, debug, cmake_ar
|
|
|
1841
1842
|
cmd(["cmake", "--install", os.path.join(build_dir, "mbedtls")])
|
|
1842
1843
|
|
|
1843
1844
|
|
|
1845
|
+
@versioned
|
|
1846
|
+
def install_libjpeg_turbo(version, source_dir, build_dir, install_dir, configuration, cmake_args):
|
|
1847
|
+
libjpeg_source_dir = os.path.join(source_dir, "libjpeg-turbo")
|
|
1848
|
+
libjpeg_build_dir = os.path.join(build_dir, "libjpeg-turbo")
|
|
1849
|
+
libjpeg_install_dir = os.path.join(install_dir, "libjpeg-turbo")
|
|
1850
|
+
rm_rf(libjpeg_source_dir)
|
|
1851
|
+
rm_rf(libjpeg_build_dir)
|
|
1852
|
+
rm_rf(libjpeg_install_dir)
|
|
1853
|
+
git_clone_shallow(
|
|
1854
|
+
"https://github.com/libjpeg-turbo/libjpeg-turbo.git",
|
|
1855
|
+
version,
|
|
1856
|
+
libjpeg_source_dir,
|
|
1857
|
+
)
|
|
1858
|
+
mkdir_p(libjpeg_build_dir)
|
|
1859
|
+
with cd(libjpeg_build_dir):
|
|
1860
|
+
cmd(
|
|
1861
|
+
[
|
|
1862
|
+
"cmake",
|
|
1863
|
+
libjpeg_source_dir,
|
|
1864
|
+
f"-DCMAKE_INSTALL_PREFIX={libjpeg_install_dir}",
|
|
1865
|
+
f"-DCMAKE_BUILD_TYPE={configuration}",
|
|
1866
|
+
"-DENABLE_SHARED=FALSE",
|
|
1867
|
+
"-DENABLE_STATIC=TRUE",
|
|
1868
|
+
"-DCMAKE_BUILD_TYPE=Release",
|
|
1869
|
+
"-DCMAKE_POSITION_INDEPENDENT_CODE=ON",
|
|
1870
|
+
]
|
|
1871
|
+
+ cmake_args
|
|
1872
|
+
)
|
|
1873
|
+
cmd(
|
|
1874
|
+
[
|
|
1875
|
+
"cmake",
|
|
1876
|
+
"--build",
|
|
1877
|
+
libjpeg_build_dir,
|
|
1878
|
+
f"-j{multiprocessing.cpu_count()}",
|
|
1879
|
+
"--config",
|
|
1880
|
+
"Release",
|
|
1881
|
+
]
|
|
1882
|
+
)
|
|
1883
|
+
cmd(["cmake", "--install", libjpeg_build_dir])
|
|
1884
|
+
|
|
1885
|
+
|
|
1886
|
+
@versioned
|
|
1887
|
+
def install_libyuv(
|
|
1888
|
+
version, source_dir, build_dir, install_dir, libjpeg_turbo_dir, configuration, cmake_args
|
|
1889
|
+
):
|
|
1890
|
+
libyuv_source_dir = os.path.join(source_dir, "libyuv")
|
|
1891
|
+
libyuv_build_dir = os.path.join(build_dir, "libyuv")
|
|
1892
|
+
libyuv_install_dir = os.path.join(install_dir, "libyuv")
|
|
1893
|
+
rm_rf(libyuv_source_dir)
|
|
1894
|
+
rm_rf(libyuv_build_dir)
|
|
1895
|
+
rm_rf(libyuv_install_dir)
|
|
1896
|
+
git_clone_shallow(
|
|
1897
|
+
"https://chromium.googlesource.com/libyuv/libyuv",
|
|
1898
|
+
version,
|
|
1899
|
+
libyuv_source_dir,
|
|
1900
|
+
)
|
|
1901
|
+
mkdir_p(libyuv_build_dir)
|
|
1902
|
+
with cd(libyuv_build_dir):
|
|
1903
|
+
cmd(
|
|
1904
|
+
[
|
|
1905
|
+
"cmake",
|
|
1906
|
+
libyuv_source_dir,
|
|
1907
|
+
f"-DCMAKE_INSTALL_PREFIX={cmake_path(libyuv_install_dir)}",
|
|
1908
|
+
f"-DCMAKE_BUILD_TYPE={configuration}",
|
|
1909
|
+
f"-DCMAKE_PREFIX_PATH={cmake_path(libjpeg_turbo_dir)}",
|
|
1910
|
+
*cmake_args,
|
|
1911
|
+
]
|
|
1912
|
+
)
|
|
1913
|
+
cmd(
|
|
1914
|
+
[
|
|
1915
|
+
"cmake",
|
|
1916
|
+
"--build",
|
|
1917
|
+
libyuv_build_dir,
|
|
1918
|
+
f"-j{multiprocessing.cpu_count()}",
|
|
1919
|
+
"--config",
|
|
1920
|
+
"Release",
|
|
1921
|
+
]
|
|
1922
|
+
)
|
|
1923
|
+
cmd(["cmake", "--install", libyuv_build_dir])
|
|
1924
|
+
|
|
1925
|
+
|
|
1926
|
+
@versioned
|
|
1927
|
+
def install_aom(version, source_dir, build_dir, install_dir, configuration, cmake_args):
|
|
1928
|
+
aom_source_dir = os.path.join(source_dir, "aom")
|
|
1929
|
+
aom_build_dir = os.path.join(build_dir, "aom")
|
|
1930
|
+
aom_install_dir = os.path.join(install_dir, "aom")
|
|
1931
|
+
rm_rf(aom_source_dir)
|
|
1932
|
+
rm_rf(aom_build_dir)
|
|
1933
|
+
rm_rf(aom_install_dir)
|
|
1934
|
+
git_clone_shallow(
|
|
1935
|
+
"https://aomedia.googlesource.com/aom",
|
|
1936
|
+
version,
|
|
1937
|
+
aom_source_dir,
|
|
1938
|
+
)
|
|
1939
|
+
with cd(aom_source_dir):
|
|
1940
|
+
cmd(
|
|
1941
|
+
[
|
|
1942
|
+
"cmake",
|
|
1943
|
+
"-B",
|
|
1944
|
+
aom_build_dir,
|
|
1945
|
+
f"-DCMAKE_INSTALL_PREFIX={cmake_path(aom_install_dir)}",
|
|
1946
|
+
f"-DCMAKE_BUILD_TYPE={configuration}",
|
|
1947
|
+
"-DENABLE_DOCS=OFF",
|
|
1948
|
+
"-DENABLE_TESTS=OFF",
|
|
1949
|
+
*cmake_args,
|
|
1950
|
+
]
|
|
1951
|
+
)
|
|
1952
|
+
cmd(
|
|
1953
|
+
[
|
|
1954
|
+
"cmake",
|
|
1955
|
+
"--build",
|
|
1956
|
+
aom_build_dir,
|
|
1957
|
+
f"-j{multiprocessing.cpu_count()}",
|
|
1958
|
+
"--config",
|
|
1959
|
+
"Release",
|
|
1960
|
+
]
|
|
1961
|
+
)
|
|
1962
|
+
cmd(["cmake", "--install", aom_build_dir])
|
|
1963
|
+
|
|
1964
|
+
|
|
1844
1965
|
class PlatformTarget(object):
|
|
1845
1966
|
def __init__(self, os, osver, arch, extra=None):
|
|
1846
1967
|
self.os = os
|
|
@@ -18,17 +18,17 @@ Source = "https://github.com/shiguredo/libdatachannel-py"
|
|
|
18
18
|
Discord = "https://discord.gg/shiguredo"
|
|
19
19
|
|
|
20
20
|
[build-system]
|
|
21
|
-
requires = ["setuptools
|
|
21
|
+
requires = ["setuptools>=80.8", "wheel>=0.45.1"]
|
|
22
22
|
build-backend = "setuptools.build_meta"
|
|
23
23
|
|
|
24
24
|
[dependency-groups]
|
|
25
25
|
dev = [
|
|
26
|
-
"nanobind>=2.7
|
|
27
|
-
"pytest>=8
|
|
28
|
-
"setuptools>=80.
|
|
26
|
+
"nanobind>=2.7",
|
|
27
|
+
"pytest>=8",
|
|
28
|
+
"setuptools>=80.8",
|
|
29
29
|
"build>=1.2.2.post1",
|
|
30
30
|
"wheel>=0.45.1",
|
|
31
|
-
"numpy>=2.2
|
|
31
|
+
"numpy>=2.2",
|
|
32
32
|
]
|
|
33
33
|
|
|
34
34
|
[tool.ruff]
|
|
@@ -16,9 +16,13 @@ from buildbase import (
|
|
|
16
16
|
get_macos_osver,
|
|
17
17
|
get_windows_osver,
|
|
18
18
|
git_clone_shallow,
|
|
19
|
+
install_aom,
|
|
19
20
|
install_cmake,
|
|
21
|
+
install_libjpeg_turbo,
|
|
22
|
+
install_libyuv,
|
|
20
23
|
install_mbedtls,
|
|
21
24
|
install_openh264,
|
|
25
|
+
install_opus,
|
|
22
26
|
mkdir_p,
|
|
23
27
|
read_version_file,
|
|
24
28
|
)
|
|
@@ -115,6 +119,55 @@ def install_deps(
|
|
|
115
119
|
}
|
|
116
120
|
install_openh264(**install_openh264_args)
|
|
117
121
|
|
|
122
|
+
# Opus
|
|
123
|
+
install_opus_args = {
|
|
124
|
+
"version": version["OPUS_VERSION"],
|
|
125
|
+
"version_file": os.path.join(install_dir, "opus.version"),
|
|
126
|
+
"source_dir": source_dir,
|
|
127
|
+
"build_dir": build_dir,
|
|
128
|
+
"install_dir": install_dir,
|
|
129
|
+
"configuration": "Debug" if debug else "Release",
|
|
130
|
+
"cmake_args": macos_cmake_args,
|
|
131
|
+
}
|
|
132
|
+
install_opus(**install_opus_args)
|
|
133
|
+
|
|
134
|
+
# libjpeg-turbo
|
|
135
|
+
install_libjpeg_turbo_args = {
|
|
136
|
+
"version": version["LIBJPEG_TURBO_VERSION"],
|
|
137
|
+
"version_file": os.path.join(install_dir, "libjpeg-turbo.version"),
|
|
138
|
+
"source_dir": source_dir,
|
|
139
|
+
"build_dir": build_dir,
|
|
140
|
+
"install_dir": install_dir,
|
|
141
|
+
"configuration": "Debug" if debug else "Release",
|
|
142
|
+
"cmake_args": macos_cmake_args,
|
|
143
|
+
}
|
|
144
|
+
install_libjpeg_turbo(**install_libjpeg_turbo_args)
|
|
145
|
+
|
|
146
|
+
# libyuv
|
|
147
|
+
install_libyuv_args = {
|
|
148
|
+
"version": version["LIBYUV_VERSION"],
|
|
149
|
+
"version_file": os.path.join(install_dir, "libyuv.version"),
|
|
150
|
+
"source_dir": source_dir,
|
|
151
|
+
"build_dir": build_dir,
|
|
152
|
+
"install_dir": install_dir,
|
|
153
|
+
"libjpeg_turbo_dir": os.path.join(install_dir, "libjpeg-turbo"),
|
|
154
|
+
"configuration": "Debug" if debug else "Release",
|
|
155
|
+
"cmake_args": macos_cmake_args,
|
|
156
|
+
}
|
|
157
|
+
install_libyuv(**install_libyuv_args)
|
|
158
|
+
|
|
159
|
+
# AOM
|
|
160
|
+
install_aom_args = {
|
|
161
|
+
"version": version["AOM_VERSION"],
|
|
162
|
+
"version_file": os.path.join(install_dir, "aom.version"),
|
|
163
|
+
"source_dir": source_dir,
|
|
164
|
+
"build_dir": build_dir,
|
|
165
|
+
"install_dir": install_dir,
|
|
166
|
+
"configuration": "Debug" if debug else "Release",
|
|
167
|
+
"cmake_args": macos_cmake_args,
|
|
168
|
+
}
|
|
169
|
+
install_aom(**install_aom_args)
|
|
170
|
+
|
|
118
171
|
|
|
119
172
|
AVAILABLE_TARGETS = [
|
|
120
173
|
"windows_x86_64",
|
|
@@ -199,6 +252,18 @@ def main():
|
|
|
199
252
|
# OpenH264
|
|
200
253
|
cmake_args.append(f"-DOPENH264_DIR={cmake_path(os.path.join(install_dir, 'openh264'))}")
|
|
201
254
|
|
|
255
|
+
# Opus
|
|
256
|
+
cmake_args.append(f"-DOPUS_DIR={cmake_path(os.path.join(install_dir, 'opus'))}")
|
|
257
|
+
|
|
258
|
+
# Libyuv
|
|
259
|
+
cmake_args.append(
|
|
260
|
+
f"-DLIBJPEG_TURBO_DIR={cmake_path(os.path.join(install_dir, 'libjpeg-turbo'))}"
|
|
261
|
+
)
|
|
262
|
+
cmake_args.append(f"-DLIBYUV_DIR={cmake_path(os.path.join(install_dir, 'libyuv'))}")
|
|
263
|
+
|
|
264
|
+
# AOM
|
|
265
|
+
cmake_args.append(f"-DAOM_DIR={cmake_path(os.path.join(install_dir, 'aom'))}")
|
|
266
|
+
|
|
202
267
|
if platform.target.os == "macos":
|
|
203
268
|
sysroot = cmdcap(["xcrun", "--sdk", "macosx", "--show-sdk-path"])
|
|
204
269
|
cmake_args += [
|
|
@@ -261,6 +326,20 @@ def main():
|
|
|
261
326
|
os.path.join(libdatachannelpy_src_dir, file),
|
|
262
327
|
)
|
|
263
328
|
|
|
329
|
+
for file in os.listdir(os.path.join(libdatachannelpy_build_target_dir, "libyuv")):
|
|
330
|
+
if file in ("__init__.pyi",):
|
|
331
|
+
shutil.copyfile(
|
|
332
|
+
os.path.join(libdatachannelpy_build_target_dir, "libyuv", file),
|
|
333
|
+
os.path.join(libdatachannelpy_src_dir, "libyuv", file),
|
|
334
|
+
)
|
|
335
|
+
|
|
336
|
+
for file in os.listdir(os.path.join(libdatachannelpy_build_target_dir, "codec")):
|
|
337
|
+
if file in ("__init__.pyi",):
|
|
338
|
+
shutil.copyfile(
|
|
339
|
+
os.path.join(libdatachannelpy_build_target_dir, "codec", file),
|
|
340
|
+
os.path.join(libdatachannelpy_src_dir, "codec", file),
|
|
341
|
+
)
|
|
342
|
+
|
|
264
343
|
|
|
265
344
|
if __name__ == "__main__":
|
|
266
345
|
main()
|
|
Binary file
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
from collections.abc import Callable, Sequence
|
|
2
2
|
import datetime
|
|
3
3
|
import enum
|
|
4
|
-
from typing import
|
|
4
|
+
from typing import overload
|
|
5
5
|
|
|
6
|
-
from
|
|
6
|
+
from . import codec as codec, libyuv as libyuv
|
|
7
7
|
|
|
8
8
|
|
|
9
9
|
class IceServer:
|
|
@@ -1667,211 +1667,3 @@ class WebSocketServer:
|
|
|
1667
1667
|
def port(self) -> int: ...
|
|
1668
1668
|
|
|
1669
1669
|
def on_client(self, callback: Callable[[WebSocket], None]) -> None: ...
|
|
1670
|
-
|
|
1671
|
-
class VideoCodecType(enum.Enum):
|
|
1672
|
-
H264 = 0
|
|
1673
|
-
|
|
1674
|
-
H265 = 1
|
|
1675
|
-
|
|
1676
|
-
VP8 = 2
|
|
1677
|
-
|
|
1678
|
-
VP9 = 3
|
|
1679
|
-
|
|
1680
|
-
AV1 = 4
|
|
1681
|
-
|
|
1682
|
-
class ImageFormat(enum.Enum):
|
|
1683
|
-
I420 = 0
|
|
1684
|
-
|
|
1685
|
-
NV12 = 1
|
|
1686
|
-
|
|
1687
|
-
BGR888 = 2
|
|
1688
|
-
|
|
1689
|
-
class VideoFrameBufferI420:
|
|
1690
|
-
@staticmethod
|
|
1691
|
-
def create(arg0: int, arg1: int, /) -> VideoFrameBufferI420: ...
|
|
1692
|
-
|
|
1693
|
-
@property
|
|
1694
|
-
def y(self) -> Annotated[ArrayLike, dict(dtype='uint8', shape=(None, None), order='C')]: ...
|
|
1695
|
-
|
|
1696
|
-
@y.setter
|
|
1697
|
-
def y(self, arg: Annotated[ArrayLike, dict(dtype='uint8', shape=(None, None), order='C')], /) -> None: ...
|
|
1698
|
-
|
|
1699
|
-
@property
|
|
1700
|
-
def u(self) -> Annotated[ArrayLike, dict(dtype='uint8', shape=(None, None), order='C')]: ...
|
|
1701
|
-
|
|
1702
|
-
@u.setter
|
|
1703
|
-
def u(self, arg: Annotated[ArrayLike, dict(dtype='uint8', shape=(None, None), order='C')], /) -> None: ...
|
|
1704
|
-
|
|
1705
|
-
@property
|
|
1706
|
-
def v(self) -> Annotated[ArrayLike, dict(dtype='uint8', shape=(None, None), order='C')]: ...
|
|
1707
|
-
|
|
1708
|
-
@v.setter
|
|
1709
|
-
def v(self, arg: Annotated[ArrayLike, dict(dtype='uint8', shape=(None, None), order='C')], /) -> None: ...
|
|
1710
|
-
|
|
1711
|
-
def width(self) -> int: ...
|
|
1712
|
-
|
|
1713
|
-
def height(self) -> int: ...
|
|
1714
|
-
|
|
1715
|
-
def stride_y(self) -> int: ...
|
|
1716
|
-
|
|
1717
|
-
def stride_u(self) -> int: ...
|
|
1718
|
-
|
|
1719
|
-
def stride_v(self) -> int: ...
|
|
1720
|
-
|
|
1721
|
-
class VideoFrameBufferNV12:
|
|
1722
|
-
@staticmethod
|
|
1723
|
-
def create(arg0: int, arg1: int, /) -> VideoFrameBufferNV12: ...
|
|
1724
|
-
|
|
1725
|
-
@property
|
|
1726
|
-
def y(self) -> Annotated[ArrayLike, dict(dtype='uint8', shape=(None, None), order='C')]: ...
|
|
1727
|
-
|
|
1728
|
-
@y.setter
|
|
1729
|
-
def y(self, arg: Annotated[ArrayLike, dict(dtype='uint8', shape=(None, None), order='C')], /) -> None: ...
|
|
1730
|
-
|
|
1731
|
-
@property
|
|
1732
|
-
def uv(self) -> Annotated[ArrayLike, dict(dtype='uint8', shape=(None, None), order='C')]: ...
|
|
1733
|
-
|
|
1734
|
-
@uv.setter
|
|
1735
|
-
def uv(self, arg: Annotated[ArrayLike, dict(dtype='uint8', shape=(None, None), order='C')], /) -> None: ...
|
|
1736
|
-
|
|
1737
|
-
def width(self) -> int: ...
|
|
1738
|
-
|
|
1739
|
-
def height(self) -> int: ...
|
|
1740
|
-
|
|
1741
|
-
def stride_y(self) -> int: ...
|
|
1742
|
-
|
|
1743
|
-
def stride_uv(self) -> int: ...
|
|
1744
|
-
|
|
1745
|
-
class VideoFrameBufferBGR888:
|
|
1746
|
-
@staticmethod
|
|
1747
|
-
def create(arg0: int, arg1: int, /) -> VideoFrameBufferBGR888: ...
|
|
1748
|
-
|
|
1749
|
-
@property
|
|
1750
|
-
def bgr(self) -> Annotated[ArrayLike, dict(dtype='uint8', shape=(None, None, 3), order='C')]: ...
|
|
1751
|
-
|
|
1752
|
-
@bgr.setter
|
|
1753
|
-
def bgr(self, arg: Annotated[ArrayLike, dict(dtype='uint8', shape=(None, None, 3), order='C')], /) -> None: ...
|
|
1754
|
-
|
|
1755
|
-
def width(self) -> int: ...
|
|
1756
|
-
|
|
1757
|
-
def height(self) -> int: ...
|
|
1758
|
-
|
|
1759
|
-
def stride(self) -> int: ...
|
|
1760
|
-
|
|
1761
|
-
class VideoFrame:
|
|
1762
|
-
def __init__(self) -> None: ...
|
|
1763
|
-
|
|
1764
|
-
@property
|
|
1765
|
-
def format(self) -> ImageFormat: ...
|
|
1766
|
-
|
|
1767
|
-
@format.setter
|
|
1768
|
-
def format(self, arg: ImageFormat, /) -> None: ...
|
|
1769
|
-
|
|
1770
|
-
@property
|
|
1771
|
-
def i420_buffer(self) -> VideoFrameBufferI420: ...
|
|
1772
|
-
|
|
1773
|
-
@i420_buffer.setter
|
|
1774
|
-
def i420_buffer(self, arg: VideoFrameBufferI420, /) -> None: ...
|
|
1775
|
-
|
|
1776
|
-
@property
|
|
1777
|
-
def nv12_buffer(self) -> VideoFrameBufferNV12: ...
|
|
1778
|
-
|
|
1779
|
-
@nv12_buffer.setter
|
|
1780
|
-
def nv12_buffer(self, arg: VideoFrameBufferNV12, /) -> None: ...
|
|
1781
|
-
|
|
1782
|
-
@property
|
|
1783
|
-
def bgr888_buffer(self) -> VideoFrameBufferBGR888: ...
|
|
1784
|
-
|
|
1785
|
-
@bgr888_buffer.setter
|
|
1786
|
-
def bgr888_buffer(self, arg: VideoFrameBufferBGR888, /) -> None: ...
|
|
1787
|
-
|
|
1788
|
-
@property
|
|
1789
|
-
def timestamp(self) -> datetime.timedelta: ...
|
|
1790
|
-
|
|
1791
|
-
@timestamp.setter
|
|
1792
|
-
def timestamp(self, arg: datetime.timedelta | float, /) -> None: ...
|
|
1793
|
-
|
|
1794
|
-
@property
|
|
1795
|
-
def rid(self) -> str | None: ...
|
|
1796
|
-
|
|
1797
|
-
@rid.setter
|
|
1798
|
-
def rid(self, arg: str, /) -> None: ...
|
|
1799
|
-
|
|
1800
|
-
@property
|
|
1801
|
-
def base_width(self) -> int: ...
|
|
1802
|
-
|
|
1803
|
-
@base_width.setter
|
|
1804
|
-
def base_width(self, arg: int, /) -> None: ...
|
|
1805
|
-
|
|
1806
|
-
@property
|
|
1807
|
-
def base_height(self) -> int: ...
|
|
1808
|
-
|
|
1809
|
-
@base_height.setter
|
|
1810
|
-
def base_height(self, arg: int, /) -> None: ...
|
|
1811
|
-
|
|
1812
|
-
def width(self) -> int: ...
|
|
1813
|
-
|
|
1814
|
-
def height(self) -> int: ...
|
|
1815
|
-
|
|
1816
|
-
class EncodedImage:
|
|
1817
|
-
def __init__(self) -> None: ...
|
|
1818
|
-
|
|
1819
|
-
@property
|
|
1820
|
-
def data(self) -> Annotated[ArrayLike, dict(dtype='uint8', shape=(None), order='C')]: ...
|
|
1821
|
-
|
|
1822
|
-
@data.setter
|
|
1823
|
-
def data(self, arg: Annotated[ArrayLike, dict(dtype='uint8', shape=(None), order='C')], /) -> None: ...
|
|
1824
|
-
|
|
1825
|
-
@property
|
|
1826
|
-
def timestamp(self) -> datetime.timedelta: ...
|
|
1827
|
-
|
|
1828
|
-
@timestamp.setter
|
|
1829
|
-
def timestamp(self, arg: datetime.timedelta | float, /) -> None: ...
|
|
1830
|
-
|
|
1831
|
-
@property
|
|
1832
|
-
def rid(self) -> str | None: ...
|
|
1833
|
-
|
|
1834
|
-
@rid.setter
|
|
1835
|
-
def rid(self, arg: str, /) -> None: ...
|
|
1836
|
-
|
|
1837
|
-
class VideoEncoder:
|
|
1838
|
-
def init(self, arg: VideoEncoder.Settings, /) -> bool: ...
|
|
1839
|
-
|
|
1840
|
-
def release(self) -> None: ...
|
|
1841
|
-
|
|
1842
|
-
def encode(self, arg: VideoFrame, /) -> None: ...
|
|
1843
|
-
|
|
1844
|
-
def force_intra_next_frame(self) -> None: ...
|
|
1845
|
-
|
|
1846
|
-
def set_on_encoded(self, arg: Callable[[EncodedImage], None], /) -> None: ...
|
|
1847
|
-
|
|
1848
|
-
class Settings:
|
|
1849
|
-
def __init__(self) -> None: ...
|
|
1850
|
-
|
|
1851
|
-
@property
|
|
1852
|
-
def codec_type(self) -> VideoCodecType: ...
|
|
1853
|
-
|
|
1854
|
-
@codec_type.setter
|
|
1855
|
-
def codec_type(self, arg: VideoCodecType, /) -> None: ...
|
|
1856
|
-
|
|
1857
|
-
@property
|
|
1858
|
-
def width(self) -> int: ...
|
|
1859
|
-
|
|
1860
|
-
@width.setter
|
|
1861
|
-
def width(self, arg: int, /) -> None: ...
|
|
1862
|
-
|
|
1863
|
-
@property
|
|
1864
|
-
def height(self) -> int: ...
|
|
1865
|
-
|
|
1866
|
-
@height.setter
|
|
1867
|
-
def height(self, arg: int, /) -> None: ...
|
|
1868
|
-
|
|
1869
|
-
@property
|
|
1870
|
-
def bitrate(self) -> int: ...
|
|
1871
|
-
|
|
1872
|
-
@bitrate.setter
|
|
1873
|
-
def bitrate(self, arg: int, /) -> None: ...
|
|
1874
|
-
|
|
1875
|
-
def create_openh264_video_encoder(openh264: str) -> VideoEncoder: ...
|
|
1876
|
-
|
|
1877
|
-
def create_videotoolbox_video_encoder() -> VideoEncoder: ...
|
|
@@ -15,11 +15,13 @@ src/libdatachannel_py.egg-info/PKG-INFO
|
|
|
15
15
|
src/libdatachannel_py.egg-info/SOURCES.txt
|
|
16
16
|
src/libdatachannel_py.egg-info/dependency_links.txt
|
|
17
17
|
src/libdatachannel_py.egg-info/top_level.txt
|
|
18
|
+
tests/test_audio_codec.py
|
|
18
19
|
tests/test_candidate.py
|
|
19
20
|
tests/test_configuration.py
|
|
20
21
|
tests/test_description.py
|
|
21
22
|
tests/test_frameinfo.py
|
|
22
23
|
tests/test_h265nalunit.py
|
|
24
|
+
tests/test_libyuv.py
|
|
23
25
|
tests/test_mediahandler.py
|
|
24
26
|
tests/test_message.py
|
|
25
27
|
tests/test_nalunit.py
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
from datetime import timedelta
|
|
2
|
+
|
|
3
|
+
import numpy as np
|
|
4
|
+
|
|
5
|
+
from libdatachannel.codec import (
|
|
6
|
+
AudioCodecType,
|
|
7
|
+
AudioEncoder,
|
|
8
|
+
AudioFrame,
|
|
9
|
+
EncodedAudio,
|
|
10
|
+
create_opus_audio_encoder,
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_audio_encoder_encode():
|
|
15
|
+
encoder = create_opus_audio_encoder()
|
|
16
|
+
|
|
17
|
+
settings = AudioEncoder.Settings()
|
|
18
|
+
settings.codec_type = AudioCodecType.OPUS
|
|
19
|
+
settings.sample_rate = 48000
|
|
20
|
+
settings.channels = 2
|
|
21
|
+
settings.bitrate = 64000
|
|
22
|
+
settings.frame_duration_ms = 20
|
|
23
|
+
|
|
24
|
+
assert encoder.init(settings) is True
|
|
25
|
+
|
|
26
|
+
callback_timestamps = []
|
|
27
|
+
|
|
28
|
+
def on_encoded(encoded: EncodedAudio):
|
|
29
|
+
assert isinstance(encoded.data, np.ndarray)
|
|
30
|
+
callback_timestamps.append(encoded.timestamp)
|
|
31
|
+
|
|
32
|
+
encoder.set_on_encode(on_encoded)
|
|
33
|
+
|
|
34
|
+
frame = AudioFrame()
|
|
35
|
+
frame.sample_rate = 48000
|
|
36
|
+
frame.timestamp = timedelta(milliseconds=1000)
|
|
37
|
+
# 48000 Hz * 20 ms = 960 samples
|
|
38
|
+
frame.pcm = np.zeros((960, 2), dtype=np.float32)
|
|
39
|
+
|
|
40
|
+
encoder.encode(frame)
|
|
41
|
+
|
|
42
|
+
assert callback_timestamps == [timedelta(milliseconds=1000)]
|
|
43
|
+
|
|
44
|
+
# 10ms → 20ms でエンコード
|
|
45
|
+
frame = AudioFrame()
|
|
46
|
+
frame.sample_rate = 48000
|
|
47
|
+
frame.timestamp = timedelta(milliseconds=1000)
|
|
48
|
+
frame.pcm = np.zeros((480, 2), dtype=np.float32)
|
|
49
|
+
|
|
50
|
+
encoder.encode(frame)
|
|
51
|
+
|
|
52
|
+
frame.timestamp = timedelta(milliseconds=1100) # わざと大きくずらす
|
|
53
|
+
frame.pcm = np.zeros((960, 2), dtype=np.float32)
|
|
54
|
+
|
|
55
|
+
encoder.encode(frame)
|
|
56
|
+
|
|
57
|
+
# 既存のフレームが 10ms あって、1100 だったので 1100 - 10 の 1090 になるはず
|
|
58
|
+
assert callback_timestamps == [timedelta(milliseconds=1000), timedelta(milliseconds=1090)]
|
|
59
|
+
|
|
60
|
+
# 10ms のデータを渡すと追加でエンコードされるはず
|
|
61
|
+
frame.timestamp = timedelta(milliseconds=1120)
|
|
62
|
+
frame.pcm = np.zeros((480, 2), dtype=np.float32)
|
|
63
|
+
|
|
64
|
+
encoder.encode(frame)
|
|
65
|
+
|
|
66
|
+
assert callback_timestamps == [
|
|
67
|
+
timedelta(milliseconds=1000),
|
|
68
|
+
timedelta(milliseconds=1090),
|
|
69
|
+
timedelta(milliseconds=1110),
|
|
70
|
+
]
|
|
71
|
+
|
|
72
|
+
encoder.release()
|
|
@@ -0,0 +1,200 @@
|
|
|
1
|
+
import numpy as np
|
|
2
|
+
|
|
3
|
+
from libdatachannel.codec import VideoFrameBufferBGR888, VideoFrameBufferI420, VideoFrameBufferNV12
|
|
4
|
+
from libdatachannel.libyuv import (
|
|
5
|
+
FilterMode,
|
|
6
|
+
FourCC,
|
|
7
|
+
RotationMode,
|
|
8
|
+
convert_to_i420,
|
|
9
|
+
i420_scale,
|
|
10
|
+
i420_to_nv12,
|
|
11
|
+
i420_to_rgb24,
|
|
12
|
+
nv12_scale,
|
|
13
|
+
nv12_to_i420,
|
|
14
|
+
rgb24_to_i420,
|
|
15
|
+
)
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def test_libyuv_nv12_scale():
|
|
19
|
+
src_width, src_height = 640, 480
|
|
20
|
+
src = VideoFrameBufferNV12.create(src_width, src_height)
|
|
21
|
+
# type: ignore しないと型エラーになる
|
|
22
|
+
# 参考: https://github.com/wjakob/nanobind/pull/442
|
|
23
|
+
src.y[:, :] = 42 # type: ignore
|
|
24
|
+
|
|
25
|
+
dst_width, dst_height = 320, 240
|
|
26
|
+
dst = VideoFrameBufferNV12.create(dst_width, dst_height)
|
|
27
|
+
r = nv12_scale(
|
|
28
|
+
src.y,
|
|
29
|
+
src.uv,
|
|
30
|
+
src.stride_y(),
|
|
31
|
+
src.stride_uv(),
|
|
32
|
+
src.width(),
|
|
33
|
+
src.height(),
|
|
34
|
+
dst.y,
|
|
35
|
+
dst.uv,
|
|
36
|
+
dst.stride_y(),
|
|
37
|
+
dst.stride_uv(),
|
|
38
|
+
dst.width(),
|
|
39
|
+
dst.height(),
|
|
40
|
+
FilterMode.NONE,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
assert r == 0
|
|
44
|
+
assert np.all(dst.y == 42)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
def test_libyuv_i420_scale():
|
|
48
|
+
src_width, src_height = 640, 480
|
|
49
|
+
src = VideoFrameBufferI420.create(src_width, src_height)
|
|
50
|
+
src.y[:, :] = 42 # type: ignore
|
|
51
|
+
|
|
52
|
+
dst_width, dst_height = 320, 240
|
|
53
|
+
dst = VideoFrameBufferI420.create(dst_width, dst_height)
|
|
54
|
+
r = i420_scale(
|
|
55
|
+
src.y,
|
|
56
|
+
src.u,
|
|
57
|
+
src.v,
|
|
58
|
+
src.stride_y(),
|
|
59
|
+
src.stride_u(),
|
|
60
|
+
src.stride_v(),
|
|
61
|
+
src.width(),
|
|
62
|
+
src.height(),
|
|
63
|
+
dst.y,
|
|
64
|
+
dst.u,
|
|
65
|
+
dst.v,
|
|
66
|
+
dst.stride_y(),
|
|
67
|
+
dst.stride_u(),
|
|
68
|
+
dst.stride_v(),
|
|
69
|
+
dst.width(),
|
|
70
|
+
dst.height(),
|
|
71
|
+
FilterMode.NONE,
|
|
72
|
+
)
|
|
73
|
+
assert r == 0
|
|
74
|
+
assert np.all(dst.y == 42)
|
|
75
|
+
|
|
76
|
+
|
|
77
|
+
def test_libyuv_convert_to_i420():
|
|
78
|
+
nv12 = np.full((640, 480 + 480 // 2), 42, dtype=np.uint8)
|
|
79
|
+
|
|
80
|
+
dst = VideoFrameBufferI420.create(640, 480)
|
|
81
|
+
r = convert_to_i420(
|
|
82
|
+
nv12,
|
|
83
|
+
nv12.size,
|
|
84
|
+
dst.y,
|
|
85
|
+
dst.stride_y(),
|
|
86
|
+
dst.u,
|
|
87
|
+
dst.stride_u(),
|
|
88
|
+
dst.v,
|
|
89
|
+
dst.stride_v(),
|
|
90
|
+
0,
|
|
91
|
+
0,
|
|
92
|
+
640,
|
|
93
|
+
480,
|
|
94
|
+
640,
|
|
95
|
+
480,
|
|
96
|
+
RotationMode.Rotate0,
|
|
97
|
+
FourCC.NV12,
|
|
98
|
+
)
|
|
99
|
+
assert r == 0
|
|
100
|
+
assert np.all(dst.y == 42)
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def test_libyuv_nv12_to_i420():
|
|
104
|
+
src = VideoFrameBufferNV12.create(640, 480)
|
|
105
|
+
src.y[:, :] = 42 # type: ignore
|
|
106
|
+
src.uv[:, :] = 128 # type: ignore
|
|
107
|
+
|
|
108
|
+
dst = VideoFrameBufferI420.create(640, 480)
|
|
109
|
+
r = nv12_to_i420(
|
|
110
|
+
src.y,
|
|
111
|
+
src.uv,
|
|
112
|
+
src.stride_y(),
|
|
113
|
+
src.stride_uv(),
|
|
114
|
+
dst.y,
|
|
115
|
+
dst.u,
|
|
116
|
+
dst.v,
|
|
117
|
+
dst.stride_y(),
|
|
118
|
+
dst.stride_u(),
|
|
119
|
+
dst.stride_v(),
|
|
120
|
+
src.width(),
|
|
121
|
+
src.height(),
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
assert r == 0
|
|
125
|
+
assert np.all(dst.y == 42)
|
|
126
|
+
assert np.all(dst.u == 128)
|
|
127
|
+
assert np.all(dst.v == 128)
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def test_libyuv_i420_to_nv12():
|
|
131
|
+
src = VideoFrameBufferI420.create(640, 480)
|
|
132
|
+
src.y[:, :] = 42 # type: ignore
|
|
133
|
+
src.u[:, :] = 128 # type: ignore
|
|
134
|
+
src.v[:, :] = 128 # type: ignore
|
|
135
|
+
|
|
136
|
+
dst = VideoFrameBufferNV12.create(640, 480)
|
|
137
|
+
r = i420_to_nv12(
|
|
138
|
+
src.y,
|
|
139
|
+
src.u,
|
|
140
|
+
src.v,
|
|
141
|
+
src.stride_y(),
|
|
142
|
+
src.stride_u(),
|
|
143
|
+
src.stride_v(),
|
|
144
|
+
dst.y,
|
|
145
|
+
dst.uv,
|
|
146
|
+
dst.stride_y(),
|
|
147
|
+
dst.stride_uv(),
|
|
148
|
+
src.width(),
|
|
149
|
+
src.height(),
|
|
150
|
+
)
|
|
151
|
+
|
|
152
|
+
assert r == 0
|
|
153
|
+
assert np.all(dst.y == 42)
|
|
154
|
+
assert np.all(dst.uv == 128)
|
|
155
|
+
|
|
156
|
+
|
|
157
|
+
def test_libyuv_rgb24_to_i420():
|
|
158
|
+
src = VideoFrameBufferBGR888.create(640, 480)
|
|
159
|
+
src.bgr[:, :, :] = 42 # type: ignore
|
|
160
|
+
|
|
161
|
+
dst = VideoFrameBufferI420.create(640, 480)
|
|
162
|
+
r = rgb24_to_i420(
|
|
163
|
+
src.bgr,
|
|
164
|
+
src.stride(),
|
|
165
|
+
dst.y,
|
|
166
|
+
dst.u,
|
|
167
|
+
dst.v,
|
|
168
|
+
dst.stride_y(),
|
|
169
|
+
dst.stride_u(),
|
|
170
|
+
dst.stride_v(),
|
|
171
|
+
src.width(),
|
|
172
|
+
src.height(),
|
|
173
|
+
)
|
|
174
|
+
|
|
175
|
+
assert r == 0
|
|
176
|
+
assert np.all(dst.y == 52)
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
def test_libyuv_i420_to_rgb24():
|
|
180
|
+
src = VideoFrameBufferI420.create(640, 480)
|
|
181
|
+
src.y[:, :] = 42 # type: ignore
|
|
182
|
+
src.u[:, :] = 128 # type: ignore
|
|
183
|
+
src.v[:, :] = 128 # type: ignore
|
|
184
|
+
|
|
185
|
+
dst = VideoFrameBufferBGR888.create(640, 480)
|
|
186
|
+
r = i420_to_rgb24(
|
|
187
|
+
src.y,
|
|
188
|
+
src.u,
|
|
189
|
+
src.v,
|
|
190
|
+
src.stride_y(),
|
|
191
|
+
src.stride_u(),
|
|
192
|
+
src.stride_v(),
|
|
193
|
+
dst.bgr,
|
|
194
|
+
dst.stride(),
|
|
195
|
+
src.width(),
|
|
196
|
+
src.height(),
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
assert r == 0
|
|
200
|
+
assert np.all(dst.bgr == np.array([30, 30, 30], dtype=np.uint8))
|
{libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/tests/test_video_codec.py
RENAMED
|
@@ -5,7 +5,7 @@ from datetime import timedelta
|
|
|
5
5
|
import numpy as np
|
|
6
6
|
import pytest
|
|
7
7
|
|
|
8
|
-
from libdatachannel import (
|
|
8
|
+
from libdatachannel.codec import (
|
|
9
9
|
EncodedImage,
|
|
10
10
|
ImageFormat,
|
|
11
11
|
VideoCodecType,
|
|
@@ -14,6 +14,7 @@ from libdatachannel import (
|
|
|
14
14
|
VideoFrameBufferBGR888,
|
|
15
15
|
VideoFrameBufferI420,
|
|
16
16
|
VideoFrameBufferNV12,
|
|
17
|
+
create_aom_video_encoder,
|
|
17
18
|
create_openh264_video_encoder,
|
|
18
19
|
create_videotoolbox_video_encoder,
|
|
19
20
|
)
|
|
@@ -120,19 +121,19 @@ def test_openh264():
|
|
|
120
121
|
frame.base_height = 480
|
|
121
122
|
frame.timestamp = timedelta(microseconds=1234567)
|
|
122
123
|
|
|
123
|
-
|
|
124
|
+
on_encode_called = False
|
|
124
125
|
|
|
125
|
-
def
|
|
126
|
-
nonlocal
|
|
126
|
+
def on_encode(encoded_image):
|
|
127
|
+
nonlocal on_encode_called
|
|
127
128
|
assert encoded_image.data.size > 0
|
|
128
129
|
assert encoded_image.timestamp == frame.timestamp
|
|
129
130
|
assert encoded_image.rid == frame.rid
|
|
130
|
-
|
|
131
|
+
on_encode_called = True
|
|
131
132
|
|
|
132
|
-
encoder.
|
|
133
|
+
encoder.set_on_encode(on_encode)
|
|
133
134
|
encoder.encode(frame)
|
|
134
135
|
encoder.release()
|
|
135
|
-
assert
|
|
136
|
+
assert on_encode_called
|
|
136
137
|
|
|
137
138
|
|
|
138
139
|
@pytest.mark.skipif(
|
|
@@ -154,17 +155,48 @@ def test_videotoolbox():
|
|
|
154
155
|
frame.base_height = 480
|
|
155
156
|
frame.timestamp = timedelta(microseconds=1234567)
|
|
156
157
|
|
|
157
|
-
|
|
158
|
+
on_encode_called = False
|
|
158
159
|
|
|
159
|
-
def
|
|
160
|
-
nonlocal
|
|
160
|
+
def on_encode(encoded_image):
|
|
161
|
+
nonlocal on_encode_called
|
|
161
162
|
assert encoded_image.data.size > 0
|
|
162
163
|
assert encoded_image.timestamp == frame.timestamp
|
|
163
164
|
assert encoded_image.rid == frame.rid
|
|
164
|
-
|
|
165
|
+
on_encode_called = True
|
|
165
166
|
|
|
166
|
-
encoder.
|
|
167
|
+
encoder.set_on_encode(on_encode)
|
|
167
168
|
encoder.encode(frame)
|
|
168
169
|
time.sleep(1)
|
|
169
170
|
encoder.release()
|
|
170
|
-
assert
|
|
171
|
+
assert on_encode_called
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
def test_aom():
|
|
175
|
+
encoder = create_aom_video_encoder()
|
|
176
|
+
settings = VideoEncoder.Settings()
|
|
177
|
+
settings.codec_type = VideoCodecType.H264
|
|
178
|
+
settings.width = 640
|
|
179
|
+
settings.height = 480
|
|
180
|
+
settings.bitrate = 1000000
|
|
181
|
+
success = encoder.init(settings)
|
|
182
|
+
assert success
|
|
183
|
+
frame = VideoFrame()
|
|
184
|
+
frame.i420_buffer = VideoFrameBufferI420.create(640, 360)
|
|
185
|
+
frame.format = ImageFormat.I420
|
|
186
|
+
frame.base_width = 640
|
|
187
|
+
frame.base_height = 480
|
|
188
|
+
frame.timestamp = timedelta(microseconds=1234567)
|
|
189
|
+
|
|
190
|
+
on_encode_called = False
|
|
191
|
+
|
|
192
|
+
def on_encode(encoded_image):
|
|
193
|
+
nonlocal on_encode_called
|
|
194
|
+
assert encoded_image.data.size > 0
|
|
195
|
+
assert encoded_image.timestamp == frame.timestamp
|
|
196
|
+
assert encoded_image.rid == frame.rid
|
|
197
|
+
on_encode_called = True
|
|
198
|
+
|
|
199
|
+
encoder.set_on_encode(on_encode)
|
|
200
|
+
encoder.encode(frame)
|
|
201
|
+
encoder.release()
|
|
202
|
+
assert on_encode_called
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
2025.1.0.dev6
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/src/libdatachannel/__init__.py
RENAMED
|
File without changes
|
{libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/src/libdatachannel/py.typed
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/tests/test_configuration.py
RENAMED
|
File without changes
|
{libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/tests/test_description.py
RENAMED
|
File without changes
|
|
File without changes
|
{libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/tests/test_h265nalunit.py
RENAMED
|
File without changes
|
{libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/tests/test_mediahandler.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/tests/test_peerconnection.py
RENAMED
|
File without changes
|
{libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/tests/test_reliability.py
RENAMED
|
File without changes
|
{libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/tests/test_rtppacketizer.py
RENAMED
|
File without changes
|
|
File without changes
|
{libdatachannel_py-2025.1.0.dev6 → libdatachannel_py-2025.1.0.dev8}/tests/test_websocketserver.py
RENAMED
|
File without changes
|