Compare commits
10 Commits
master
...
on_rejecte
Author | SHA1 | Date |
---|---|---|
Riza Sulistyo | 70a3e2e1a4 | |
Riza Sulistyo | eb77f1f7dc | |
Riza Sulistyo | f7e28fcc2a | |
Riza Sulistyo | c2ff1540c3 | |
Riza Sulistyo | b4565c3374 | |
Riza Sulistyo | e74e036ae5 | |
Riza Sulistyo | c8bde05f9b | |
Riza Sulistyo | dc723740db | |
Riza Sulistyo | c780fe7cb2 | |
Riza Sulistyo | 2fa315e321 |
|
@ -23,21 +23,21 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: install dependencies
|
||||
run: brew install openssl opencore-amr swig sipp
|
||||
run: brew install openssl@1.1 opencore-amr swig sipp
|
||||
- name: config site
|
||||
run: cd pjlib/include/pj && cp config_site_test.h config_site.h
|
||||
- name: configure
|
||||
run: CFLAGS="-g $(pkg-config --cflags openssl) $(pkg-config --cflags opencore-amrnb) -fPIC" LDFLAGS="$(pkg-config --libs-only-L openssl) $(pkg-config --libs-only-L openssl)/lib $(pkg-config --libs-only-L opencore-amrnb)" CXXFLAGS="-g -fPIC" ./configure
|
||||
run: CFLAGS="-g -I/usr/local/include -I/usr/local/opt/openssl@1.1/include -fPIC" LDFLAGS="-L/usr/local/lib -L/usr/local/opt/openssl@1.1/lib" CXXFLAGS="-g -fPIC" ./configure
|
||||
- name: make
|
||||
run: make
|
||||
- name: set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10'
|
||||
- name: swig bindings
|
||||
run: cd pjsip-apps/src/swig && make
|
||||
- name: disable firewall
|
||||
run: sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate off
|
||||
- name: set up Python 3.10 for pjsua test
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10'
|
||||
- name: unit tests
|
||||
run: make pjlib-test-ci pjmedia-test pjlib-util-test pjsua-test
|
||||
|
||||
|
@ -47,11 +47,11 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: install dependencies
|
||||
run: brew install openssl opencore-amr
|
||||
run: brew install openssl@1.1 opencore-amr
|
||||
- name: config site
|
||||
run: cd pjlib/include/pj && cp config_site_test.h config_site.h
|
||||
- name: configure
|
||||
run: CFLAGS="-g $(pkg-config --cflags openssl) $(pkg-config --cflags opencore-amrnb)" LDFLAGS="$(pkg-config --libs-only-L openssl) $(pkg-config --libs-only-L openssl)/lib $(pkg-config --libs-only-L opencore-amrnb)" ./configure
|
||||
run: CFLAGS="-g -I/usr/local/include -I/usr/local/opt/openssl@1.1/include" LDFLAGS="-L/usr/local/lib -L/usr/local/opt/openssl@1.1/lib" ./configure
|
||||
- name: make
|
||||
run: make
|
||||
- name: disable firewall
|
||||
|
@ -65,11 +65,11 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: install dependencies
|
||||
run: brew install openssl opencore-amr
|
||||
run: brew install openssl@1.1 opencore-amr
|
||||
- name: config site
|
||||
run: cd pjlib/include/pj && cp config_site_test.h config_site.h
|
||||
- name: configure
|
||||
run: CFLAGS="-g $(pkg-config --cflags openssl) $(pkg-config --cflags opencore-amrnb)" LDFLAGS="$(pkg-config --libs-only-L openssl) $(pkg-config --libs-only-L openssl)/lib $(pkg-config --libs-only-L opencore-amrnb)" ./configure
|
||||
run: CFLAGS="-g -I/usr/local/include -I/usr/local/opt/openssl@1.1/include" LDFLAGS="-L/usr/local/lib -L/usr/local/opt/openssl@1.1/lib" ./configure
|
||||
- name: make
|
||||
run: make
|
||||
- name: disable firewall
|
||||
|
@ -86,15 +86,11 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: install dependencies
|
||||
run: brew install openssl swig
|
||||
run: brew install openssl@1.1 swig
|
||||
- name: configure
|
||||
run: CFLAGS="$(pkg-config --cflags openssl) -fPIC" LDFLAGS="$(pkg-config --libs-only-L openssl) $(pkg-config --libs-only-L openssl)/lib" CXXFLAGS="-fPIC" ./configure
|
||||
run: CFLAGS="-I/usr/local/include -I/usr/local/opt/openssl@1.1/include -fPIC" LDFLAGS="-L/usr/local/lib -L/usr/local/opt/openssl@1.1/lib" CXXFLAGS="-fPIC" ./configure
|
||||
- name: make
|
||||
run: make
|
||||
- name: set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10'
|
||||
- name: swig bindings
|
||||
run: cd pjsip-apps/src/swig && make
|
||||
|
||||
|
@ -109,10 +105,6 @@ jobs:
|
|||
run: CFLAGS="-fPIC" CXXFLAGS="-fPIC" ./configure --with-gnutls=/usr/local/
|
||||
- name: make
|
||||
run: make
|
||||
- name: set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10'
|
||||
- name: swig bindings
|
||||
run: cd pjsip-apps/src/swig && make
|
||||
|
||||
|
@ -123,21 +115,21 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: install dependencies
|
||||
run: brew install openssl openh264 libvpx opencore-amr swig sipp
|
||||
run: brew install openssl@1.1 openh264 libvpx opencore-amr swig sipp
|
||||
- name: config site
|
||||
run: cd pjlib/include/pj && cp config_site_test.h config_site.h && echo "#define PJMEDIA_HAS_VIDEO 1" >> config_site.h
|
||||
- name: configure
|
||||
run: CFLAGS="-g $(pkg-config --cflags openssl) $(pkg-config --cflags opencore-amrnb) -DHAS_VID_CODEC_TEST=0 -fPIC" LDFLAGS="$(pkg-config --libs-only-L openssl) $(pkg-config --libs-only-L openssl)/lib $(pkg-config --libs-only-L opencore-amrnb)" CXXFLAGS="-g -fPIC" ./configure
|
||||
run: CFLAGS="-g -I/usr/local/include -I/usr/local/opt/openssl@1.1/include -DHAS_VID_CODEC_TEST=0 -fPIC" LDFLAGS="-L/usr/local/lib -L/usr/local/opt/openssl@1.1/lib" CXXFLAGS="-g -fPIC" ./configure
|
||||
- name: make
|
||||
run: make
|
||||
- name: set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10'
|
||||
- name: swig bindings
|
||||
run: cd pjsip-apps/src/swig && make
|
||||
- name: disable firewall
|
||||
run: sudo /usr/libexec/ApplicationFirewall/socketfilterfw --setglobalstate off
|
||||
- name: set up Python 3.10 for pjsua test
|
||||
uses: actions/setup-python@v2
|
||||
with:
|
||||
python-version: '3.10'
|
||||
- name: unit tests
|
||||
run: make pjlib-test-ci pjmedia-test pjlib-util-test pjsua-test
|
||||
|
||||
|
@ -147,11 +139,11 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: install dependencies
|
||||
run: brew install openssl openh264 libvpx opencore-amr
|
||||
run: brew install openssl@1.1 openh264 libvpx opencore-amr
|
||||
- name: config site
|
||||
run: cd pjlib/include/pj && cp config_site_test.h config_site.h && echo "#define PJMEDIA_HAS_VIDEO 1" >> config_site.h
|
||||
- name: configure
|
||||
run: CFLAGS="-g $(pkg-config --cflags openssl) $(pkg-config --cflags opencore-amrnb)" LDFLAGS="$(pkg-config --libs-only-L openssl) $(pkg-config --libs-only-L openssl)/lib $(pkg-config --libs-only-L opencore-amrnb)" ./configure
|
||||
run: CFLAGS="-g -I/usr/local/include -I/usr/local/opt/openssl@1.1/include" LDFLAGS="-L/usr/local/lib -L/usr/local/opt/openssl@1.1/lib" ./configure
|
||||
- name: make
|
||||
run: make
|
||||
- name: disable firewall
|
||||
|
@ -165,11 +157,11 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: install dependencies
|
||||
run: brew install openssl openh264 libvpx opencore-amr
|
||||
run: brew install openssl@1.1 openh264 libvpx opencore-amr
|
||||
- name: config site
|
||||
run: cd pjlib/include/pj && cp config_site_test.h config_site.h && echo "#define PJMEDIA_HAS_VIDEO 1" >> config_site.h
|
||||
- name: configure
|
||||
run: CFLAGS="-g $(pkg-config --cflags openssl) $(pkg-config --cflags opencore-amrnb)" LDFLAGS="$(pkg-config --libs-only-L openssl) $(pkg-config --libs-only-L openssl)/lib $(pkg-config --libs-only-L opencore-amrnb)" ./configure
|
||||
run: CFLAGS="-g -I/usr/local/include -I/usr/local/opt/openssl@1.1/include" LDFLAGS="-L/usr/local/lib -L/usr/local/opt/openssl@1.1/lib" ./configure
|
||||
- name: make
|
||||
run: make
|
||||
- name: disable firewall
|
||||
|
@ -183,23 +175,19 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: install dependencies
|
||||
run: brew install openssl x264 libvpx nasm swig
|
||||
run: brew install openssl@1.1 x264 libvpx nasm swig
|
||||
- name: get ffmpeg
|
||||
run: git clone --single-branch --branch release/7.0 https://github.com/FFmpeg/FFmpeg.git
|
||||
run: git clone --single-branch --branch release/4.2 https://github.com/FFmpeg/FFmpeg.git
|
||||
- name: configure ffmpeg
|
||||
run: cd FFmpeg && LDFLAGS="-Wl,-ld_classic" ./configure --enable-shared --disable-static --enable-gpl --enable-libx264
|
||||
run: cd FFmpeg && ./configure --enable-shared --disable-static --enable-gpl --enable-libx264
|
||||
- name: build ffmpeg
|
||||
run: cd FFmpeg && make -j10 && sudo make install
|
||||
- name: config site
|
||||
run: echo -e "#define PJMEDIA_HAS_VIDEO 1\n" > pjlib/include/pj/config_site.h
|
||||
- name: configure
|
||||
run: CFLAGS="$(pkg-config --cflags openssl) -fPIC" LDFLAGS="$(pkg-config --libs-only-L openssl) $(pkg-config --libs-only-L openssl)/lib" CXXFLAGS="-fPIC" ./configure
|
||||
run: CFLAGS="-I/usr/local/include -I/usr/local/opt/openssl@1.1/include -fPIC" LDFLAGS="-L/usr/local/lib -L/usr/local/opt/openssl@1.1/lib" CXXFLAGS="-fPIC" ./configure
|
||||
- name: make
|
||||
run: make
|
||||
- name: set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10'
|
||||
- name: swig bindings
|
||||
run: cd pjsip-apps/src/swig && make
|
||||
|
||||
|
@ -209,16 +197,12 @@ jobs:
|
|||
steps:
|
||||
- uses: actions/checkout@v2
|
||||
- name: install dependencies
|
||||
run: brew install openssl libvpx swig
|
||||
run: brew install openssl@1.1 libvpx swig
|
||||
- name: config site
|
||||
run: echo -e "#define PJMEDIA_HAS_VIDEO 1\n#define PJMEDIA_HAS_VID_TOOLBOX_CODEC 1\n" > pjlib/include/pj/config_site.h
|
||||
- name: configure
|
||||
run: CFLAGS="$(pkg-config --cflags openssl) -fPIC" LDFLAGS="$(pkg-config --libs-only-L openssl) $(pkg-config --libs-only-L openssl)/lib" CXXFLAGS="-fPIC" ./configure
|
||||
run: CFLAGS="-I/usr/local/include -I/usr/local/opt/openssl@1.1/include -fPIC" LDFLAGS="-L/usr/local/lib -L/usr/local/opt/openssl@1.1/lib" CXXFLAGS="-fPIC" ./configure
|
||||
- name: make
|
||||
run: make
|
||||
- name: set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.10'
|
||||
- name: swig bindings
|
||||
run: cd pjsip-apps/src/swig && make
|
||||
|
|
|
@ -178,10 +178,25 @@ jobs:
|
|||
msbuild pjproject-vs14.sln /p:PlatformToolset=v143 /p:Configuration=Release /p:Platform=win32 /p:UseEnv=true
|
||||
shell: cmd
|
||||
|
||||
windows-with-video-libvpx-schannel-unit-test-1:
|
||||
windows-with-video-libvpx-unit-test-1:
|
||||
runs-on: windows-latest
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: get openssl
|
||||
run: Invoke-WebRequest -Uri "https://github.com/pjsip/third_party_libs/raw/main/openssl-1.1.1s-win.zip" -OutFile ".\openssl.zip"
|
||||
shell: powershell
|
||||
- name: expand openssl
|
||||
run: |
|
||||
Expand-Archive -LiteralPath .\openssl.zip -DestinationPath .; pwd
|
||||
cd openssl_build
|
||||
Add-Content ..\openssl_dir.txt $pwd.Path
|
||||
shell: powershell
|
||||
- name: check openssl folder
|
||||
run: |
|
||||
set /P OPENSSL_DIR=<openssl_dir.txt
|
||||
dir "%OPENSSL_DIR%\include"
|
||||
dir "%OPENSSL_DIR%\lib"
|
||||
shell: cmd
|
||||
- name: get vpx
|
||||
run: Invoke-WebRequest -Uri "https://github.com/pjsip/third_party_libs/raw/main/vpx-1.12-win.zip" -Outfile "vpx.zip"
|
||||
shell: powershell
|
||||
|
@ -216,8 +231,6 @@ jobs:
|
|||
run: |
|
||||
cd pjlib/include/pj; cp config_site_test.h config_site.h
|
||||
Add-Content config_site.h "#define PJ_HAS_SSL_SOCK 1"
|
||||
Add-Content config_site.h "#define PJ_SSL_SOCK_IMP PJ_SSL_SOCK_IMP_SCHANNEL"
|
||||
Add-Content config_site.h "#undef PJMEDIA_SRTP_HAS_DTLS"
|
||||
Add-Content config_site.h "#define PJMEDIA_HAS_VIDEO 1"
|
||||
Add-Content config_site.h "#define PJMEDIA_VIDEO_DEV_HAS_DSHOW 1"
|
||||
Add-Content config_site.h "#define PJMEDIA_HAS_LIBYUV 1"
|
||||
|
@ -245,7 +258,7 @@ jobs:
|
|||
set /P SDL_DIR=<sdl_dir.txt
|
||||
cd tests/pjsua/tools
|
||||
set INCLUDE=%INCLUDE%;%OPENSSL_DIR%\include;%VPX_DIR%\include;%SDL_DIR%\include
|
||||
set LIB=%LIB%;%VPX_DIR%\lib;%SDL_DIR%\lib\x86
|
||||
set LIB=%LIB%;%OPENSSL_DIR%\lib;%VPX_DIR%\lib;%SDL_DIR%\lib\x86
|
||||
call "%PROGRAMFILES%\Microsoft Visual Studio\2022\Enterprise\Common7\Tools\VsDevCmd.bat"
|
||||
msbuild cmp_wav.vcxproj /p:PlatformToolset=v143 /p:Configuration=Release /p:Platform=win32 /p:UseEnv=true
|
||||
shell: cmd
|
||||
|
@ -255,8 +268,9 @@ jobs:
|
|||
python-version: '3.10'
|
||||
- name: unit tests
|
||||
run: |
|
||||
$env:OPENSSL_DIR = Get-Content .\openssl_dir.txt
|
||||
$env:SDL_DIR = Get-Content .\sdl_dir.txt
|
||||
$env:PATH+=";$env:SDL_DIR\lib\x86;"
|
||||
$env:PATH+=";$env:OPENSSL_DIR\bin;$env:SDL_DIR\lib\x86;"
|
||||
cd tests/pjsua; python runall.py
|
||||
cd ../../pjlib/bin; ./pjlib-test-i386-Win32-vc14-Release.exe --ci-mode
|
||||
cd ../../pjlib-util/bin; ./pjlib-util-test-i386-Win32-vc14-Release.exe
|
||||
|
|
82
SECURITY.md
82
SECURITY.md
|
@ -17,50 +17,50 @@ Encrypt sensitive information using our PGP public key below.
|
|||
```
|
||||
-----BEGIN PGP PUBLIC KEY BLOCK-----
|
||||
Comment: User-ID: Teluu <security@pjsip.org>
|
||||
Comment: Created: 1/24/2024 10:05 AM
|
||||
Comment: Expires: 12/31/2029 12:00 PM
|
||||
Comment: Created: 7/29/2021 8:24 AM
|
||||
Comment: Expires: 7/29/2023 12:00 PM
|
||||
Comment: Type: 3,072-bit RSA (secret key available)
|
||||
Comment: Usage: Signing, Encryption, Certifying User-IDs
|
||||
Comment: Fingerprint: BCCC7ADEFFABAAB10FA4CDC027E875D43D995460
|
||||
Comment: Fingerprint: C2A9D29D94D131466D8832AE15BA5B3B5DAE8B36
|
||||
|
||||
|
||||
mQGNBGWwfm8BDACpBBGoBkkxgkm6hao9Fk63iEt3mJ6Ycg2BabeA7ZeHAA1IMkMG
|
||||
6247Y08Mk5DkqS+SeDu//44I6MQ/3tEDHqr59/F1qqhsu4zvPDOSgcfCET9kL7u0
|
||||
XhCrJC0DbEpTNmY9prnvNnzJOTzvbDQVysUII6b4UwhWC+Y+qhl6csVhoHUphwMs
|
||||
XZDtMR3EPpNbIrkXgUWRhEkcR2iuuLxnmdGTH8gDrtiq+IBcANkzojIEEQPulv6r
|
||||
IrrGbVx8hFRgbk5mJwIy6xRfr+5ah5gUeNM8fV/BwCUOP++qtY3c491I499XXdWa
|
||||
OpSRTSYgqY0kI0rl8B75FLG0qjnB1ySbmek++bWzK6sCJWmJxJJGjzVr3sccHOQZ
|
||||
hDUoK82OFkvde0em8HU1WnshRbSJhchrL6bO4uDMrGCYdO9uE2XHb/UiKFE9mCrw
|
||||
JKZlDg6PPUf8Gkqf594S3raekrvwWEmq/JWsk3WtNancMUQRd1pQR6ouXU0mHIih
|
||||
+1qf6hvXITxzDccAEQEAAbQaVGVsdXUgPHNlY3VyaXR5QHBqc2lwLm9yZz6JAdcE
|
||||
EwEIAEEWIQS8zHre/6uqsQ+kzcAn6HXUPZlUYAUCZbB+bwIbAwUJCypO4QULCQgH
|
||||
AgIiAgYVCgkICwIEFgIDAQIeBwIXgAAKCRAn6HXUPZlUYJmfDACLT86rTd+JMpUY
|
||||
iqYbELpOBfMkY0ebXVWQE/1FjmE5itS6XgHb3BWwXq99wtn9yKgwqbG8F2A/PVZd
|
||||
4Ga/EI0jyfJN85tjbk+bEqAkKIhzVljuLl6qkDqOOr6EzGAVAHLIJ1NgPLOOZKF8
|
||||
WM4t3WBTKRTJmGL9uNE/yblbRqrtsLAbtLcyZk0f8E8UYCIrWHKV7teop0VeBUw3
|
||||
+a0ISa9NHCLH35FYGROPL3s1CieWrYOSS/B8ncChqB8sfCE3UkcTTWvPSvCpYEIY
|
||||
mZjQa975HFcvYaD+sYJ+ZwJJGg5fm1jLaGFrL5zTvPpx53Y3u/SBXTeGEmal/tvp
|
||||
s5hz/3ZZeSmTLLcWjG1xcxVGnQF7EK4h1EmvcTz7mZrTY+ZHohnv7a50G3C5eo2s
|
||||
tNkf0E0ajfmgLXClxWMue+TzhwnnMQN7jdbTRU8SLgooG4LJeww7TiLI2eiyZC7L
|
||||
wOhNsbOyofnIfT0q/xWHKGJFe7Sffk6+cT/Jw0EWrt+34ATEUmC5AY0EZbB+bwEM
|
||||
AKan7Fo7Y2PDLh+hMb4KrPfQyypBIv8+//Ln4oEZLcYFcNzdWWVc4z54YfqkSu8j
|
||||
vGhjYKk5JK1l9RBHPoFGPV4pmG2hf/wSeNoYcs7Tz4wQapCYLNL6ouA9hJIezG5S
|
||||
BYs74njIrFtycJXlXhOlqzsJQ7dcMWlYjeXyiOFVYWyzcfwZWGJQ7i6YotmRxx6j
|
||||
IfJ3abRJtgTeUXqUNUagetpOjno+R8uYhm6r1sgajyi/WE8QMixVNoWgUo94jhk4
|
||||
ZAcAAw/gBN+pGQawf9TOC4llle8g0YENf39m/GtQ6PD6ks1pSnjXNLhiIHkrv5eD
|
||||
+I8td0RSbsHqgWjO1F4/h1eH4yQXbV5QTIcVgE5yLqIQaoScEFsOokLFm8NDWrVA
|
||||
eI0TBbOm1qtHaPpJROrEQkTyJBBFCFKRuC5u7LCirlN+O21lZDgKg/bPNe6tV4zr
|
||||
30FEsVy0njusY5ZSapbLemAOQldIwphgp8WBMFxq1tb86n6dOLYYte1A8DF3ryHM
|
||||
iQARAQABiQG8BBgBCAAmFiEEvMx63v+rqrEPpM3AJ+h11D2ZVGAFAmWwfm8CGwwF
|
||||
CQsqTuEACgkQJ+h11D2ZVGAcLAv+JB0iNqrtVG/cqBz44VC2+zJ6rAuGYuiR1sNL
|
||||
Ejvk9D483ZUKUpsZOjpVkgEJ88Fw73RoAiuEvF78mN6CloIIxQtJCFRs66PECjJP
|
||||
m9pjzx5wer2TqC+7l6fNp8pXFuLoeirvYTPisdUM+cqJ9N37BekqqiE0LSdGWcmK
|
||||
GqlO3DjPgyWfjE5rSGy9Bu4l9HKmv8AUtFiw3g65cwDC/23LFYK+HJB8gelLytkp
|
||||
kLSC6HbNg6lpnFoqhIJYBr3TK8IKXhD62dO4B3IyWnqMnKFJ2fv1ILj42LlzWgZo
|
||||
ULnZUI/EUpV3+5ELVmNKJiWGB1OgVsaJalN5TMqnr2iXPg1qnJzvzvvuwwDfA6g0
|
||||
EeR5H7yOK5WvQvGDJrUaESXRMZgubJmv42EmfT048Ajq1/SaWTdQqRK9CoFIJTOY
|
||||
lQAakbU2ukwSJRdwd+PDRFWB8c4geIAtiYJw+LseTKtjo4++hADQBoRkqgnKB1o7
|
||||
oUbFbwQAAHfNE3xFJespnLA/KbbO
|
||||
=Oiwu
|
||||
mQGNBGECAzwBDADjloGXRtTaSoTj+Nz4uy5Ei8e9CpIe0kEXLUykdr0bxWh7EiUX
|
||||
EqkZnFXbt3bWcFTVp7CQMn1as8/AUSteRbKuweLVyx/fFFtxrOQIBNqrwJhwwbmx
|
||||
SKLc4Pe/RqT8HmJb+MRnU3rkuzJ4ak0Nh5fLUFL/gBmped8MqBmF8OobJt0U/z/d
|
||||
opqVGfnHPablA3nJUcbMW97GJ8FH4cX5ZT+46cbpoJo/L7WbMUpbZcnz+iPiQFFO
|
||||
/oO7AbVihdvFNd0SoXi7aE8i8BFIhOYa9nLJId/PMRqG9aFTRP8dOwbOL+EekQ7d
|
||||
5x81bQLgjpXogORDxiUns0cFgPBDz5P1Y1qXlQ+HYa8m/vIKnEZMo1mnNhBR40cM
|
||||
XyrapeA9WcXiYNo4FBEt6rHoCKpGbMG5Rfpk5u5KljDGxg3tdbuXNfbJPFAOp3IB
|
||||
hQ72zhT4rWV31J8IEmoBOT8smf04cEr+jfrjs/ejYJh//Ez7AzMhyoDm1m1ELWwW
|
||||
Mzvm5QPtm1pwHakAEQEAAbQaVGVsdXUgPHNlY3VyaXR5QHBqc2lwLm9yZz6JAdQE
|
||||
EwEIAD4WIQTCqdKdlNExRm2IMq4Vuls7Xa6LNgUCYQIDPAIbAwUJA8KZlAULCQgH
|
||||
AgYVCgkICwIEFgIDAQIeAQIXgAAKCRAVuls7Xa6LNhEGC/4p9GiArgRF0DgVa40O
|
||||
JeH8mObjpweBvQc1zpHX2cA9DhkEs/vP0lg29v1248HnnZFz0HBnXKGQVq599jZX
|
||||
blm1IphNJSWfkutfjIIH80fqDCuqHOHLhrf0qzDxIAWaSSr0Bh/rGHlsPo2+s35f
|
||||
3EMwpkDzETnoLeJMShxAwJOocZBqIieWK2/MZKdLnwn2Evb40BJ63UftFOCf7LuQ
|
||||
tbZQ/w2op3Capt+6BL5aNAwnhz5uTgzUE2dLA31YCpWPDJbE1vMy05suzbEqGLu1
|
||||
aAFAKocdw1gbFrvEj2nDhH3dD10kQeMtXNPXqtQfRcmQCi8HCetfmFjfB8n5J6YW
|
||||
G6dtmiC9RfDgUlrhfTcHRL7ioD2g8jZt2LE2yXulS+8AD10/WQTWkEHYmly0bHAE
|
||||
sbAtwNA1asVsuVNUreTirZA0KgTJRySe/WbCyaCXStlTHy2X2aKR0jaNhm56Snpz
|
||||
K+aRPTsc6ZFOQOzBMys7hBCAQlCQ0CQyzucMfV3Egl83Qxm5AY0EYQIDPAEMALRb
|
||||
OcHPuJ77J+jZGtNAp27/QDXsA1AwvyxDVP+BhZUS3gKXqoyXS3THNEQoqL8GhvZz
|
||||
j/sDQo7Hs6p3oEj+HXF2LzlOjiaqObZsYaEBrMo/OS6p/8YvVOa39eTtuvgNVeDB
|
||||
EitlH8/pjk5bsZ0KFWqijcqsu0i4ye758UyERZ1ruXHNMB4auow4ZAwqn0vNN0CH
|
||||
f1hP/2qMLw5krCgHx1QowMk7S83ljFF5J36ojOuVQjzrCd96eWMHCdUpXbBJv7dd
|
||||
firVH9JIOAMDRAEoeX/EjWqeHlPVoOElGUWqAVKveQ0GNdN10hT+1gg0lxqR8f5G
|
||||
QDz7u6pDHJHhDQeMH6HYpRLXiXN23AEYnwpzFyw7p22WihV/6rKzGAP7JECZGDsD
|
||||
w5x2/YWRcg04MWcnY25f79JM/QWfRGfX6cxdKPxDDgZKUREzESy8/VeefF+xLklg
|
||||
O8t9xASz7dU4iSzwdyT5AJX7hIjyJxij8EroQ+4rn4m/zwVE9I9vUNn139kIaQAR
|
||||
AQABiQG8BBgBCAAmFiEEwqnSnZTRMUZtiDKuFbpbO12uizYFAmECAzwCGwwFCQPC
|
||||
mZQACgkQFbpbO12uizZQHwwAkActQzy2bb6naSAAVgxvobrNuXzO+HygJLgBa37l
|
||||
NdFxbBnN0YjYYrjA5PJJZYTcEaedz8Uec2onqTDpsaMDRwouCRayo19WizmSQd34
|
||||
DdygKA2CecQdXxKUf/2vxE//Jxq1/Sq0+facynhTygG24aSI44F/iw2h+9Z9JPcM
|
||||
BwtNLdGcuWEU2slHcN24sBveBHbTyCe4h52OMr/HBPldAREa2zojF4J8fxTPD6ES
|
||||
wx8mWc79sr50EPejw2r3ipKjrbxiB1yDtiry/eZatidb0slGWLzBhawOkZAUrVJh
|
||||
DODKf+upkfP8V/MayqRdNNH8FDxYUgxYwnX9+VbtJr7BrvnoyGgOwIuxN5TV+EQt
|
||||
+Bf7Kzzsqz2/bzsPtnd/F3faAAoOEzby//fdLWUpKcubf7kVq0EQ9bMKwC56rLpd
|
||||
BnLaAfcL/676JS3bjJMc3ij3T2doC3IFwj84kNoBk+ArgBFlKjcB84Uket+rj23e
|
||||
SjwjgsVZsFg9w1+m0F72hyAQ
|
||||
=rD28
|
||||
-----END PGP PUBLIC KEY BLOCK-----
|
||||
```
|
||||
|
|
61
aconfigure
61
aconfigure
|
@ -712,7 +712,6 @@ ac_pjmedia_video_has_qt
|
|||
ac_darwin_cflags
|
||||
ac_pjmedia_video_has_ios_opengl
|
||||
ac_pjmedia_video_has_vtoolbox
|
||||
ac_pjmedia_video_has_metal
|
||||
ac_pjmedia_video_has_darwin
|
||||
ac_dshow_ldflags
|
||||
ac_dshow_cflags
|
||||
|
@ -4849,7 +4848,7 @@ fi
|
|||
|
||||
if test "$AR_FLAGS" = ""; then AR_FLAGS="rv"; fi
|
||||
|
||||
if test "$LD" = ""; then LD="$CXX"; fi
|
||||
if test "$LD" = ""; then LD="$CC"; fi
|
||||
|
||||
if test "$LDOUT" = ""; then LDOUT="-o "; fi
|
||||
|
||||
|
@ -6518,26 +6517,19 @@ rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext
|
|||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking ioqueue backend" >&5
|
||||
printf %s "checking ioqueue backend... " >&6; }
|
||||
|
||||
ac_os_objs=ioqueue_select.o
|
||||
ac_linux_poll=select
|
||||
|
||||
case $target in
|
||||
*darwin* | *bsd*)
|
||||
# Check whether --enable-kqueue was given.
|
||||
if test ${enable_kqueue+y}
|
||||
then :
|
||||
enableval=$enable_kqueue;
|
||||
if test "$enable_kqueue" = "yes"; then
|
||||
ac_os_objs=ioqueue_kqueue.o
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: kqueue()" >&5
|
||||
ac_os_objs=ioqueue_kqueue.o
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: kqueue()" >&5
|
||||
printf "%s\n" "kqueue()" >&6; }
|
||||
else
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: select()" >&5
|
||||
printf "%s\n" "select()" >&6; }
|
||||
fi
|
||||
|
||||
else $as_nop
|
||||
|
||||
ac_os_objs=ioqueue_select.o
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: select()" >&5
|
||||
printf "%s\n" "select()" >&6; }
|
||||
|
||||
|
@ -6549,22 +6541,19 @@ fi
|
|||
if test ${enable_epoll+y}
|
||||
then :
|
||||
enableval=$enable_epoll;
|
||||
if test "$enable_epoll" = "yes"; then
|
||||
ac_os_objs=ioqueue_epoll.o
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: /dev/epoll" >&5
|
||||
ac_os_objs=ioqueue_epoll.o
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: /dev/epoll" >&5
|
||||
printf "%s\n" "/dev/epoll" >&6; }
|
||||
printf "%s\n" "#define PJ_HAS_LINUX_EPOLL 1" >>confdefs.h
|
||||
printf "%s\n" "#define PJ_HAS_LINUX_EPOLL 1" >>confdefs.h
|
||||
|
||||
ac_linux_poll=epoll
|
||||
else
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: select()" >&5
|
||||
printf "%s\n" "select()" >&6; }
|
||||
fi
|
||||
ac_linux_poll=epoll
|
||||
|
||||
else $as_nop
|
||||
|
||||
ac_os_objs=ioqueue_select.o
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: select()" >&5
|
||||
printf "%s\n" "select()" >&6; }
|
||||
ac_linux_poll=select
|
||||
|
||||
fi
|
||||
|
||||
|
@ -7480,7 +7469,6 @@ printf "%s\n" "Checking if OpenGL ES 2 is available... no" >&6; }
|
|||
|
||||
|
||||
|
||||
|
||||
SAVED_LIBS="$LIBS"
|
||||
LIBS="-framework AVFoundation -framework CoreGraphics -framework QuartzCore -framework CoreVideo -framework CoreMedia"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
|
@ -7520,26 +7508,6 @@ then :
|
|||
else $as_nop
|
||||
ac_pjmedia_video_has_vtoolbox=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS="-framework Metal"
|
||||
cat confdefs.h - <<_ACEOF >conftest.$ac_ext
|
||||
/* end confdefs.h. */
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
|
||||
;
|
||||
return 0;
|
||||
}
|
||||
_ACEOF
|
||||
if ac_fn_c_try_link "$LINENO"
|
||||
then :
|
||||
ac_pjmedia_video_has_metal=yes
|
||||
else $as_nop
|
||||
ac_pjmedia_video_has_metal=no
|
||||
fi
|
||||
rm -f core conftest.err conftest.$ac_objext conftest.beam \
|
||||
conftest$ac_exeext conftest.$ac_ext
|
||||
LIBS="-framework OpenGLES"
|
||||
|
@ -7571,15 +7539,6 @@ printf "%s\n" "Checking if AVFoundation framework is available... yes" >&6; }
|
|||
else
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Checking if AVFoundation framework is available... no" >&5
|
||||
printf "%s\n" "Checking if AVFoundation framework is available... no" >&6; }
|
||||
fi
|
||||
if test "$ac_pjmedia_video_has_metal" = "yes"; then
|
||||
ac_darwin_cflags+=" -DPJMEDIA_VIDEO_DEV_HAS_METAL=1"
|
||||
LIBS="$LIBS -framework Metal -framework MetalKit"
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Checking if Metal framework is available... yes" >&5
|
||||
printf "%s\n" "Checking if Metal framework is available... yes" >&6; }
|
||||
else
|
||||
{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: Checking if Metal framework is available... no" >&5
|
||||
printf "%s\n" "Checking if Metal framework is available... no" >&6; }
|
||||
fi
|
||||
if test "$ac_pjmedia_video_has_vtoolbox" = "yes"; then
|
||||
#ac_darwin_cflags+=" -DPJMEDIA_HAS_VID_TOOLBOX_CODEC=1"
|
||||
|
|
|
@ -46,7 +46,7 @@ AC_CHECK_TOOLS([AR], [ar gar], :)
|
|||
|
||||
if test "$AR_FLAGS" = ""; then AR_FLAGS="rv"; fi
|
||||
AC_SUBST(AR_FLAGS)
|
||||
if test "$LD" = ""; then LD="$CXX"; fi
|
||||
if test "$LD" = ""; then LD="$CC"; fi
|
||||
AC_SUBST(LD)
|
||||
if test "$LDOUT" = ""; then LDOUT="-o "; fi
|
||||
AC_SUBST(LDOUT)
|
||||
|
@ -467,23 +467,17 @@ AC_SUBST(ac_os_objs)
|
|||
AC_SUBST(ac_linux_poll)
|
||||
AC_MSG_CHECKING([ioqueue backend])
|
||||
|
||||
ac_os_objs=ioqueue_select.o
|
||||
ac_linux_poll=select
|
||||
|
||||
case $target in
|
||||
*darwin* | *bsd*)
|
||||
AC_ARG_ENABLE(kqueue,
|
||||
AS_HELP_STRING([--enable-kqueue],
|
||||
[Use kqueue ioqueue on macos/BSD (experimental)]),
|
||||
[
|
||||
if test "$enable_kqueue" = "yes"; then
|
||||
ac_os_objs=ioqueue_kqueue.o
|
||||
AC_MSG_RESULT([kqueue()])
|
||||
else
|
||||
AC_MSG_RESULT([select()])
|
||||
fi
|
||||
ac_os_objs=ioqueue_kqueue.o
|
||||
AC_MSG_RESULT([kqueue()])
|
||||
],
|
||||
[
|
||||
ac_os_objs=ioqueue_select.o
|
||||
AC_MSG_RESULT([select()])
|
||||
])
|
||||
;;
|
||||
|
@ -492,17 +486,15 @@ case $target in
|
|||
AS_HELP_STRING([--enable-epoll],
|
||||
[Use /dev/epoll ioqueue on Linux (experimental)]),
|
||||
[
|
||||
if test "$enable_epoll" = "yes"; then
|
||||
ac_os_objs=ioqueue_epoll.o
|
||||
AC_MSG_RESULT([/dev/epoll])
|
||||
AC_DEFINE(PJ_HAS_LINUX_EPOLL,1)
|
||||
ac_linux_poll=epoll
|
||||
else
|
||||
AC_MSG_RESULT([select()])
|
||||
fi
|
||||
ac_os_objs=ioqueue_epoll.o
|
||||
AC_MSG_RESULT([/dev/epoll])
|
||||
AC_DEFINE(PJ_HAS_LINUX_EPOLL,1)
|
||||
ac_linux_poll=epoll
|
||||
],
|
||||
[
|
||||
ac_os_objs=ioqueue_select.o
|
||||
AC_MSG_RESULT([select()])
|
||||
ac_linux_poll=select
|
||||
])
|
||||
;;
|
||||
esac
|
||||
|
@ -1055,7 +1047,6 @@ else
|
|||
*darwin*)
|
||||
ac_pjmedia_video=darwin_os
|
||||
AC_SUBST(ac_pjmedia_video_has_darwin)
|
||||
AC_SUBST(ac_pjmedia_video_has_metal)
|
||||
AC_SUBST(ac_pjmedia_video_has_vtoolbox)
|
||||
AC_SUBST(ac_pjmedia_video_has_ios_opengl)
|
||||
AC_SUBST(ac_darwin_cflags)
|
||||
|
@ -1068,10 +1059,6 @@ else
|
|||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [])],
|
||||
[ac_pjmedia_video_has_vtoolbox=yes],
|
||||
[ac_pjmedia_video_has_vtoolbox=no])
|
||||
LIBS="-framework Metal"
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [])],
|
||||
[ac_pjmedia_video_has_metal=yes],
|
||||
[ac_pjmedia_video_has_metal=no])
|
||||
LIBS="-framework OpenGLES"
|
||||
AC_LINK_IFELSE([AC_LANG_PROGRAM([[]], [])],
|
||||
[ac_pjmedia_video_has_ios_opengl=yes],
|
||||
|
@ -1084,13 +1071,6 @@ else
|
|||
else
|
||||
AC_MSG_RESULT([Checking if AVFoundation framework is available... no])
|
||||
fi
|
||||
if test "$ac_pjmedia_video_has_metal" = "yes"; then
|
||||
ac_darwin_cflags+=" -DPJMEDIA_VIDEO_DEV_HAS_METAL=1"
|
||||
LIBS="$LIBS -framework Metal -framework MetalKit"
|
||||
AC_MSG_RESULT([Checking if Metal framework is available... yes])
|
||||
else
|
||||
AC_MSG_RESULT([Checking if Metal framework is available... no])
|
||||
fi
|
||||
if test "$ac_pjmedia_video_has_vtoolbox" = "yes"; then
|
||||
#ac_darwin_cflags+=" -DPJMEDIA_HAS_VID_TOOLBOX_CODEC=1"
|
||||
LIBS="$LIBS -framework VideoToolbox"
|
||||
|
|
|
@ -204,7 +204,6 @@ AC_PJMEDIA_VIDEO_HAS_QT = @ac_pjmedia_video_has_qt@
|
|||
|
||||
# Darwin (Mac and iOS)
|
||||
AC_PJMEDIA_VIDEO_HAS_DARWIN = @ac_pjmedia_video_has_darwin@
|
||||
AC_PJMEDIA_VIDEO_HAS_METAL = @ac_pjmedia_video_has_metal@
|
||||
AC_PJMEDIA_VIDEO_HAS_VTOOLBOX = @ac_pjmedia_video_has_vtoolbox@
|
||||
AC_PJMEDIA_VIDEO_HAS_IOS_OPENGL = @ac_pjmedia_video_has_ios_opengl@
|
||||
DARWIN_CFLAGS = @ac_darwin_cflags@
|
||||
|
|
|
@ -20,8 +20,8 @@ if test "$*" = "--help" -o "$*" = "-h"; then
|
|||
echo " ARCH Optional flags to specify target architecture, e.g."
|
||||
echo " ARCH=\"-arch armv7\". Default is arm64."
|
||||
echo " MIN_IOS Optional flags to specify minimum supported iOS"
|
||||
echo " versions, e.g. MIN_IOS=\"-miphoneos-version-min=11.0\". "
|
||||
echo " Default is 11.0."
|
||||
echo " versions, e.g. MIN_IOS=\"-miphoneos-version-min=10.0\". "
|
||||
echo " Default is 7.0."
|
||||
echo ""
|
||||
exit 0
|
||||
fi
|
||||
|
@ -123,7 +123,7 @@ if test "${ARCH_VAL}" = "arm64e"; then
|
|||
fi
|
||||
|
||||
if test "${MIN_IOS}" = ""; then
|
||||
MIN_IOS_VER="11.0"
|
||||
MIN_IOS_VER="7.0"
|
||||
echo "$F: MIN_IOS is not specified, choosing ${MIN_IOS_VER}"
|
||||
MIN_IOS="-miphoneos-version-min=${MIN_IOS_VER}"
|
||||
fi
|
||||
|
|
|
@ -259,10 +259,6 @@ GENERATE_DEPRECATEDLIST= YES
|
|||
# You can put \n's in the value part of an alias to insert newlines.
|
||||
|
||||
ALIASES =
|
||||
ALIASES += src{1}="\verbatim embed:rst:inline :source:`\1` \endverbatim"
|
||||
ALIASES += srcdir{1}="\verbatim embed:rst:inline :sourcedir:`\1` \endverbatim"
|
||||
ALIASES += img{1}="<img src=\"https://raw.githubusercontent.com/pjsip/pjproject/master/\1\" />"
|
||||
ALIASES += img{2}="<img src=\"https://raw.githubusercontent.com/pjsip/pjproject/master/\1\" alt=\"\2\" />"
|
||||
|
||||
# The ENABLED_SECTIONS tag can be used to enable conditional
|
||||
# documentation sections, marked by \if sectionname ... \endif.
|
||||
|
|
|
@ -64,21 +64,6 @@ PJ_BEGIN_DECL
|
|||
PJ_DECL(pj_status_t) pj_base64_encode(const pj_uint8_t *input, int in_len,
|
||||
char *output, int *out_len);
|
||||
|
||||
/**
|
||||
* Encode a buffer into base64 (URL and Filename Safe) encoding.
|
||||
*
|
||||
* @param input The input buffer.
|
||||
* @param in_len Size of the input buffer.
|
||||
* @param output Output buffer. Caller must allocate this buffer with
|
||||
* the appropriate size.
|
||||
* @param out_len On entry, it specifies the length of the output buffer.
|
||||
* Upon return, this will be filled with the actual
|
||||
* length of the output buffer.
|
||||
*
|
||||
* @return PJ_SUCCESS on success.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_base64url_encode(const pj_uint8_t *input, int in_len,
|
||||
char *output, int *out_len);
|
||||
|
||||
/**
|
||||
* Decode base64 string.
|
||||
|
@ -93,18 +78,6 @@ PJ_DECL(pj_status_t) pj_base64url_encode(const pj_uint8_t *input, int in_len,
|
|||
PJ_DECL(pj_status_t) pj_base64_decode(const pj_str_t *input,
|
||||
pj_uint8_t *out, int *out_len);
|
||||
|
||||
/**
|
||||
* Decode base64 (URL and Filename Safe) string.
|
||||
*
|
||||
* @param input Input string.
|
||||
* @param out Buffer to store the output. Caller must allocate
|
||||
* this buffer with the appropriate size.
|
||||
* @param out_len On entry, it specifies the length of the output buffer.
|
||||
* Upon return, this will be filled with the actual
|
||||
* length of the output.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_base64url_decode(const pj_str_t *input,
|
||||
pj_uint8_t *out, int *out_len);
|
||||
|
||||
|
||||
/**
|
||||
|
|
|
@ -163,7 +163,7 @@ static void on_data_read(pj_http_req *hreq, void *data, pj_size_t size)
|
|||
PJ_UNUSED_ARG(hreq);
|
||||
PJ_UNUSED_ARG(data);
|
||||
|
||||
PJ_LOG(5, (THIS_FILE, "\nData received: %lu bytes", (unsigned long)size));
|
||||
PJ_LOG(5, (THIS_FILE, "\nData received: %ld bytes", size));
|
||||
if (size > 0) {
|
||||
#ifdef VERBOSE
|
||||
printf("%.*s\n", (int)size, (char *)data);
|
||||
|
@ -190,8 +190,8 @@ static void on_send_data(pj_http_req *hreq,
|
|||
*data = sdata;
|
||||
*size = sendsz;
|
||||
|
||||
PJ_LOG(5, (THIS_FILE, "\nSending data progress: %lu out of %lu bytes",
|
||||
(unsigned long)send_size, (unsigned long)total_size));
|
||||
PJ_LOG(5, (THIS_FILE, "\nSending data progress: %ld out of %ld bytes",
|
||||
send_size, total_size));
|
||||
}
|
||||
|
||||
|
||||
|
@ -210,8 +210,7 @@ static void on_complete(pj_http_req *hreq, pj_status_t status,
|
|||
PJ_LOG(3, (THIS_FILE, "Error %d", status));
|
||||
return;
|
||||
}
|
||||
PJ_LOG(5, (THIS_FILE, "\nData completed: %lu bytes",
|
||||
(unsigned long)resp->size));
|
||||
PJ_LOG(5, (THIS_FILE, "\nData completed: %ld bytes", resp->size));
|
||||
if (resp->size > 0 && resp->data) {
|
||||
#ifdef VERBOSE
|
||||
printf("%.*s\n", (int)resp->size, (char *)resp->data);
|
||||
|
|
|
@ -33,18 +33,7 @@ static const char base64_char[] = {
|
|||
'8', '9', '+', '/'
|
||||
};
|
||||
|
||||
/* Base 64 Encoding with URL and Filename Safe Alphabet (RFC 4648 section 5) */
|
||||
static const char base64url_char[] = {
|
||||
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J',
|
||||
'K', 'L', 'M', 'N', 'O', 'P', 'Q', 'R', 'S', 'T',
|
||||
'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 'c', 'd',
|
||||
'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n',
|
||||
'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x',
|
||||
'y', 'z', '0', '1', '2', '3', '4', '5', '6', '7',
|
||||
'8', '9', '-', '_'
|
||||
};
|
||||
|
||||
static int base256_char(char c, pj_bool_t url)
|
||||
static int base256_char(char c)
|
||||
{
|
||||
if (c >= 'A' && c <= 'Z')
|
||||
return (c - 'A');
|
||||
|
@ -52,9 +41,9 @@ static int base256_char(char c, pj_bool_t url)
|
|||
return (c - 'a' + 26);
|
||||
else if (c >= '0' && c <= '9')
|
||||
return (c - '0' + 52);
|
||||
else if ((!url && c == '+') || (url && c == '-'))
|
||||
else if (c == '+')
|
||||
return (62);
|
||||
else if ((!url && c == '/') || (url && c == '_'))
|
||||
else if (c == '/')
|
||||
return (63);
|
||||
else {
|
||||
/* It *may* happen on bad input, so this is not a good idea.
|
||||
|
@ -66,18 +55,17 @@ static int base256_char(char c, pj_bool_t url)
|
|||
|
||||
|
||||
static void base256to64(pj_uint8_t c1, pj_uint8_t c2, pj_uint8_t c3,
|
||||
int padding, char *output, pj_bool_t url)
|
||||
int padding, char *output)
|
||||
{
|
||||
const char *b64 = url ? base64url_char : base64_char;
|
||||
*output++ = b64[c1>>2];
|
||||
*output++ = b64[((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)];
|
||||
*output++ = base64_char[c1>>2];
|
||||
*output++ = base64_char[((c1 & 0x3)<< 4) | ((c2 & 0xF0) >> 4)];
|
||||
switch (padding) {
|
||||
case 0:
|
||||
*output++ = b64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];
|
||||
*output = b64[c3 & 0x3F];
|
||||
*output++ = base64_char[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];
|
||||
*output = base64_char[c3 & 0x3F];
|
||||
break;
|
||||
case 1:
|
||||
*output++ = b64[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];
|
||||
*output++ = base64_char[((c2 & 0xF) << 2) | ((c3 & 0xC0) >>6)];
|
||||
*output = PADDING;
|
||||
break;
|
||||
case 2:
|
||||
|
@ -88,9 +76,9 @@ static void base256to64(pj_uint8_t c1, pj_uint8_t c2, pj_uint8_t c3,
|
|||
}
|
||||
}
|
||||
|
||||
static pj_status_t b64_encode(const pj_uint8_t *input, int in_len,
|
||||
char *output, int *out_len,
|
||||
pj_bool_t url)
|
||||
|
||||
PJ_DEF(pj_status_t) pj_base64_encode(const pj_uint8_t *input, int in_len,
|
||||
char *output, int *out_len)
|
||||
{
|
||||
const pj_uint8_t *pi = input;
|
||||
pj_uint8_t c1, c2, c3;
|
||||
|
@ -106,7 +94,7 @@ static pj_status_t b64_encode(const pj_uint8_t *input, int in_len,
|
|||
++i;
|
||||
|
||||
if (i == in_len) {
|
||||
base256to64(c1, 0, 0, 2, po, url);
|
||||
base256to64(c1, 0, 0, 2, po);
|
||||
po += 4;
|
||||
break;
|
||||
} else {
|
||||
|
@ -114,13 +102,13 @@ static pj_status_t b64_encode(const pj_uint8_t *input, int in_len,
|
|||
++i;
|
||||
|
||||
if (i == in_len) {
|
||||
base256to64(c1, c2, 0, 1, po, url);
|
||||
base256to64(c1, c2, 0, 1, po);
|
||||
po += 4;
|
||||
break;
|
||||
} else {
|
||||
c3 = *pi++;
|
||||
++i;
|
||||
base256to64(c1, c2, c3, 0, po, url);
|
||||
base256to64(c1, c2, c3, 0, po);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,9 +119,9 @@ static pj_status_t b64_encode(const pj_uint8_t *input, int in_len,
|
|||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
static pj_status_t b64_decode(const pj_str_t *input,
|
||||
pj_uint8_t *out, int *out_len,
|
||||
pj_bool_t url)
|
||||
|
||||
PJ_DEF(pj_status_t) pj_base64_decode(const pj_str_t *input,
|
||||
pj_uint8_t *out, int *out_len)
|
||||
{
|
||||
const char *buf;
|
||||
int len;
|
||||
|
@ -154,7 +142,7 @@ static pj_status_t b64_decode(const pj_str_t *input,
|
|||
/* Fill up c, silently ignoring invalid characters */
|
||||
for (k=0; k<4 && i<len; ++k) {
|
||||
do {
|
||||
c[k] = base256_char(buf[i++], url);
|
||||
c[k] = base256_char(buf[i++]);
|
||||
} while (c[k]==INV && i<len);
|
||||
}
|
||||
|
||||
|
@ -180,26 +168,4 @@ static pj_status_t b64_decode(const pj_str_t *input,
|
|||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
PJ_DEF(pj_status_t) pj_base64_encode(const pj_uint8_t *input, int in_len,
|
||||
char *output, int *out_len)
|
||||
{
|
||||
return b64_encode(input, in_len, output, out_len, PJ_FALSE);
|
||||
}
|
||||
|
||||
PJ_DEF(pj_status_t) pj_base64url_encode(const pj_uint8_t *input, int in_len,
|
||||
char *output, int *out_len)
|
||||
{
|
||||
return b64_encode(input, in_len, output, out_len, PJ_TRUE);
|
||||
}
|
||||
|
||||
PJ_DEF(pj_status_t) pj_base64_decode(const pj_str_t *input,
|
||||
pj_uint8_t *out, int *out_len)
|
||||
{
|
||||
return b64_decode(input, out, out_len, PJ_FALSE);
|
||||
}
|
||||
|
||||
PJ_DEF(pj_status_t) pj_base64url_decode(const pj_str_t *input,
|
||||
pj_uint8_t *out, int *out_len)
|
||||
{
|
||||
return b64_decode(input, out, out_len, PJ_TRUE);
|
||||
}
|
||||
|
|
|
@ -1840,15 +1840,15 @@ PJ_DEF(pj_status_t) pj_dns_resolver_add_entry( pj_dns_resolver *resolver,
|
|||
pj_bzero(&key, sizeof(struct res_key));
|
||||
if (pkt->hdr.anscount) {
|
||||
/* Make sure name is not too long. */
|
||||
PJ_ASSERT_ON_FAIL(pkt->ans[0].name.slen < PJ_MAX_HOSTNAME,
|
||||
{ pj_grp_lock_release(resolver->grp_lock); return PJ_ENAMETOOLONG; });
|
||||
PJ_ASSERT_RETURN(pkt->ans[0].name.slen < PJ_MAX_HOSTNAME,
|
||||
PJ_ENAMETOOLONG);
|
||||
|
||||
init_res_key(&key, pkt->ans[0].type, &pkt->ans[0].name);
|
||||
|
||||
} else {
|
||||
/* Make sure name is not too long. */
|
||||
PJ_ASSERT_ON_FAIL(pkt->q[0].name.slen < PJ_MAX_HOSTNAME,
|
||||
{ pj_grp_lock_release(resolver->grp_lock); return PJ_ENAMETOOLONG; });
|
||||
PJ_ASSERT_RETURN(pkt->q[0].name.slen < PJ_MAX_HOSTNAME,
|
||||
PJ_ENAMETOOLONG);
|
||||
|
||||
init_res_key(&key, pkt->q[0].type, &pkt->q[0].name);
|
||||
}
|
||||
|
@ -1942,12 +1942,12 @@ PJ_DEF(void) pj_dns_resolver_dump(pj_dns_resolver *resolver,
|
|||
}
|
||||
}
|
||||
PJ_LOG(3,(resolver->name.ptr, " Nb. of pending query free nodes: %lu",
|
||||
(unsigned long)pj_list_size(&resolver->query_free_nodes)));
|
||||
pj_list_size(&resolver->query_free_nodes)));
|
||||
PJ_LOG(3,(resolver->name.ptr, " Nb. of timer entries: %lu",
|
||||
(unsigned long)pj_timer_heap_count(resolver->timer)));
|
||||
pj_timer_heap_count(resolver->timer)));
|
||||
PJ_LOG(3,(resolver->name.ptr, " Pool capacity: %lu, used size: %lu",
|
||||
(unsigned long)pj_pool_get_capacity(resolver->pool),
|
||||
(unsigned long)pj_pool_get_used_size(resolver->pool)));
|
||||
pj_pool_get_capacity(resolver->pool),
|
||||
pj_pool_get_used_size(resolver->pool)));
|
||||
|
||||
pj_grp_lock_release(resolver->grp_lock);
|
||||
#endif
|
||||
|
|
|
@ -142,17 +142,14 @@ PJ_DEF(void) pj_scan_skip_whitespace( pj_scanner *scanner )
|
|||
{
|
||||
register char *s = scanner->curptr;
|
||||
|
||||
while (PJ_SCAN_CHECK_EOF(s) && PJ_SCAN_IS_SPACE(*s)) {
|
||||
while (PJ_SCAN_IS_SPACE(*s)) {
|
||||
++s;
|
||||
}
|
||||
|
||||
if (PJ_SCAN_CHECK_EOF(s) && PJ_SCAN_IS_NEWLINE(*s) &&
|
||||
(scanner->skip_ws & PJ_SCAN_AUTOSKIP_NEWLINE))
|
||||
{
|
||||
for (; PJ_SCAN_CHECK_EOF(s); ) {
|
||||
if (PJ_SCAN_IS_NEWLINE(*s) && (scanner->skip_ws & PJ_SCAN_AUTOSKIP_NEWLINE)) {
|
||||
for (;;) {
|
||||
if (*s == '\r') {
|
||||
++s;
|
||||
if (!PJ_SCAN_CHECK_EOF(s)) break;
|
||||
if (*s == '\n') ++s;
|
||||
++scanner->line;
|
||||
scanner->curptr = scanner->start_line = s;
|
||||
|
@ -163,33 +160,30 @@ PJ_DEF(void) pj_scan_skip_whitespace( pj_scanner *scanner )
|
|||
} else if (PJ_SCAN_IS_SPACE(*s)) {
|
||||
do {
|
||||
++s;
|
||||
} while (PJ_SCAN_CHECK_EOF(s) && PJ_SCAN_IS_SPACE(*s));
|
||||
} while (PJ_SCAN_IS_SPACE(*s));
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (PJ_SCAN_CHECK_EOF(s) && PJ_SCAN_IS_NEWLINE(*s) &&
|
||||
(scanner->skip_ws & PJ_SCAN_AUTOSKIP_WS_HEADER)==
|
||||
PJ_SCAN_AUTOSKIP_WS_HEADER)
|
||||
{
|
||||
if (PJ_SCAN_IS_NEWLINE(*s) && (scanner->skip_ws & PJ_SCAN_AUTOSKIP_WS_HEADER)==PJ_SCAN_AUTOSKIP_WS_HEADER) {
|
||||
/* Check for header continuation. */
|
||||
scanner->curptr = s;
|
||||
|
||||
if (*s == '\r') {
|
||||
++s;
|
||||
}
|
||||
if (PJ_SCAN_CHECK_EOF(s) && *s == '\n') {
|
||||
if (*s == '\n') {
|
||||
++s;
|
||||
}
|
||||
scanner->start_line = s;
|
||||
|
||||
if (PJ_SCAN_CHECK_EOF(s) && PJ_SCAN_IS_SPACE(*s)) {
|
||||
if (PJ_SCAN_IS_SPACE(*s)) {
|
||||
register char *t = s;
|
||||
do {
|
||||
++t;
|
||||
} while (PJ_SCAN_CHECK_EOF(t) && PJ_SCAN_IS_SPACE(*t));
|
||||
} while (PJ_SCAN_IS_SPACE(*t));
|
||||
|
||||
++scanner->line;
|
||||
scanner->curptr = t;
|
||||
|
@ -226,7 +220,8 @@ PJ_DEF(int) pj_scan_peek( pj_scanner *scanner,
|
|||
return -1;
|
||||
}
|
||||
|
||||
while (PJ_SCAN_CHECK_EOF(s) && pj_cis_match(spec, *s))
|
||||
/* Don't need to check EOF with PJ_SCAN_CHECK_EOF(s) */
|
||||
while (pj_cis_match(spec, *s))
|
||||
++s;
|
||||
|
||||
pj_strset3(out, scanner->curptr, s);
|
||||
|
@ -282,15 +277,17 @@ PJ_DEF(void) pj_scan_get( pj_scanner *scanner,
|
|||
|
||||
do {
|
||||
++s;
|
||||
} while (PJ_SCAN_CHECK_EOF(s) && pj_cis_match(spec, *s));
|
||||
} while (pj_cis_match(spec, *s));
|
||||
/* No need to check EOF here (PJ_SCAN_CHECK_EOF(s)) because
|
||||
* buffer is NULL terminated and pj_cis_match(spec,0) should be
|
||||
* false.
|
||||
*/
|
||||
|
||||
pj_strset3(out, scanner->curptr, s);
|
||||
|
||||
scanner->curptr = s;
|
||||
|
||||
if (!pj_scan_is_eof(scanner) &&
|
||||
PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws)
|
||||
{
|
||||
if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
|
||||
pj_scan_skip_whitespace(scanner);
|
||||
}
|
||||
}
|
||||
|
@ -333,20 +330,18 @@ PJ_DEF(void) pj_scan_get_unescape( pj_scanner *scanner,
|
|||
char *start = s;
|
||||
do {
|
||||
++s;
|
||||
} while (PJ_SCAN_CHECK_EOF(s) && pj_cis_match(spec, *s));
|
||||
} while (pj_cis_match(spec, *s));
|
||||
|
||||
if (dst != start) pj_memmove(dst, start, s-start);
|
||||
dst += (s-start);
|
||||
}
|
||||
|
||||
} while (PJ_SCAN_CHECK_EOF(s) && (*s == '%'));
|
||||
} while (*s == '%');
|
||||
|
||||
scanner->curptr = s;
|
||||
out->slen = (dst - out->ptr);
|
||||
|
||||
if (!pj_scan_is_eof(scanner) &&
|
||||
PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws)
|
||||
{
|
||||
if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
|
||||
pj_scan_skip_whitespace(scanner);
|
||||
}
|
||||
}
|
||||
|
@ -427,9 +422,7 @@ PJ_DEF(void) pj_scan_get_quotes(pj_scanner *scanner,
|
|||
|
||||
scanner->curptr = s;
|
||||
|
||||
if (!pj_scan_is_eof(scanner) &&
|
||||
PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws)
|
||||
{
|
||||
if (PJ_SCAN_IS_PROBABLY_SPACE(*s) && scanner->skip_ws) {
|
||||
pj_scan_skip_whitespace(scanner);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -76,8 +76,7 @@ PJ_DEF(pj_status_t) pjstun_parse_msg( void *buf, pj_size_t buf_len,
|
|||
msg_len = pj_ntohs(msg->hdr->length);
|
||||
if (msg_len != buf_len - sizeof(pjstun_msg_hdr)) {
|
||||
PJ_LOG(4,(THIS_FILE, "Error: invalid msg_len %d (expecting %lu)",
|
||||
msg_len, (unsigned long)
|
||||
(buf_len - sizeof(pjstun_msg_hdr))));
|
||||
msg_len, buf_len - sizeof(pjstun_msg_hdr)));
|
||||
return PJLIB_UTIL_ESTUNINMSGLEN;
|
||||
}
|
||||
|
||||
|
|
|
@ -345,9 +345,8 @@ PJ_DEF(pj_status_t) pjstun_get_mapped_addr2(pj_pool_factory *pf,
|
|||
}
|
||||
}
|
||||
|
||||
TRACE_((THIS_FILE, " Pool usage=%lu of %lu",
|
||||
(unsigned long)pj_pool_get_used_size(pool),
|
||||
(unsigned long)pj_pool_get_capacity(pool)));
|
||||
TRACE_((THIS_FILE, " Pool usage=%d of %d", pj_pool_get_used_size(pool),
|
||||
pj_pool_get_capacity(pool)));
|
||||
|
||||
pj_pool_release(pool);
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug-Dynamic|ARM">
|
||||
|
@ -998,7 +998,6 @@
|
|||
</ClCompile>
|
||||
<ClCompile Include="..\src\pj\ssl_sock_ossl.c" />
|
||||
<ClCompile Include="..\src\pj\ssl_sock_gtls.c" />
|
||||
<ClCompile Include="..\src\pj\ssl_sock_schannel.c" />
|
||||
<ClCompile Include="..\src\pj\string.c" />
|
||||
<ClCompile Include="..\src\pj\symbols.c">
|
||||
<ExcludedFromBuild Condition="'$(Configuration)|$(Platform)'=='Debug-Dynamic|Win32'">true</ExcludedFromBuild>
|
||||
|
|
|
@ -260,10 +260,7 @@ GENERATE_DEPRECATEDLIST= YES
|
|||
|
||||
ALIASES =
|
||||
ALIASES += src{1}="\verbatim embed:rst:inline :source:`\1` \endverbatim"
|
||||
ALIASES += srcdir{1}="\verbatim embed:rst:inline :sourcedir:`\1` \endverbatim"
|
||||
ALIASES += img{1}="<img src=\"https://raw.githubusercontent.com/pjsip/pjproject/master/\1\" />"
|
||||
ALIASES += img{2}="<img src=\"https://raw.githubusercontent.com/pjsip/pjproject/master/\1\" alt=\"\2\" />"
|
||||
|
||||
|
||||
# The ENABLED_SECTIONS tag can be used to enable conditional
|
||||
# documentation sections, marked by \if sectionname ... \endif.
|
||||
|
||||
|
|
|
@ -1077,9 +1077,6 @@
|
|||
/** Using Apple's Network framework */
|
||||
#define PJ_SSL_SOCK_IMP_APPLE 4
|
||||
|
||||
/** Using Windows's Schannel */
|
||||
#define PJ_SSL_SOCK_IMP_SCHANNEL 5
|
||||
|
||||
/**
|
||||
* Select which SSL socket implementation to use. Currently pjlib supports
|
||||
* PJ_SSL_SOCK_IMP_OPENSSL, which uses OpenSSL, and PJ_SSL_SOCK_IMP_GNUTLS,
|
||||
|
@ -1496,7 +1493,7 @@ PJ_BEGIN_DECL
|
|||
#define PJ_VERSION_NUM_MAJOR 2
|
||||
|
||||
/** PJLIB version minor number. */
|
||||
#define PJ_VERSION_NUM_MINOR 14
|
||||
#define PJ_VERSION_NUM_MINOR 13
|
||||
|
||||
/** PJLIB version revision number. */
|
||||
#define PJ_VERSION_NUM_REV 0
|
||||
|
|
|
@ -40,8 +40,8 @@ PJ_BEGIN_DECL
|
|||
* \section pj_except_sample_sec Quick Example
|
||||
*
|
||||
* For the impatient, take a look at some examples:
|
||||
* - Exception Handling sample: \src{pjlib/src/pjlib-samples/except.c}
|
||||
* - Exception Handling test: \src{pjlib/src/pjlib-test/exception.c}
|
||||
* - @ref page_pjlib_samples_except_c
|
||||
* - @ref page_pjlib_exception_test
|
||||
*
|
||||
* \section pj_except_except Exception Handling
|
||||
*
|
||||
|
@ -217,8 +217,8 @@ PJ_BEGIN_DECL
|
|||
* \section pj_except_examples_sec Examples
|
||||
*
|
||||
* For some examples on how to use the exception construct, please see:
|
||||
* - Exception Handling sample: \src{pjlib/src/pjlib-samples/except.c}
|
||||
* - Exception Handling test: \src{pjlib/src/pjlib-test/exception.c}
|
||||
* - @ref page_pjlib_samples_except_c
|
||||
* - @ref page_pjlib_exception_test
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
@ -47,8 +47,8 @@ PJ_BEGIN_DECL
|
|||
* \section pj_list_example_sec Examples
|
||||
*
|
||||
* See below for examples on how to manipulate linked list:
|
||||
* - List sample: \src{pjlib/src/pjlib-samples/list.c}
|
||||
* - List test: \src{pjlib/src/pjlib-test/list.c}
|
||||
* - @ref page_pjlib_samples_list_c
|
||||
* - @ref page_pjlib_list_test
|
||||
*/
|
||||
|
||||
|
||||
|
@ -170,27 +170,6 @@ PJ_IDECL(void) pj_list_insert_nodes_after(pj_list_type *lst,
|
|||
pj_list_type *nodes);
|
||||
|
||||
|
||||
/**
|
||||
* Insert a list to another list before the specified element position.
|
||||
*
|
||||
* @param pos The element to which the node will be inserted before.
|
||||
* @param lst The list to be inserted.
|
||||
*/
|
||||
PJ_IDECL(void) pj_list_insert_list_before(pj_list_type *pos,
|
||||
pj_list_type *lst);
|
||||
|
||||
|
||||
/**
|
||||
* Insert a list to another list after the specified element position.
|
||||
*
|
||||
* @param pos The element in the list which will precede the inserted
|
||||
* list.
|
||||
* @param lst The list to be inserted.
|
||||
*/
|
||||
PJ_IDECL(void) pj_list_insert_list_after(pj_list_type *pos,
|
||||
pj_list_type *lst);
|
||||
|
||||
|
||||
/**
|
||||
* Remove elements from the source list, and insert them to the destination
|
||||
* list. The elements of the source list will occupy the
|
||||
|
|
|
@ -54,23 +54,6 @@ PJ_IDEF(void) pj_list_insert_nodes_before(pj_list_type *pos, pj_list_type *lst)
|
|||
pj_list_insert_nodes_after(((pj_list*)pos)->prev, lst);
|
||||
}
|
||||
|
||||
PJ_IDEF(void) pj_list_insert_list_after(pj_list_type *pos, pj_list_type *lst)
|
||||
{
|
||||
if (!pj_list_empty(lst)) {
|
||||
pj_list *lst_last = (pj_list *) ((pj_list*)lst)->prev;
|
||||
pj_list *pos_next = (pj_list *) ((pj_list*)pos)->next;
|
||||
|
||||
pj_link_node(pos, (pj_list *) ((pj_list*)lst)->next);
|
||||
pj_link_node(lst_last, pos_next);
|
||||
pj_list_init(lst);
|
||||
}
|
||||
}
|
||||
|
||||
PJ_IDEF(void) pj_list_insert_list_before(pj_list_type *pos, pj_list_type *lst)
|
||||
{
|
||||
pj_list_insert_list_after(((pj_list*)pos)->prev, lst);
|
||||
}
|
||||
|
||||
PJ_IDEF(void) pj_list_merge_last(pj_list_type *lst1, pj_list_type *lst2)
|
||||
{
|
||||
if (!pj_list_empty(lst2)) {
|
||||
|
|
|
@ -59,7 +59,7 @@ PJ_BEGIN_DECL
|
|||
* \section pj_log_quick_sample_sec Examples
|
||||
*
|
||||
* For examples, see:
|
||||
* - Simple Log sample: \src{pjlib/src/pjlib-samples/log.c}
|
||||
* - @ref page_pjlib_samples_log_c.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
|
@ -608,7 +608,7 @@ PJ_DECL(void*) pj_thread_local_get(long index);
|
|||
* \section pj_atomic_examples_sec Examples
|
||||
*
|
||||
* For some example codes, please see:
|
||||
* - Atomic Variable test: \src{pjlib/src/pjlib-test/atomic.c}
|
||||
* - @ref page_pjlib_atomic_test
|
||||
*/
|
||||
|
||||
|
||||
|
|
|
@ -276,7 +276,7 @@ PJ_BEGIN_DECL
|
|||
* \section PJ_POOL_EXAMPLES_SEC Examples
|
||||
*
|
||||
* For some sample codes on how to use the pool, please see:
|
||||
* - Pool test: \src{pjlib/src/pjlib-test/pool.c}
|
||||
* - @ref page_pjlib_pool_test
|
||||
*
|
||||
* @{
|
||||
*/
|
||||
|
@ -849,16 +849,12 @@ struct pj_caching_pool
|
|||
|
||||
/**
|
||||
* Total size of memory currently used by application.
|
||||
*
|
||||
* This field is deprecated.
|
||||
*/
|
||||
pj_size_t used_size;
|
||||
|
||||
/**
|
||||
* The maximum size of memory used by application throughout the life
|
||||
* of the caching pool.
|
||||
*
|
||||
* This field is deprecated.
|
||||
*/
|
||||
pj_size_t peak_used_size;
|
||||
|
||||
|
|
|
@ -117,11 +117,6 @@ typedef enum pj_ssl_cert_verify_flag_t
|
|||
*/
|
||||
PJ_SSL_CERT_ECHAIN_TOO_LONG = (1 << 8),
|
||||
|
||||
/**
|
||||
* The certificate signature is created using a weak hashing algorithm.
|
||||
*/
|
||||
PJ_SSL_CERT_EWEAK_SIGNATURE = (1 << 9),
|
||||
|
||||
/**
|
||||
* The server identity does not match to any identities specified in
|
||||
* the certificate, e.g: subjectAltName extension, subject common name.
|
||||
|
@ -150,59 +145,6 @@ typedef enum pj_ssl_cert_name_type
|
|||
PJ_SSL_CERT_NAME_IP
|
||||
} pj_ssl_cert_name_type;
|
||||
|
||||
/**
|
||||
* Field type for looking up SSL certificate in the certificate stores.
|
||||
*/
|
||||
typedef enum pj_ssl_cert_lookup_type
|
||||
{
|
||||
/**
|
||||
* No certificate to be looked up.
|
||||
*/
|
||||
PJ_SSL_CERT_LOOKUP_NONE,
|
||||
|
||||
/**
|
||||
* Lookup by subject, this will lookup any first certificate whose
|
||||
* subject containing the specified keyword. Note that subject may not
|
||||
* be unique in the store, so the lookup may end up selecting a wrong
|
||||
* certificate.
|
||||
*/
|
||||
PJ_SSL_CERT_LOOKUP_SUBJECT,
|
||||
|
||||
/**
|
||||
* Lookup by fingerprint/thumbprint (SHA1 hash), this will lookup
|
||||
* any first certificate whose fingerprint matching the specified
|
||||
* keyword. The keyword is an array of hash octets.
|
||||
*/
|
||||
PJ_SSL_CERT_LOOKUP_FINGERPRINT,
|
||||
|
||||
/**
|
||||
* Lookup by friendly name, this will lookup any first certificate
|
||||
* whose friendly name containing the specified keyword. Note that
|
||||
* friendly name may not be unique in the store, so the lookup may end up
|
||||
* selecting a wrong certificate.
|
||||
*/
|
||||
PJ_SSL_CERT_LOOKUP_FRIENDLY_NAME
|
||||
|
||||
} pj_ssl_cert_lookup_type;
|
||||
|
||||
/**
|
||||
* Describe structure of certificate lookup criteria.
|
||||
*/
|
||||
typedef struct pj_ssl_cert_lookup_criteria
|
||||
{
|
||||
/**
|
||||
* Certificate field type to look.
|
||||
*/
|
||||
pj_ssl_cert_lookup_type type;
|
||||
|
||||
/*
|
||||
* Keyword to match on the field specified in \a type.
|
||||
*/
|
||||
pj_str_t keyword;
|
||||
|
||||
} pj_ssl_cert_lookup_criteria;
|
||||
|
||||
|
||||
/**
|
||||
* Describe structure of certificate info.
|
||||
*/
|
||||
|
@ -331,30 +273,6 @@ PJ_DECL(pj_status_t) pj_ssl_cert_load_from_buffer(pj_pool_t *pool,
|
|||
const pj_str_t *privkey_pass,
|
||||
pj_ssl_cert_t **p_cert);
|
||||
|
||||
/**
|
||||
* Create credential from OS certificate store, this function will lookup
|
||||
* certificate using the specified criterias.
|
||||
*
|
||||
* Currently this is used by Windows Schannel backend only, it will lookup
|
||||
* in the Current User store first, if no certificate with the specified
|
||||
* criteria is not found, it will lookup in the Local Machine store.
|
||||
*
|
||||
* Note that for manual verification (e.g: when pj_ssl_sock_param.verify_peer
|
||||
* is disabled), the backend will provide pre-verification result against
|
||||
* trusted CA certificates in Current User store only (will not check CA
|
||||
* certificates in the Local Machine store).
|
||||
*
|
||||
* @param pool The pool.
|
||||
* @param criteria The lookup criteria.
|
||||
* @param p_cert Pointer to credential instance to be created.
|
||||
*
|
||||
* @return PJ_SUCCESS when successful.
|
||||
*/
|
||||
PJ_DECL(pj_status_t) pj_ssl_cert_load_from_store(
|
||||
pj_pool_t *pool,
|
||||
const pj_ssl_cert_lookup_criteria *criteria,
|
||||
pj_ssl_cert_t **p_cert);
|
||||
|
||||
/**
|
||||
* Dump SSL certificate info.
|
||||
*
|
||||
|
@ -1160,8 +1078,7 @@ typedef struct pj_ssl_sock_param
|
|||
/**
|
||||
* Specify options to be set on the transport.
|
||||
*
|
||||
* For GnuTLS backend, by default TCP_NODELAY will be set. For other
|
||||
* SSL backends, the default is no options.
|
||||
* By default there is no options.
|
||||
*
|
||||
*/
|
||||
pj_sockopt_params sockopt_params;
|
||||
|
|
|
@ -65,7 +65,7 @@ PJ_BEGIN_DECL
|
|||
* \section pj_pstr_examples_sec Examples
|
||||
*
|
||||
* For some examples, please see:
|
||||
* - String test: \src{pjlib/src/pjlib-test/string.c}
|
||||
* - @ref page_pjlib_string_test
|
||||
*/
|
||||
|
||||
/**
|
||||
|
|
|
@ -143,9 +143,6 @@ static void activesock_destroy_iphone_os_stream(pj_activesock_t *asock)
|
|||
|
||||
static void activesock_create_iphone_os_stream(pj_activesock_t *asock)
|
||||
{
|
||||
#if (defined(__IPHONE_OS_VERSION_MIN_REQUIRED) && \
|
||||
__IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_9_0)
|
||||
|
||||
if (ios_bg_support && asock->bg_setting && asock->stream_oriented) {
|
||||
activesock_destroy_iphone_os_stream(asock);
|
||||
|
||||
|
@ -167,8 +164,6 @@ static void activesock_create_iphone_os_stream(pj_activesock_t *asock)
|
|||
activesock_destroy_iphone_os_stream(asock);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -513,8 +508,7 @@ static void ioqueue_on_read_complete(pj_ioqueue_key_t *key,
|
|||
ret = (*asock->cb.on_data_read)(asock, r->pkt, r->size,
|
||||
PJ_SUCCESS, &remainder);
|
||||
PJ_ASSERT_ON_FAIL(
|
||||
!ret || !asock->stream_oriented || remainder <= r->size,
|
||||
{
|
||||
!asock->stream_oriented || remainder <= r->size, {
|
||||
PJ_LOG(2, ("",
|
||||
"App bug! Invalid remainder length from "
|
||||
"activesock on_data_read()."));
|
||||
|
@ -590,8 +584,7 @@ static void ioqueue_on_read_complete(pj_ioqueue_key_t *key,
|
|||
ret = (*asock->cb.on_data_read)(asock, r->pkt, r->size,
|
||||
status, &remainder);
|
||||
PJ_ASSERT_ON_FAIL(
|
||||
!ret || !asock->stream_oriented || remainder <= r->size,
|
||||
{
|
||||
!asock->stream_oriented || remainder <= r->size, {
|
||||
PJ_LOG(2, ("",
|
||||
"App bug! Invalid remainder length from "
|
||||
"activesock on_data_read()."));
|
||||
|
|
|
@ -187,9 +187,9 @@ static pj_hash_entry **find_entry( pj_pool_t *pool, pj_hash_table_t *ht,
|
|||
|
||||
entry = PJ_POOL_ALLOC_T(pool, pj_hash_entry);
|
||||
PJ_LOG(6, ("hashtbl",
|
||||
"%p: New p_entry %p created, pool used=%lu, cap=%lu",
|
||||
ht, entry, (unsigned long)pj_pool_get_used_size(pool),
|
||||
(unsigned long)pj_pool_get_capacity(pool)));
|
||||
"%p: New p_entry %p created, pool used=%u, cap=%u",
|
||||
ht, entry, pj_pool_get_used_size(pool),
|
||||
pj_pool_get_capacity(pool)));
|
||||
}
|
||||
entry->next = NULL;
|
||||
entry->hash = hash;
|
||||
|
|
|
@ -345,7 +345,7 @@ pj_bool_t ioqueue_dispatch_write_event( pj_ioqueue_t *ioqueue,
|
|||
h->fd_type==pj_SOCK_DGRAM())
|
||||
{
|
||||
PJ_PERROR(4,(THIS_FILE, send_rc,
|
||||
"Send error for socket %ld, retrying",
|
||||
"Send error for socket %d, retrying",
|
||||
h->fd));
|
||||
send_rc = replace_udp_sock(h);
|
||||
continue;
|
||||
|
@ -1037,7 +1037,7 @@ retry_on_restart:
|
|||
{
|
||||
if (!restart_retry) {
|
||||
PJ_PERROR(4, (THIS_FILE, status,
|
||||
"Send error for socket %ld, retrying",
|
||||
"Send error for socket %d, retrying",
|
||||
key->fd));
|
||||
status = replace_udp_sock(key);
|
||||
if (status == PJ_SUCCESS) {
|
||||
|
@ -1056,7 +1056,7 @@ retry_on_restart:
|
|||
/*
|
||||
* Check that address storage can hold the address parameter.
|
||||
*/
|
||||
PJ_ASSERT_RETURN(addrlen <= (int)sizeof(pj_sockaddr), PJ_EBUG);
|
||||
PJ_ASSERT_RETURN(addrlen <= (int)sizeof(pj_sockaddr_in), PJ_EBUG);
|
||||
|
||||
/*
|
||||
* Schedule asynchronous send.
|
||||
|
|
|
@ -63,7 +63,7 @@ struct write_operation
|
|||
pj_size_t size;
|
||||
pj_ssize_t written;
|
||||
unsigned flags;
|
||||
pj_sockaddr rmt_addr;
|
||||
pj_sockaddr_in rmt_addr;
|
||||
int rmt_addrlen;
|
||||
};
|
||||
|
||||
|
|
|
@ -769,12 +769,12 @@ static pj_status_t replace_udp_sock(pj_ioqueue_key_t *h)
|
|||
/* Can only replace UDP socket */
|
||||
pj_assert(h->fd_type == pj_SOCK_DGRAM());
|
||||
|
||||
PJ_LOG(4,(THIS_FILE, "Attempting to replace UDP socket %ld", old_sock));
|
||||
PJ_LOG(4,(THIS_FILE, "Attempting to replace UDP socket %d", old_sock));
|
||||
|
||||
for (msec=20; (msec<1000 && status != PJ_SUCCESS); msec=msec*2)
|
||||
{
|
||||
if (msec > 20) {
|
||||
PJ_LOG(4,(THIS_FILE, "Retry to replace UDP socket %ld", h->fd));
|
||||
PJ_LOG(4,(THIS_FILE, "Retry to replace UDP socket %d", h->fd));
|
||||
pj_thread_sleep(msec);
|
||||
}
|
||||
|
||||
|
@ -920,7 +920,7 @@ on_error:
|
|||
}
|
||||
|
||||
h->fd = PJ_INVALID_SOCKET;
|
||||
PJ_PERROR(1,(THIS_FILE, status, "Error replacing socket %ld", old_sock));
|
||||
PJ_PERROR(1,(THIS_FILE, status, "Error replacing socket %d", old_sock));
|
||||
pj_lock_release(h->ioqueue->lock);
|
||||
return PJ_ESOCKETSTOP;
|
||||
}
|
||||
|
|
|
@ -495,7 +495,6 @@ PJ_DEF(pj_status_t) pj_ioqueue_destroy( pj_ioqueue_t *ioqueue )
|
|||
}
|
||||
#endif
|
||||
|
||||
pj_lock_release(ioqueue->lock);
|
||||
if (ioqueue->auto_delete_lock)
|
||||
pj_lock_destroy(ioqueue->lock);
|
||||
|
||||
|
|
|
@ -91,7 +91,6 @@ PJ_DEF(int) pj_run_app(pj_main_func_ptr main_func, int argc, char *argv[],
|
|||
param.main_func = main_func;
|
||||
if (pthread_create(&thread, NULL, &main_thread, ¶m) == 0) {
|
||||
CFRunLoopRun();
|
||||
pthread_join(thread, NULL);
|
||||
}
|
||||
|
||||
PJ_UNUSED_ARG(pool);
|
||||
|
|
|
@ -52,9 +52,8 @@ static pj_pool_block *pj_pool_create_block( pj_pool_t *pool, pj_size_t size)
|
|||
PJ_CHECK_STACK();
|
||||
pj_assert(size >= sizeof(pj_pool_block));
|
||||
|
||||
LOG((pool->obj_name, "create_block(sz=%lu), cur.cap=%lu, cur.used=%lu",
|
||||
(unsigned long)size, (unsigned long)pool->capacity,
|
||||
(unsigned long)pj_pool_get_used_size(pool)));
|
||||
LOG((pool->obj_name, "create_block(sz=%u), cur.cap=%u, cur.used=%u",
|
||||
size, pool->capacity, pj_pool_get_used_size(pool)));
|
||||
|
||||
/* Request memory from allocator. */
|
||||
block = (pj_pool_block*)
|
||||
|
@ -117,10 +116,9 @@ PJ_DEF(void*) pj_pool_allocate_find(pj_pool_t *pool, pj_size_t size)
|
|||
|
||||
/* If pool is configured NOT to expand, return error. */
|
||||
if (pool->increment_size == 0) {
|
||||
LOG((pool->obj_name, "Can't expand pool to allocate %lu bytes "
|
||||
"(used=%lu, cap=%lu)",
|
||||
(unsigned long)size, (unsigned long)pj_pool_get_used_size(pool),
|
||||
(unsigned long)pool->capacity));
|
||||
LOG((pool->obj_name, "Can't expand pool to allocate %u bytes "
|
||||
"(used=%u, cap=%u)",
|
||||
size, pj_pool_get_used_size(pool), pool->capacity));
|
||||
(*pool->callback)(pool, size);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -144,10 +142,8 @@ PJ_DEF(void*) pj_pool_allocate_find(pj_pool_t *pool, pj_size_t size)
|
|||
}
|
||||
|
||||
LOG((pool->obj_name,
|
||||
"%lu bytes requested, resizing pool by %lu bytes (used=%lu, cap=%lu)",
|
||||
(unsigned long)size, (unsigned long)block_size,
|
||||
(unsigned long)pj_pool_get_used_size(pool),
|
||||
(unsigned long)pool->capacity));
|
||||
"%u bytes requested, resizing pool by %u bytes (used=%u, cap=%u)",
|
||||
size, block_size, pj_pool_get_used_size(pool), pool->capacity));
|
||||
|
||||
block = pj_pool_create_block(pool, block_size);
|
||||
if (!block)
|
||||
|
@ -237,8 +233,7 @@ PJ_DEF(pj_pool_t*) pj_pool_create_int( pj_pool_factory *f, const char *name,
|
|||
/* Pool initial capacity and used size */
|
||||
pool->capacity = initial_size;
|
||||
|
||||
LOG((pool->obj_name, "pool created, size=%lu",
|
||||
(unsigned long)pool->capacity));
|
||||
LOG((pool->obj_name, "pool created, size=%u", pool->capacity));
|
||||
return pool;
|
||||
}
|
||||
|
||||
|
@ -283,10 +278,9 @@ static void reset_pool(pj_pool_t *pool)
|
|||
*/
|
||||
PJ_DEF(void) pj_pool_reset(pj_pool_t *pool)
|
||||
{
|
||||
LOG((pool->obj_name, "reset(): cap=%lu, used=%lu(%lu%%)",
|
||||
(unsigned long)pool->capacity,
|
||||
(unsigned long)pj_pool_get_used_size(pool),
|
||||
(unsigned long)(pj_pool_get_used_size(pool)*100/pool->capacity)));
|
||||
LOG((pool->obj_name, "reset(): cap=%d, used=%d(%d%%)",
|
||||
pool->capacity, pj_pool_get_used_size(pool),
|
||||
pj_pool_get_used_size(pool)*100/pool->capacity));
|
||||
|
||||
reset_pool(pool);
|
||||
}
|
||||
|
@ -298,10 +292,9 @@ PJ_DEF(void) pj_pool_destroy_int(pj_pool_t *pool)
|
|||
{
|
||||
pj_size_t initial_size;
|
||||
|
||||
LOG((pool->obj_name, "destroy(): cap=%lu, used=%lu(%lu%%), block0=%p-%p",
|
||||
(unsigned long)pool->capacity,
|
||||
(unsigned long)pj_pool_get_used_size(pool),
|
||||
(unsigned long)(pj_pool_get_used_size(pool)*100/pool->capacity),
|
||||
LOG((pool->obj_name, "destroy(): cap=%d, used=%d(%d%%), block0=%p-%p",
|
||||
pool->capacity, pj_pool_get_used_size(pool),
|
||||
pj_pool_get_used_size(pool)*100/pool->capacity,
|
||||
((pj_pool_block*)pool->block_list.next)->buf,
|
||||
((pj_pool_block*)pool->block_list.next)->end));
|
||||
|
||||
|
|
|
@ -75,12 +75,8 @@ PJ_DEF(void) pj_caching_pool_init( pj_caching_pool *cp,
|
|||
cp->factory.create_pool = &cpool_create_pool;
|
||||
cp->factory.release_pool = &cpool_release_pool;
|
||||
cp->factory.dump_status = &cpool_dump_status;
|
||||
|
||||
/* Deprecated, these callbacks are only used for updating cp.used_size &
|
||||
* cp.peak_used_size which are no longer used.
|
||||
*/
|
||||
//cp->factory.on_block_alloc = &cpool_on_block_alloc;
|
||||
//cp->factory.on_block_free = &cpool_on_block_free;
|
||||
cp->factory.on_block_alloc = &cpool_on_block_alloc;
|
||||
cp->factory.on_block_free = &cpool_on_block_free;
|
||||
|
||||
pool = pj_pool_create_on_buf("cachingpool", cp->pool_buf, sizeof(cp->pool_buf));
|
||||
status = pj_lock_create_simple_mutex(pool, "cachingpool", &cp->lock);
|
||||
|
@ -192,8 +188,7 @@ static pj_pool_t* cpool_create_pool(pj_pool_factory *pf,
|
|||
cp->capacity = 0;
|
||||
}
|
||||
|
||||
PJ_LOG(6, (pool->obj_name, "pool reused, size=%lu",
|
||||
(unsigned long)pool->capacity));
|
||||
PJ_LOG(6, (pool->obj_name, "pool reused, size=%u", pool->capacity));
|
||||
}
|
||||
|
||||
/* Put in used list. */
|
||||
|
@ -224,7 +219,6 @@ static void cpool_release_pool( pj_pool_factory *pf, pj_pool_t *pool)
|
|||
#if PJ_SAFE_POOL
|
||||
/* Make sure pool is still in our used list */
|
||||
if (pj_list_find_node(&cp->used_list, pool) != pool) {
|
||||
pj_lock_release(cp->lock);
|
||||
pj_assert(!"Attempt to destroy pool that has been destroyed before");
|
||||
return;
|
||||
}
|
||||
|
@ -251,11 +245,9 @@ static void cpool_release_pool( pj_pool_factory *pf, pj_pool_t *pool)
|
|||
}
|
||||
|
||||
/* Reset pool. */
|
||||
PJ_LOG(6, (pool->obj_name, "recycle(): cap=%lu, used=%lu(%lu%%)",
|
||||
(unsigned long)pool_capacity,
|
||||
(unsigned long)pj_pool_get_used_size(pool),
|
||||
(unsigned long)(pj_pool_get_used_size(pool)*100/
|
||||
pool_capacity)));
|
||||
PJ_LOG(6, (pool->obj_name, "recycle(): cap=%d, used=%d(%d%%)",
|
||||
pool_capacity, pj_pool_get_used_size(pool),
|
||||
pj_pool_get_used_size(pool)*100/pool_capacity));
|
||||
pj_pool_reset(pool);
|
||||
|
||||
pool_capacity = pj_pool_get_capacity(pool);
|
||||
|
@ -287,9 +279,8 @@ static void cpool_dump_status(pj_pool_factory *factory, pj_bool_t detail )
|
|||
pj_lock_acquire(cp->lock);
|
||||
|
||||
PJ_LOG(3,("cachpool", " Dumping caching pool:"));
|
||||
PJ_LOG(3,("cachpool", " Capacity=%lu, max_capacity=%lu, used_cnt=%lu",
|
||||
(unsigned long)cp->capacity, (unsigned long)cp->max_capacity,
|
||||
(unsigned long)cp->used_count));
|
||||
PJ_LOG(3,("cachpool", " Capacity=%lu, max_capacity=%lu, used_cnt=%lu", \
|
||||
cp->capacity, cp->max_capacity, cp->used_count));
|
||||
if (detail) {
|
||||
pj_pool_t *pool = (pj_pool_t*) cp->used_list.next;
|
||||
pj_size_t total_used = 0, total_capacity = 0;
|
||||
|
@ -303,7 +294,7 @@ static void cpool_dump_status(pj_pool_factory *factory, pj_bool_t detail )
|
|||
#if 0
|
||||
PJ_LOG(6, ("cachpool", " %16s block %u, size %ld",
|
||||
pj_pool_getobjname(pool), nblocks,
|
||||
(long)(block->end - block->buf + 1)));
|
||||
block->end - block->buf + 1));
|
||||
#endif
|
||||
nblocks++;
|
||||
block = block->next;
|
||||
|
@ -312,10 +303,9 @@ static void cpool_dump_status(pj_pool_factory *factory, pj_bool_t detail )
|
|||
PJ_LOG(3,("cachpool", " %16s: %8lu of %8lu (%lu%%) used, "
|
||||
"nblocks: %d",
|
||||
pj_pool_getobjname(pool),
|
||||
(unsigned long)pj_pool_get_used_size(pool),
|
||||
(unsigned long)pool_capacity,
|
||||
(unsigned long)(pj_pool_get_used_size(pool)*
|
||||
100/pool_capacity),
|
||||
pj_pool_get_used_size(pool),
|
||||
pool_capacity,
|
||||
pj_pool_get_used_size(pool)*100/pool_capacity,
|
||||
nblocks));
|
||||
|
||||
#if PJ_POOL_MAX_SEARCH_BLOCK_COUNT == 0
|
||||
|
@ -333,10 +323,8 @@ static void cpool_dump_status(pj_pool_factory *factory, pj_bool_t detail )
|
|||
}
|
||||
if (total_capacity) {
|
||||
PJ_LOG(3,("cachpool", " Total %9lu of %9lu (%lu %%) used!",
|
||||
(unsigned long)total_used,
|
||||
(unsigned long)total_capacity,
|
||||
(unsigned long)(total_used * 100 /
|
||||
total_capacity)));
|
||||
total_used, total_capacity,
|
||||
total_used * 100 / total_capacity));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -735,11 +735,6 @@ PJ_DEF(pj_status_t) pj_sock_sendto(pj_sock_t sock,
|
|||
|
||||
CHECK_ADDR_LEN(to, tolen);
|
||||
|
||||
#ifdef MSG_NOSIGNAL
|
||||
/* Suppress SIGPIPE. See https://github.com/pjsip/pjproject/issues/1538 */
|
||||
flags |= MSG_NOSIGNAL;
|
||||
#endif
|
||||
|
||||
*len = sendto(sock, (const char*)buf, (int)(*len), flags,
|
||||
(const struct sockaddr*)to, tolen);
|
||||
|
||||
|
|
|
@ -34,21 +34,9 @@ PJ_DEF(void) pj_ssl_sock_param_default(pj_ssl_sock_param *param)
|
|||
param->async_cnt = 1;
|
||||
param->concurrency = -1;
|
||||
param->whole_data = PJ_TRUE;
|
||||
|
||||
#if (PJ_SSL_SOCK_IMP == PJ_SSL_SOCK_IMP_GNUTLS)
|
||||
/* GnuTLS is allowed to send bigger chunks.*/
|
||||
param->send_buffer_size = 65536;
|
||||
|
||||
{
|
||||
/* For GnuTLS, TCP_NODELAY is needed to avoid polling delay. */
|
||||
static pj_int32_t val = 1;
|
||||
param->sockopt_params.cnt = 1;
|
||||
param->sockopt_params.options[0].level = pj_SOL_TCP();
|
||||
param->sockopt_params.options[0].optname = pj_TCP_NODELAY();
|
||||
param->sockopt_params.options[0].optval = &val;
|
||||
param->sockopt_params.options[0].optlen = sizeof(pj_int32_t);
|
||||
}
|
||||
|
||||
#else
|
||||
param->send_buffer_size = 8192;
|
||||
#endif
|
||||
|
@ -173,10 +161,6 @@ PJ_DEF(pj_status_t) pj_ssl_cert_get_verify_status_strings(
|
|||
case PJ_SSL_CERT_ECHAIN_TOO_LONG:
|
||||
p = "The certificate chain length is too long";
|
||||
break;
|
||||
case PJ_SSL_CERT_EWEAK_SIGNATURE:
|
||||
p = "The certificate signature is created using a weak hashing "
|
||||
"algorithm";
|
||||
break;
|
||||
case PJ_SSL_CERT_EIDENTITY_NOT_MATCH:
|
||||
p = "The server identity does not match to any identities "
|
||||
"specified in the certificate";
|
||||
|
|
|
@ -52,22 +52,9 @@ static pj_bool_t asock_on_data_sent (pj_activesock_t *asock,
|
|||
*******************************************************************
|
||||
*/
|
||||
|
||||
static pj_size_t next_pow2(pj_size_t n)
|
||||
{
|
||||
/* Next 32-bit power of two */
|
||||
pj_size_t power = 1;
|
||||
while (power < n && power < 0x8000000) {
|
||||
power <<= 1;
|
||||
}
|
||||
return power;
|
||||
}
|
||||
|
||||
static pj_status_t circ_init(pj_pool_factory *factory,
|
||||
circ_buf_t *cb, pj_size_t cap)
|
||||
{
|
||||
/* Round-up cap */
|
||||
cap = next_pow2(cap);
|
||||
|
||||
cb->cap = cap;
|
||||
cb->readp = 0;
|
||||
cb->writep = 0;
|
||||
|
@ -81,24 +68,17 @@ static pj_status_t circ_init(pj_pool_factory *factory,
|
|||
/* Allocate circular buffer */
|
||||
cb->buf = pj_pool_alloc(cb->pool, cap);
|
||||
if (!cb->buf) {
|
||||
pj_pool_secure_release(&cb->pool);
|
||||
pj_pool_release(cb->pool);
|
||||
return PJ_ENOMEM;
|
||||
}
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
static void circ_reset(circ_buf_t* cb)
|
||||
{
|
||||
cb->readp = 0;
|
||||
cb->writep = 0;
|
||||
cb->size = 0;
|
||||
}
|
||||
|
||||
static void circ_deinit(circ_buf_t *cb)
|
||||
{
|
||||
if (cb->pool) {
|
||||
pj_pool_secure_release(&cb->pool);
|
||||
pj_pool_release(cb->pool);
|
||||
cb->pool = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -124,8 +104,6 @@ static void circ_read(circ_buf_t *cb, pj_uint8_t *dst, pj_size_t len)
|
|||
pj_size_t tbc = PJ_MIN(size_after, len);
|
||||
pj_size_t rem = len - tbc;
|
||||
|
||||
pj_assert(cb->size >= len);
|
||||
|
||||
pj_memcpy(dst, cb->buf + cb->readp, tbc);
|
||||
pj_memcpy(dst + tbc, cb->buf, rem);
|
||||
|
||||
|
@ -135,21 +113,6 @@ static void circ_read(circ_buf_t *cb, pj_uint8_t *dst, pj_size_t len)
|
|||
cb->size -= len;
|
||||
}
|
||||
|
||||
/* Cancel previous read, partially or fully.
|
||||
* Should be called in the same mutex block as circ_read().
|
||||
*/
|
||||
static void circ_read_cancel(circ_buf_t* cb, pj_size_t len)
|
||||
{
|
||||
pj_assert(cb->cap - cb->size >= len);
|
||||
|
||||
if (cb->readp < len)
|
||||
cb->readp = cb->cap - (len - cb->readp);
|
||||
else
|
||||
cb->readp -= len;
|
||||
|
||||
cb->size += len;
|
||||
}
|
||||
|
||||
static pj_status_t circ_write(circ_buf_t *cb,
|
||||
const pj_uint8_t *src, pj_size_t len)
|
||||
{
|
||||
|
@ -158,8 +121,14 @@ static pj_status_t circ_write(circ_buf_t *cb,
|
|||
/* Minimum required capacity */
|
||||
pj_size_t min_cap = len + cb->size;
|
||||
|
||||
/* Round-up minimum capacity */
|
||||
min_cap = next_pow2(min_cap);
|
||||
/* Next 32-bit power of two */
|
||||
min_cap--;
|
||||
min_cap |= min_cap >> 1;
|
||||
min_cap |= min_cap >> 2;
|
||||
min_cap |= min_cap >> 4;
|
||||
min_cap |= min_cap >> 8;
|
||||
min_cap |= min_cap >> 16;
|
||||
min_cap++;
|
||||
|
||||
/* Create a new pool to hold a bigger buffer, using the same factory */
|
||||
pj_pool_t *pool = pj_pool_create(cb->pool->factory, "tls-circ%p",
|
||||
|
@ -184,7 +153,7 @@ static pj_status_t circ_write(circ_buf_t *cb,
|
|||
cb->size = old_size;
|
||||
|
||||
/* Release the previous pool */
|
||||
pj_pool_secure_release(&cb->pool);
|
||||
pj_pool_release(cb->pool);
|
||||
|
||||
/* Update circular buffer members */
|
||||
cb->pool = pool;
|
||||
|
@ -981,7 +950,7 @@ static pj_bool_t ssock_on_accept_complete (pj_ssl_sock_t *ssock_parent,
|
|||
int src_addr_len,
|
||||
pj_status_t accept_status)
|
||||
{
|
||||
pj_ssl_sock_t *ssock = NULL;
|
||||
pj_ssl_sock_t *ssock;
|
||||
#ifndef SSL_SOCK_IMP_USE_OWN_NETWORK
|
||||
pj_activesock_cb asock_cb;
|
||||
pj_activesock_cfg asock_cfg;
|
||||
|
@ -1165,6 +1134,7 @@ static pj_bool_t ssock_on_accept_complete (pj_ssl_sock_t *ssock_parent,
|
|||
ssock->param.grp_lock);
|
||||
if (status != PJ_SUCCESS) {
|
||||
ssock->timer.id = TIMER_NONE;
|
||||
status = PJ_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1768,7 +1738,7 @@ static pj_status_t ssl_send (pj_ssl_sock_t *ssock,
|
|||
unsigned flags)
|
||||
{
|
||||
pj_status_t status;
|
||||
int nwritten = 0;
|
||||
int nwritten;
|
||||
|
||||
/* Write the plain data to SSL, after SSL encrypts it, the buffer will
|
||||
* contain the secured data to be sent via socket. Note that re-
|
||||
|
@ -2272,9 +2242,8 @@ static void wipe_buf(pj_str_t *buf)
|
|||
}
|
||||
|
||||
PJ_DEF(void) pj_ssl_cert_wipe_keys(pj_ssl_cert_t *cert)
|
||||
{
|
||||
{
|
||||
if (cert) {
|
||||
#if (PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
wipe_buf(&cert->CA_file);
|
||||
wipe_buf(&cert->CA_path);
|
||||
wipe_buf(&cert->cert_file);
|
||||
|
@ -2283,10 +2252,6 @@ PJ_DEF(void) pj_ssl_cert_wipe_keys(pj_ssl_cert_t *cert)
|
|||
wipe_buf(&cert->CA_buf);
|
||||
wipe_buf(&cert->cert_buf);
|
||||
wipe_buf(&cert->privkey_buf);
|
||||
#else
|
||||
cert->criteria.type = PJ_SSL_CERT_LOOKUP_NONE;
|
||||
wipe_buf(&cert->criteria.keyword);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -2310,7 +2275,6 @@ PJ_DEF(pj_status_t) pj_ssl_cert_load_from_files2(pj_pool_t *pool,
|
|||
const pj_str_t *privkey_pass,
|
||||
pj_ssl_cert_t **p_cert)
|
||||
{
|
||||
#if (PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
pj_ssl_cert_t *cert;
|
||||
|
||||
PJ_ASSERT_RETURN(pool && (CA_file || CA_path) && cert_file &&
|
||||
|
@ -2331,16 +2295,6 @@ PJ_DEF(pj_status_t) pj_ssl_cert_load_from_files2(pj_pool_t *pool,
|
|||
*p_cert = cert;
|
||||
|
||||
return PJ_SUCCESS;
|
||||
#else
|
||||
PJ_UNUSED_ARG(pool);
|
||||
PJ_UNUSED_ARG(CA_file);
|
||||
PJ_UNUSED_ARG(CA_path);
|
||||
PJ_UNUSED_ARG(cert_file);
|
||||
PJ_UNUSED_ARG(privkey_file);
|
||||
PJ_UNUSED_ARG(privkey_pass);
|
||||
PJ_UNUSED_ARG(p_cert);
|
||||
return PJ_ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
PJ_DEF(pj_status_t) pj_ssl_cert_load_from_buffer(pj_pool_t *pool,
|
||||
|
@ -2350,7 +2304,6 @@ PJ_DEF(pj_status_t) pj_ssl_cert_load_from_buffer(pj_pool_t *pool,
|
|||
const pj_str_t *privkey_pass,
|
||||
pj_ssl_cert_t **p_cert)
|
||||
{
|
||||
#if (PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
pj_ssl_cert_t *cert;
|
||||
|
||||
PJ_ASSERT_RETURN(pool && CA_buf && cert_buf && privkey_buf, PJ_EINVAL);
|
||||
|
@ -2364,44 +2317,8 @@ PJ_DEF(pj_status_t) pj_ssl_cert_load_from_buffer(pj_pool_t *pool,
|
|||
*p_cert = cert;
|
||||
|
||||
return PJ_SUCCESS;
|
||||
#else
|
||||
PJ_UNUSED_ARG(pool);
|
||||
PJ_UNUSED_ARG(CA_buf);
|
||||
PJ_UNUSED_ARG(cert_buf);
|
||||
PJ_UNUSED_ARG(privkey_buf);
|
||||
PJ_UNUSED_ARG(privkey_pass);
|
||||
PJ_UNUSED_ARG(p_cert);
|
||||
return PJ_ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
PJ_DEF(pj_status_t) pj_ssl_cert_load_from_store(
|
||||
pj_pool_t *pool,
|
||||
const pj_ssl_cert_lookup_criteria *criteria,
|
||||
pj_ssl_cert_t **p_cert)
|
||||
{
|
||||
#if (PJ_SSL_SOCK_IMP == PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
pj_ssl_cert_t *cert;
|
||||
|
||||
PJ_ASSERT_RETURN(pool && criteria && p_cert, PJ_EINVAL);
|
||||
|
||||
cert = PJ_POOL_ZALLOC_T(pool, pj_ssl_cert_t);
|
||||
pj_memcpy(&cert->criteria, criteria, sizeof(*criteria));
|
||||
pj_strdup_with_null(pool, &cert->criteria.keyword, &criteria->keyword);
|
||||
|
||||
*p_cert = cert;
|
||||
|
||||
return PJ_SUCCESS;
|
||||
#else
|
||||
PJ_UNUSED_ARG(pool);
|
||||
PJ_UNUSED_ARG(criteria);
|
||||
PJ_UNUSED_ARG(p_cert);
|
||||
return PJ_ENOTSUP;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/* Set SSL socket credentials. */
|
||||
PJ_DEF(pj_status_t) pj_ssl_sock_set_certificate(
|
||||
pj_ssl_sock_t *ssock,
|
||||
|
@ -2414,8 +2331,6 @@ PJ_DEF(pj_status_t) pj_ssl_sock_set_certificate(
|
|||
|
||||
cert_ = PJ_POOL_ZALLOC_T(pool, pj_ssl_cert_t);
|
||||
pj_memcpy(cert_, cert, sizeof(pj_ssl_cert_t));
|
||||
|
||||
#if (PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
pj_strdup_with_null(pool, &cert_->CA_file, &cert->CA_file);
|
||||
pj_strdup_with_null(pool, &cert_->CA_path, &cert->CA_path);
|
||||
pj_strdup_with_null(pool, &cert_->cert_file, &cert->cert_file);
|
||||
|
@ -2425,10 +2340,6 @@ PJ_DEF(pj_status_t) pj_ssl_sock_set_certificate(
|
|||
pj_strdup(pool, &cert_->CA_buf, &cert->CA_buf);
|
||||
pj_strdup(pool, &cert_->cert_buf, &cert->cert_buf);
|
||||
pj_strdup(pool, &cert_->privkey_buf, &cert->privkey_buf);
|
||||
#else
|
||||
pj_strdup_with_null(pool, &cert_->criteria.keyword,
|
||||
&cert->criteria.keyword);
|
||||
#endif
|
||||
|
||||
ssock->cert = cert_;
|
||||
|
||||
|
|
|
@ -152,7 +152,6 @@ struct pj_ssl_sock_t
|
|||
*/
|
||||
struct pj_ssl_cert_t
|
||||
{
|
||||
#if (PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
pj_str_t CA_file;
|
||||
pj_str_t CA_path;
|
||||
pj_str_t cert_file;
|
||||
|
@ -163,9 +162,6 @@ struct pj_ssl_cert_t
|
|||
pj_ssl_cert_buffer CA_buf;
|
||||
pj_ssl_cert_buffer cert_buf;
|
||||
pj_ssl_cert_buffer privkey_buf;
|
||||
#else
|
||||
pj_ssl_cert_lookup_criteria criteria;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* ssl available ciphers */
|
||||
|
@ -209,11 +205,9 @@ static pj_status_t flush_delayed_send(pj_ssl_sock_t *ssock);
|
|||
static pj_status_t circ_init(pj_pool_factory *factory,
|
||||
circ_buf_t *cb, pj_size_t cap);
|
||||
static void circ_deinit(circ_buf_t *cb);
|
||||
static void circ_reset(circ_buf_t* cb);
|
||||
static pj_bool_t circ_empty(const circ_buf_t *cb);
|
||||
static pj_size_t circ_size(const circ_buf_t *cb);
|
||||
static void circ_read(circ_buf_t *cb, pj_uint8_t *dst, pj_size_t len);
|
||||
static void circ_read_cancel(circ_buf_t* cb, pj_size_t len);
|
||||
static pj_status_t circ_write(circ_buf_t *cb,
|
||||
const pj_uint8_t *src, pj_size_t len);
|
||||
|
||||
|
@ -236,7 +230,7 @@ inline static void io_read(pj_ssl_sock_t *ssock, circ_buf_t *cb,
|
|||
pj_uint8_t *dst, pj_size_t len)
|
||||
{
|
||||
PJ_UNUSED_ARG(ssock);
|
||||
circ_read(cb, dst, len);
|
||||
return circ_read(cb, dst, len);
|
||||
}
|
||||
inline static pj_status_t io_write(pj_ssl_sock_t *ssock, circ_buf_t *cb,
|
||||
const pj_uint8_t *src, pj_size_t len)
|
||||
|
|
|
@ -159,12 +159,10 @@ static void update_certs_info(pj_ssl_sock_t* ssock,
|
|||
pj_ssl_cert_info *remote_cert_info,
|
||||
pj_bool_t is_verify);
|
||||
|
||||
#if OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
#if !USING_LIBRESSL && OPENSSL_VERSION_NUMBER >= 0x10100000L
|
||||
# define OPENSSL_NO_SSL2 /* seems to be removed in 1.1.0 */
|
||||
# ifndef M_ASN1_STRING_data
|
||||
# define M_ASN1_STRING_data(x) ASN1_STRING_get0_data(x)
|
||||
# define M_ASN1_STRING_length(x) ASN1_STRING_length(x)
|
||||
# endif
|
||||
# if defined(OPENSSL_API_COMPAT) && OPENSSL_API_COMPAT >= 0x10100000L || \
|
||||
defined(OPENSSL_NO_DEPRECATED)
|
||||
|
||||
|
@ -181,7 +179,7 @@ static void update_certs_info(pj_ssl_sock_t* ssock,
|
|||
# endif
|
||||
|
||||
# endif
|
||||
#else
|
||||
#elif !USING_LIBRESSL
|
||||
# define SSL_CIPHER_get_id(c) (c)->id
|
||||
# define SSL_set_session(ssl, s) (ssl)->session = (s)
|
||||
# define X509_STORE_CTX_get0_cert(ctx) ((ctx)->cert)
|
||||
|
@ -483,12 +481,11 @@ static pj_str_t ssl_strerror(pj_status_t status,
|
|||
*/
|
||||
static const struct ssl_ciphers_t ADDITIONAL_CIPHERS[] = {
|
||||
{0xFF000000, "DEFAULT"},
|
||||
{0xFF000001, "@SECLEVEL=0"},
|
||||
{0xFF000002, "@SECLEVEL=1"},
|
||||
{0xFF000003, "@SECLEVEL=2"},
|
||||
{0xFF000004, "@SECLEVEL=3"},
|
||||
{0xFF000005, "@SECLEVEL=4"},
|
||||
{0xFF000006, "@SECLEVEL=5"}
|
||||
{0xFF000001, "@SECLEVEL=1"},
|
||||
{0xFF000002, "@SECLEVEL=2"},
|
||||
{0xFF000003, "@SECLEVEL=3"},
|
||||
{0xFF000004, "@SECLEVEL=4"},
|
||||
{0xFF000005, "@SECLEVEL=5"}
|
||||
};
|
||||
static const unsigned int ADDITIONAL_CIPHER_COUNT =
|
||||
sizeof (ADDITIONAL_CIPHERS) / sizeof (ADDITIONAL_CIPHERS[0]);
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -259,7 +259,7 @@ PJ_DEF(long) pj_strtol(const pj_str_t *str)
|
|||
uval = pj_strtoul(str);
|
||||
|
||||
if (is_negative)
|
||||
val = uval > PJ_MAXLONG ? PJ_MINLONG : -(long)uval;
|
||||
val = uval > PJ_MAXLONG ? PJ_MINLONG : -uval;
|
||||
else
|
||||
val = uval > PJ_MAXLONG ? PJ_MAXLONG : uval;
|
||||
|
||||
|
@ -310,12 +310,7 @@ PJ_DEF(pj_status_t) pj_strtol2(const pj_str_t *str, long *value)
|
|||
return PJ_ETOOSMALL;
|
||||
}
|
||||
|
||||
if (is_negative && retval == PJ_MAXLONG + 1UL) {
|
||||
*value = PJ_MINLONG;
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
*value = is_negative ? -(long)retval : retval;
|
||||
*value = is_negative ? -retval : retval;
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -381,9 +381,8 @@ static pj_status_t grow_heap(pj_timer_heap_t *ht)
|
|||
pj_timer_entry_dup *new_dup;
|
||||
#endif
|
||||
|
||||
PJ_LOG(6,(THIS_FILE, "Growing heap size from %lu to %lu",
|
||||
(unsigned long)ht->max_size,
|
||||
(unsigned long)new_size));
|
||||
PJ_LOG(6,(THIS_FILE, "Growing heap size from %d to %d",
|
||||
ht->max_size, new_size));
|
||||
|
||||
// First grow the heap itself.
|
||||
new_heap = (pj_timer_entry_dup**)
|
||||
|
@ -534,14 +533,11 @@ static int cancel( pj_timer_heap_t *ht,
|
|||
|
||||
PJ_CHECK_STACK();
|
||||
|
||||
// Check to see if the timer_id is out of range.
|
||||
// Moved to cancel_timer() as it needs to validate _timer_id earlier
|
||||
/*
|
||||
// Check to see if the timer_id is out of range
|
||||
if (entry->_timer_id < 1 || (pj_size_t)entry->_timer_id >= ht->max_size) {
|
||||
entry->_timer_id = -1;
|
||||
return 0;
|
||||
}
|
||||
*/
|
||||
|
||||
timer_node_slot = ht->timer_ids[entry->_timer_id];
|
||||
|
||||
|
@ -814,13 +810,6 @@ static int cancel_timer(pj_timer_heap_t *ht,
|
|||
PJ_ASSERT_RETURN(ht && entry, PJ_EINVAL);
|
||||
|
||||
lock_timer_heap(ht);
|
||||
|
||||
// Check to see if the timer_id is out of range
|
||||
if (entry->_timer_id < 1 || (pj_size_t)entry->_timer_id >= ht->max_size) {
|
||||
unlock_timer_heap(ht);
|
||||
return 0;
|
||||
}
|
||||
|
||||
timer_copy = GET_TIMER(ht, entry);
|
||||
grp_lock = timer_copy->_grp_lock;
|
||||
|
||||
|
|
|
@ -121,8 +121,8 @@ static void on_read_complete(pj_ioqueue_key_t *key,
|
|||
PJ_LOG(3,(THIS_FILE,
|
||||
".....additional info: type=%s, total read=%lu, "
|
||||
"total sent=%lu",
|
||||
item->type_name, (unsigned long)item->bytes_recv,
|
||||
(unsigned long)item->bytes_sent));
|
||||
item->type_name, item->bytes_recv,
|
||||
item->bytes_sent));
|
||||
}
|
||||
} else {
|
||||
last_error_counter++;
|
||||
|
@ -480,10 +480,8 @@ static int perform_test(const pj_ioqueue_cfg *cfg,
|
|||
if (display_report) {
|
||||
PJ_LOG(3,(THIS_FILE, " %s %d threads, %d pairs", type_name,
|
||||
thread_cnt, sockpair_cnt));
|
||||
PJ_LOG(3,(THIS_FILE, " Elapsed : %lu msec",
|
||||
(unsigned long)(total_elapsed_usec/1000)));
|
||||
PJ_LOG(3,(THIS_FILE, " Bandwidth: %lu KB/s",
|
||||
(unsigned long)*p_bandwidth));
|
||||
PJ_LOG(3,(THIS_FILE, " Elapsed : %lu msec", total_elapsed_usec/1000));
|
||||
PJ_LOG(3,(THIS_FILE, " Bandwidth: %lu KB/s", *p_bandwidth));
|
||||
PJ_LOG(3,(THIS_FILE, " Threads statistics:"));
|
||||
PJ_LOG(3,(THIS_FILE, " ============================="));
|
||||
PJ_LOG(3,(THIS_FILE, " Thread Loops Events Errors"));
|
||||
|
@ -508,7 +506,7 @@ static int perform_test(const pj_ioqueue_cfg *cfg,
|
|||
} else {
|
||||
PJ_LOG(3,(THIS_FILE, " %.4s %2d %2d %8lu KB/s",
|
||||
type_name, thread_cnt, sockpair_cnt,
|
||||
(unsigned long)*p_bandwidth));
|
||||
*p_bandwidth));
|
||||
}
|
||||
|
||||
/* Done. */
|
||||
|
@ -580,7 +578,7 @@ static int ioqueue_perf_test_imp(const pj_ioqueue_cfg *cfg)
|
|||
test_param[best_index].type_name,
|
||||
test_param[best_index].thread_cnt,
|
||||
test_param[best_index].sockpair_cnt,
|
||||
(unsigned long)best_bandwidth));
|
||||
best_bandwidth));
|
||||
PJ_LOG(3,(THIS_FILE, " (Note: packet size=%d, total errors=%u)",
|
||||
BUF_SIZE, last_error_counter));
|
||||
return 0;
|
||||
|
|
|
@ -402,6 +402,10 @@ static int compliance_test_0(const pj_ioqueue_cfg *cfg)
|
|||
return -52;
|
||||
}
|
||||
pending_op -= status;
|
||||
|
||||
if (pending_op == 0) {
|
||||
status = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -69,7 +69,7 @@ static int capacity_test(void)
|
|||
|
||||
if (pj_pool_alloc(pool, freesize) == NULL) {
|
||||
PJ_LOG(3,("test", "...error: wrong freesize %lu reported",
|
||||
(unsigned long)freesize));
|
||||
freesize));
|
||||
pj_pool_release(pool);
|
||||
return -210;
|
||||
}
|
||||
|
@ -175,8 +175,7 @@ static int drain_test(pj_size_t size, pj_size_t increment)
|
|||
void *p;
|
||||
int status = 0;
|
||||
|
||||
PJ_LOG(3,("test", "...drain_test(%lu,%lu)", (unsigned long)size,
|
||||
(unsigned long)increment));
|
||||
PJ_LOG(3,("test", "...drain_test(%lu,%lu)", size, increment));
|
||||
|
||||
if (!pool)
|
||||
return -10;
|
||||
|
@ -209,7 +208,7 @@ static int drain_test(pj_size_t size, pj_size_t increment)
|
|||
/* Check that capacity is zero. */
|
||||
if (GET_FREE(pool) != 0) {
|
||||
PJ_LOG(3,("test", "....error: returned free=%lu (expecting 0)",
|
||||
(unsigned long)(GET_FREE(pool))));
|
||||
GET_FREE(pool)));
|
||||
status=-30; goto on_error;
|
||||
}
|
||||
|
||||
|
|
|
@ -93,7 +93,7 @@ static int simple_sleep_test(void)
|
|||
static int sleep_duration_test(void)
|
||||
{
|
||||
const unsigned MAX_SLIP = param_ci_mode? 200 : 20;
|
||||
long duration[] = { 2000, 1000, 500, 200, 100 };
|
||||
unsigned duration[] = { 2000, 1000, 500, 200, 100 };
|
||||
unsigned i;
|
||||
unsigned avg_diff, max_diff;
|
||||
pj_status_t rc;
|
||||
|
@ -103,7 +103,7 @@ static int sleep_duration_test(void)
|
|||
/* Test pj_thread_sleep() and pj_gettimeofday() */
|
||||
for (i=0, avg_diff=0, max_diff=0; i<PJ_ARRAY_SIZE(duration); ++i) {
|
||||
pj_time_val start, stop;
|
||||
long msec;
|
||||
pj_uint32_t msec;
|
||||
unsigned diff;
|
||||
|
||||
/* Mark start of test. */
|
||||
|
@ -139,7 +139,7 @@ static int sleep_duration_test(void)
|
|||
max_diff = diff>max_diff ? diff : max_diff;
|
||||
if (diff > MAX_SLIP) {
|
||||
PJ_LOG(3,(THIS_FILE,
|
||||
"...error: slept for %ld ms instead of %ld ms "
|
||||
"...error: slept for %d ms instead of %d ms "
|
||||
"(outside %d msec tolerance)",
|
||||
msec, duration[i], MAX_SLIP));
|
||||
}
|
||||
|
@ -153,7 +153,7 @@ static int sleep_duration_test(void)
|
|||
for (i=0, avg_diff=0, max_diff=0; i<PJ_ARRAY_SIZE(duration); ++i) {
|
||||
pj_time_val t1, t2;
|
||||
pj_timestamp start, stop;
|
||||
long msec;
|
||||
pj_uint32_t msec;
|
||||
unsigned diff;
|
||||
|
||||
pj_thread_sleep(0);
|
||||
|
@ -196,7 +196,7 @@ static int sleep_duration_test(void)
|
|||
max_diff = diff>max_diff ? diff : max_diff;
|
||||
if (diff > MAX_SLIP) {
|
||||
PJ_LOG(3,(THIS_FILE,
|
||||
"...error: slept for %ld ms instead of %ld ms "
|
||||
"...error: slept for %d ms instead of %d ms "
|
||||
"(outside %d msec tolerance)",
|
||||
msec, duration[i], MAX_SLIP));
|
||||
PJ_TIME_VAL_SUB(t2, t1);
|
||||
|
|
|
@ -541,15 +541,14 @@ static int send_recv_test(int sock_type,
|
|||
rc = -155; goto on_error;
|
||||
}
|
||||
if (received <= 0) {
|
||||
PJ_LOG(3,("", "...error: socket has closed! (received=%lu)",
|
||||
(unsigned long)received));
|
||||
PJ_LOG(3,("", "...error: socket has closed! (received=%ld)",
|
||||
received));
|
||||
rc = -156; goto on_error;
|
||||
}
|
||||
if (received != DATA_LEN-total_received) {
|
||||
if (sock_type != pj_SOCK_STREAM()) {
|
||||
PJ_LOG(3,("", "...error: expecting %lu bytes, got %lu bytes",
|
||||
(unsigned long)(DATA_LEN-total_received),
|
||||
(unsigned long)received));
|
||||
DATA_LEN-total_received, received));
|
||||
rc = -157; goto on_error;
|
||||
}
|
||||
}
|
||||
|
@ -600,15 +599,14 @@ static int send_recv_test(int sock_type,
|
|||
rc = -170; goto on_error;
|
||||
}
|
||||
if (received <= 0) {
|
||||
PJ_LOG(3,("", "...error: socket has closed! (received=%lu)",
|
||||
(unsigned long)received));
|
||||
PJ_LOG(3,("", "...error: socket has closed! (received=%ld)",
|
||||
received));
|
||||
rc = -173; goto on_error;
|
||||
}
|
||||
if (received != BIG_DATA_LEN-total_received) {
|
||||
if (sock_type != pj_SOCK_STREAM()) {
|
||||
PJ_LOG(3,("", "...error: expecting %lu bytes, got %lu bytes",
|
||||
(unsigned long)BIG_DATA_LEN-total_received,
|
||||
(unsigned long)received));
|
||||
BIG_DATA_LEN-total_received, received));
|
||||
rc = -176; goto on_error;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -350,8 +350,7 @@ static pj_bool_t ssl_on_data_read(pj_ssl_sock_t *ssock,
|
|||
}
|
||||
|
||||
pj_sockaddr_print((pj_sockaddr_t*)&info.local_addr, buf, sizeof(buf), 1);
|
||||
PJ_LOG(3, ("", "...%s successfully recv %lu bytes echo", buf,
|
||||
(unsigned long)st->recv));
|
||||
PJ_LOG(3, ("", "...%s successfully recv %lu bytes echo", buf, st->recv));
|
||||
st->done = PJ_TRUE;
|
||||
}
|
||||
}
|
||||
|
@ -502,8 +501,7 @@ static int https_client_test(unsigned ms_timeout)
|
|||
}
|
||||
|
||||
PJ_LOG(3, ("", "...Done!"));
|
||||
PJ_LOG(3, ("", ".....Sent/recv: %lu/%lu bytes", (unsigned long)state.sent,
|
||||
(unsigned long)state.recv));
|
||||
PJ_LOG(3, ("", ".....Sent/recv: %lu/%lu bytes", state.sent, state.recv));
|
||||
|
||||
on_return:
|
||||
if (ssock && !state.err && !state.done)
|
||||
|
@ -540,39 +538,6 @@ static pj_status_t load_cert_to_buf(pj_pool_t *pool, const pj_str_t *file_name,
|
|||
}
|
||||
#endif
|
||||
|
||||
static pj_status_t load_cert_from_store(pj_pool_t *pool,
|
||||
pj_ssl_cert_t **p_cert)
|
||||
{
|
||||
#if 0
|
||||
/* To test loading certificate from the store, follow these steps:
|
||||
* 1. Install the certificate & the private-key pair to the store,
|
||||
* and optionally set the friendly-name for it.
|
||||
* 2. Update the lookup criteria below (field & keyword).
|
||||
*/
|
||||
pj_ssl_cert_lookup_criteria crit = {0};
|
||||
|
||||
/* Lookup by subject */
|
||||
crit.type = PJ_SSL_CERT_LOOKUP_SUBJECT;
|
||||
pj_cstr(&crit.keyword, "test.pjsip.org");
|
||||
|
||||
/* Lookup by friendly-name */
|
||||
//crit.type = PJ_SSL_CERT_LOOKUP_FRIENDLY_NAME;
|
||||
//pj_cstr(&crit.keyword, "schannel-test");
|
||||
|
||||
/* Lookup by fingerprint */
|
||||
//crit.type = PJ_SSL_CERT_LOOKUP_FINGERPRINT;
|
||||
//pj_cstr(&crit.keyword, "\x08\x3a\x6c\xdc\xd0\x19\x59\xec\x28\xc3"
|
||||
// "\x81\xb8\xc0\x21\x09\xe9\xd5\xf6\x57\x7d");
|
||||
|
||||
return pj_ssl_cert_load_from_store(pool, &crit, p_cert);
|
||||
#else
|
||||
/* Set no certificate, Schannel will use self-signed cert */
|
||||
PJ_UNUSED_ARG(pool);
|
||||
PJ_UNUSED_ARG(p_cert);
|
||||
return PJ_ENOTFOUND;
|
||||
#endif
|
||||
}
|
||||
|
||||
static int echo_test(pj_ssl_sock_proto srv_proto, pj_ssl_sock_proto cli_proto,
|
||||
pj_ssl_cipher srv_cipher, pj_ssl_cipher cli_cipher,
|
||||
pj_bool_t req_client_cert, pj_bool_t client_provide_cert)
|
||||
|
@ -635,19 +600,6 @@ static int echo_test(pj_ssl_sock_proto srv_proto, pj_ssl_sock_proto cli_proto,
|
|||
}
|
||||
|
||||
/* Set server cert */
|
||||
#if (PJ_SSL_SOCK_IMP == PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
/* Schannel backend currently can only load certificates from
|
||||
* OS cert store. If the certificate loading fails, we'll skip setting
|
||||
* certificate, so the SSL socket will create & use a self-signed cert.
|
||||
*/
|
||||
status = load_cert_from_store(pool, &cert);
|
||||
if (status == PJ_SUCCESS) {
|
||||
status = pj_ssl_sock_set_certificate(ssock_serv, pool, cert);
|
||||
if (status != PJ_SUCCESS) {
|
||||
goto on_return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
pj_str_t ca_file = pj_str(CERT_CA_FILE);
|
||||
pj_str_t cert_file = pj_str(CERT_FILE);
|
||||
|
@ -689,7 +641,6 @@ static int echo_test(pj_ssl_sock_proto srv_proto, pj_ssl_sock_proto cli_proto,
|
|||
goto on_return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
status = pj_ssl_sock_start_accept(ssock_serv, pool, &addr, pj_sockaddr_get_len(&addr));
|
||||
if (status != PJ_SUCCESS) {
|
||||
|
@ -733,22 +684,9 @@ static int echo_test(pj_ssl_sock_proto srv_proto, pj_ssl_sock_proto cli_proto,
|
|||
goto on_return;
|
||||
}
|
||||
|
||||
/* Set cert for client.
|
||||
* Reusing certificate for server above, but if client_provide_cert
|
||||
* is not set, override the certificate with CA certificate.
|
||||
*/
|
||||
#if (PJ_SSL_SOCK_IMP == PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
if (client_provide_cert) {
|
||||
status = load_cert_from_store(pool, &cert);
|
||||
if (status == PJ_SUCCESS)
|
||||
status = pj_ssl_sock_set_certificate(ssock_cli, pool, cert);
|
||||
|
||||
if (status != PJ_SUCCESS) {
|
||||
goto on_return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
/* Set cert for client */
|
||||
{
|
||||
|
||||
if (!client_provide_cert) {
|
||||
pj_str_t ca_file = pj_str(CERT_CA_FILE);
|
||||
pj_str_t null_str = pj_str("");
|
||||
|
@ -780,7 +718,6 @@ static int echo_test(pj_ssl_sock_proto srv_proto, pj_ssl_sock_proto cli_proto,
|
|||
goto on_return;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
status = pj_ssl_sock_start_connect(ssock_cli, pool, &addr, &listen_addr, pj_sockaddr_get_len(&addr));
|
||||
if (status == PJ_SUCCESS) {
|
||||
|
@ -818,8 +755,7 @@ static int echo_test(pj_ssl_sock_proto srv_proto, pj_ssl_sock_proto cli_proto,
|
|||
}
|
||||
|
||||
PJ_LOG(3, ("", "...Done!"));
|
||||
PJ_LOG(3, ("", ".....Sent/recv: %lu/%lu bytes", (unsigned long)state_cli.sent,
|
||||
(unsigned long)state_cli.recv));
|
||||
PJ_LOG(3, ("", ".....Sent/recv: %lu/%lu bytes", state_cli.sent, state_cli.recv));
|
||||
|
||||
on_return:
|
||||
#if (PJ_SSL_SOCK_IMP == PJ_SSL_SOCK_IMP_DARWIN) || \
|
||||
|
@ -987,41 +923,7 @@ static int client_non_ssl(unsigned ms_timeout)
|
|||
goto on_return;
|
||||
}
|
||||
|
||||
pj_ssl_sock_param_default(¶m);
|
||||
param.cb.on_accept_complete2 = &ssl_on_accept_complete;
|
||||
param.cb.on_data_read = &ssl_on_data_read;
|
||||
param.cb.on_data_sent = &ssl_on_data_sent;
|
||||
param.ioqueue = ioqueue;
|
||||
param.timer_heap = timer;
|
||||
param.timeout.sec = 0;
|
||||
param.timeout.msec = ms_timeout;
|
||||
pj_time_val_normalize(¶m.timeout);
|
||||
|
||||
/* SERVER */
|
||||
param.user_data = &state_serv;
|
||||
state_serv.pool = pool;
|
||||
state_serv.is_server = PJ_TRUE;
|
||||
state_serv.is_verbose = PJ_TRUE;
|
||||
|
||||
status = pj_ssl_sock_create(pool, ¶m, &ssock_serv);
|
||||
if (status != PJ_SUCCESS) {
|
||||
goto on_return;
|
||||
}
|
||||
|
||||
/* Set cert */
|
||||
#if (PJ_SSL_SOCK_IMP == PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
/* Schannel backend currently can only load certificates from
|
||||
* OS cert store. If the certificate loading fails, we'll skip setting
|
||||
* certificate, so the SSL socket will create & use a self-signed cert.
|
||||
*/
|
||||
status = load_cert_from_store(pool, &cert);
|
||||
if (status == PJ_SUCCESS) {
|
||||
status = pj_ssl_sock_set_certificate(ssock_serv, pool, cert);
|
||||
if (status != PJ_SUCCESS) {
|
||||
goto on_return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
pj_str_t ca_file = pj_str(CERT_CA_FILE);
|
||||
pj_str_t cert_file = pj_str(CERT_FILE);
|
||||
|
@ -1059,11 +961,31 @@ static int client_non_ssl(unsigned ms_timeout)
|
|||
}
|
||||
}
|
||||
|
||||
pj_ssl_sock_param_default(¶m);
|
||||
param.cb.on_accept_complete2 = &ssl_on_accept_complete;
|
||||
param.cb.on_data_read = &ssl_on_data_read;
|
||||
param.cb.on_data_sent = &ssl_on_data_sent;
|
||||
param.ioqueue = ioqueue;
|
||||
param.timer_heap = timer;
|
||||
param.timeout.sec = 0;
|
||||
param.timeout.msec = ms_timeout;
|
||||
pj_time_val_normalize(¶m.timeout);
|
||||
|
||||
/* SERVER */
|
||||
param.user_data = &state_serv;
|
||||
state_serv.pool = pool;
|
||||
state_serv.is_server = PJ_TRUE;
|
||||
state_serv.is_verbose = PJ_TRUE;
|
||||
|
||||
status = pj_ssl_sock_create(pool, ¶m, &ssock_serv);
|
||||
if (status != PJ_SUCCESS) {
|
||||
goto on_return;
|
||||
}
|
||||
|
||||
status = pj_ssl_sock_set_certificate(ssock_serv, pool, cert);
|
||||
if (status != PJ_SUCCESS) {
|
||||
goto on_return;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Init bind address */
|
||||
{
|
||||
|
@ -1336,49 +1258,7 @@ static int perf_test(unsigned clients, unsigned ms_handshake_timeout)
|
|||
goto on_return;
|
||||
}
|
||||
|
||||
pj_ssl_sock_param_default(¶m);
|
||||
param.cb.on_accept_complete2 = &ssl_on_accept_complete;
|
||||
param.cb.on_connect_complete = &ssl_on_connect_complete;
|
||||
param.cb.on_data_read = &ssl_on_data_read;
|
||||
param.cb.on_data_sent = &ssl_on_data_sent;
|
||||
param.ioqueue = ioqueue;
|
||||
param.timer_heap = timer;
|
||||
param.timeout.sec = 0;
|
||||
param.timeout.msec = ms_handshake_timeout;
|
||||
pj_time_val_normalize(¶m.timeout);
|
||||
|
||||
/* Init default bind address */
|
||||
{
|
||||
pj_str_t tmp_st;
|
||||
pj_sockaddr_init(PJ_AF_INET, &addr, pj_strset2(&tmp_st, "127.0.0.1"), 0);
|
||||
}
|
||||
|
||||
/* SERVER */
|
||||
param.user_data = &state_serv;
|
||||
|
||||
state_serv.pool = pool;
|
||||
state_serv.echo = PJ_TRUE;
|
||||
state_serv.is_server = PJ_TRUE;
|
||||
|
||||
status = pj_ssl_sock_create(pool, ¶m, &ssock_serv);
|
||||
if (status != PJ_SUCCESS) {
|
||||
goto on_return;
|
||||
}
|
||||
|
||||
/* Set cert */
|
||||
#if (PJ_SSL_SOCK_IMP == PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
/* Schannel backend currently can only load certificates from
|
||||
* OS cert store. If the certificate loading fails, we'll skip setting
|
||||
* certificate, so the SSL socket will create & use a self-signed cert.
|
||||
*/
|
||||
status = load_cert_from_store(pool, &cert);
|
||||
if (status == PJ_SUCCESS) {
|
||||
status = pj_ssl_sock_set_certificate(ssock_serv, pool, cert);
|
||||
if (status != PJ_SUCCESS) {
|
||||
goto on_return;
|
||||
}
|
||||
}
|
||||
#else
|
||||
{
|
||||
pj_str_t ca_file = pj_str(CERT_CA_FILE);
|
||||
pj_str_t cert_file = pj_str(CERT_FILE);
|
||||
|
@ -1416,11 +1296,39 @@ static int perf_test(unsigned clients, unsigned ms_handshake_timeout)
|
|||
}
|
||||
}
|
||||
|
||||
pj_ssl_sock_param_default(¶m);
|
||||
param.cb.on_accept_complete2 = &ssl_on_accept_complete;
|
||||
param.cb.on_connect_complete = &ssl_on_connect_complete;
|
||||
param.cb.on_data_read = &ssl_on_data_read;
|
||||
param.cb.on_data_sent = &ssl_on_data_sent;
|
||||
param.ioqueue = ioqueue;
|
||||
param.timer_heap = timer;
|
||||
param.timeout.sec = 0;
|
||||
param.timeout.msec = ms_handshake_timeout;
|
||||
pj_time_val_normalize(¶m.timeout);
|
||||
|
||||
/* Init default bind address */
|
||||
{
|
||||
pj_str_t tmp_st;
|
||||
pj_sockaddr_init(PJ_AF_INET, &addr, pj_strset2(&tmp_st, "127.0.0.1"), 0);
|
||||
}
|
||||
|
||||
/* SERVER */
|
||||
param.user_data = &state_serv;
|
||||
|
||||
state_serv.pool = pool;
|
||||
state_serv.echo = PJ_TRUE;
|
||||
state_serv.is_server = PJ_TRUE;
|
||||
|
||||
status = pj_ssl_sock_create(pool, ¶m, &ssock_serv);
|
||||
if (status != PJ_SUCCESS) {
|
||||
goto on_return;
|
||||
}
|
||||
|
||||
status = pj_ssl_sock_set_certificate(ssock_serv, pool, cert);
|
||||
if (status != PJ_SUCCESS) {
|
||||
goto on_return;
|
||||
}
|
||||
#endif
|
||||
|
||||
status = pj_ssl_sock_start_accept(ssock_serv, pool, &addr, pj_sockaddr_get_len(&addr));
|
||||
if (status != PJ_SUCCESS) {
|
||||
|
@ -1556,8 +1464,7 @@ static int perf_test(unsigned clients, unsigned ms_handshake_timeout)
|
|||
}
|
||||
|
||||
PJ_LOG(3, ("", ".....Clients: %d (%d errors)", clients, cli_err));
|
||||
PJ_LOG(3, ("", ".....Total sent/recv: %lu/%lu bytes",
|
||||
(unsigned long)tot_sent, (unsigned long)tot_recv));
|
||||
PJ_LOG(3, ("", ".....Total sent/recv: %lu/%lu bytes", tot_sent, tot_recv));
|
||||
|
||||
on_return:
|
||||
if (ssock_serv)
|
||||
|
@ -1624,15 +1531,6 @@ int ssl_sock_test(void)
|
|||
* which require SSL server, for now.
|
||||
*/
|
||||
|
||||
/* Schannel backend notes:
|
||||
* - currently it does not support ciphers settings, so we exclude tests
|
||||
* whose ciphers setting is specified.
|
||||
* - TLS protocol older than 1.0 is not supported, TLS 1.0 & 1.1 will be
|
||||
* disabled soon, TLS 1.3 is supported since Windows 11, so for now
|
||||
* we only include tests with TLS 1.2.
|
||||
*/
|
||||
|
||||
#if (PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
PJ_LOG(3,("", "..echo test w/ TLSv1 and PJ_TLS_RSA_WITH_AES_256_CBC_SHA cipher"));
|
||||
ret = echo_test(PJ_SSL_SOCK_PROTO_TLS1, PJ_SSL_SOCK_PROTO_TLS1,
|
||||
PJ_TLS_RSA_WITH_AES_256_CBC_SHA, PJ_TLS_RSA_WITH_AES_256_CBC_SHA,
|
||||
|
@ -1646,7 +1544,6 @@ int ssl_sock_test(void)
|
|||
PJ_FALSE, PJ_FALSE);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
PJ_LOG(3,("", "..echo test w/ compatible proto: server TLSv1.2 vs client TLSv1.2"));
|
||||
ret = echo_test(PJ_SSL_SOCK_PROTO_TLS1_2, PJ_SSL_SOCK_PROTO_TLS1_2,
|
||||
|
@ -1655,7 +1552,6 @@ int ssl_sock_test(void)
|
|||
if (ret != 0)
|
||||
return ret;
|
||||
|
||||
#if (PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
PJ_LOG(3,("", "..echo test w/ compatible proto: server TLSv1.2+1.3 vs client TLSv1.3"));
|
||||
ret = echo_test(PJ_SSL_SOCK_PROTO_TLS1_2 | PJ_SSL_SOCK_PROTO_TLS1_3, PJ_SSL_SOCK_PROTO_TLS1_3,
|
||||
-1, -1,
|
||||
|
@ -1669,10 +1565,9 @@ int ssl_sock_test(void)
|
|||
PJ_FALSE, PJ_FALSE);
|
||||
if (ret == 0)
|
||||
return PJ_EBUG;
|
||||
#endif
|
||||
|
||||
/* We can't set min/max proto for TLS protocol higher than 1.0. */
|
||||
#if (PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_DARWIN && PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
#if (PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_DARWIN)
|
||||
PJ_LOG(3,("", "..echo test w/ incompatible proto: server TLSv1.2 vs client TLSv1.3"));
|
||||
ret = echo_test(PJ_SSL_SOCK_PROTO_TLS1_2, PJ_SSL_SOCK_PROTO_TLS1_3,
|
||||
-1, -1,
|
||||
|
@ -1685,7 +1580,7 @@ int ssl_sock_test(void)
|
|||
* deprecated and we only have sec_protocol_options_append_tls_ciphersuite(),
|
||||
* but there's no API to remove certain or all ciphers.
|
||||
*/
|
||||
#if (PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_APPLE && PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
#if (PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_APPLE)
|
||||
PJ_LOG(3,("", "..echo test w/ incompatible ciphers"));
|
||||
ret = echo_test(PJ_SSL_SOCK_PROTO_DEFAULT, PJ_SSL_SOCK_PROTO_DEFAULT,
|
||||
PJ_TLS_RSA_WITH_DES_CBC_SHA, PJ_TLS_RSA_WITH_AES_256_CBC_SHA,
|
||||
|
@ -1694,7 +1589,6 @@ int ssl_sock_test(void)
|
|||
return PJ_EBUG;
|
||||
#endif
|
||||
|
||||
#if (PJ_SSL_SOCK_IMP != PJ_SSL_SOCK_IMP_SCHANNEL)
|
||||
PJ_LOG(3,("", "..echo test w/ client cert required but not provided"));
|
||||
ret = echo_test(PJ_SSL_SOCK_PROTO_DEFAULT, PJ_SSL_SOCK_PROTO_DEFAULT,
|
||||
PJ_TLS_RSA_WITH_AES_256_CBC_SHA, PJ_TLS_RSA_WITH_AES_256_CBC_SHA,
|
||||
|
@ -1708,7 +1602,6 @@ int ssl_sock_test(void)
|
|||
PJ_TRUE, PJ_TRUE);
|
||||
if (ret != 0)
|
||||
return ret;
|
||||
#endif
|
||||
|
||||
#if WITH_BENCHMARK
|
||||
PJ_LOG(3,("", "..performance test"));
|
||||
|
|
|
@ -68,7 +68,7 @@ static int test_timer_heap(void)
|
|||
pool = pj_pool_create( mem, NULL, size, 4000, NULL);
|
||||
if (!pool) {
|
||||
PJ_LOG(3,("test", "...error: unable to create pool of %lu bytes",
|
||||
(unsigned long)size));
|
||||
size));
|
||||
return -10;
|
||||
}
|
||||
|
||||
|
@ -161,8 +161,8 @@ static int test_timer_heap(void)
|
|||
} while (PJ_TIME_VAL_LTE(now, expire)&&pj_timer_heap_count(timer) > 0);
|
||||
|
||||
if (pj_timer_heap_count(timer)) {
|
||||
PJ_LOG(3, (THIS_FILE, "ERROR: %lu timers left",
|
||||
(unsigned long)pj_timer_heap_count(timer)));
|
||||
PJ_LOG(3, (THIS_FILE, "ERROR: %ld timers left",
|
||||
pj_timer_heap_count(timer)));
|
||||
++err;
|
||||
}
|
||||
t_sched.u32.lo /= count;
|
||||
|
@ -715,8 +715,8 @@ on_return:
|
|||
if (timer)
|
||||
pj_timer_heap_destroy(timer);
|
||||
|
||||
PJ_LOG(3,("test", "Total memory of timer heap: %lu",
|
||||
(unsigned long)pj_timer_heap_mem_size(ST_ENTRY_COUNT)));
|
||||
PJ_LOG(3,("test", "Total memory of timer heap: %ld",
|
||||
pj_timer_heap_mem_size(ST_ENTRY_COUNT)));
|
||||
|
||||
if (tparam.idx)
|
||||
pj_atomic_destroy(tparam.idx);
|
||||
|
|
|
@ -300,13 +300,6 @@ ifeq ($(AC_PJMEDIA_VIDEO_HAS_DARWIN),yes)
|
|||
export PJMEDIA_VIDEODEV_OBJS += darwin_dev.o
|
||||
endif
|
||||
|
||||
#
|
||||
# Metal video device
|
||||
#
|
||||
ifeq ($(AC_PJMEDIA_VIDEO_HAS_METAL),yes)
|
||||
export PJMEDIA_VIDEODEV_OBJS += metal_dev.o
|
||||
endif
|
||||
|
||||
#
|
||||
# VideoToolbox codec
|
||||
#
|
||||
|
|
|
@ -259,10 +259,6 @@ GENERATE_DEPRECATEDLIST= YES
|
|||
# You can put \n's in the value part of an alias to insert newlines.
|
||||
|
||||
ALIASES =
|
||||
ALIASES += src{1}="\verbatim embed:rst:inline :source:`\1` \endverbatim"
|
||||
ALIASES += srcdir{1}="\verbatim embed:rst:inline :sourcedir:`\1` \endverbatim"
|
||||
ALIASES += img{1}="<img src=\"https://raw.githubusercontent.com/pjsip/pjproject/master/\1\" />"
|
||||
ALIASES += img{2}="<img src=\"https://raw.githubusercontent.com/pjsip/pjproject/master/\1\" alt=\"\2\" />"
|
||||
|
||||
# The ENABLED_SECTIONS tag can be used to enable conditional
|
||||
# documentation sections, marked by \if sectionname ... \endif.
|
||||
|
|
|
@ -80,7 +80,7 @@
|
|||
of one WAV file to another. In this case, application would create and
|
||||
arrange media ports connection as follows:
|
||||
|
||||
\img{pjmedia/docs/sample-manual-resampling.jpg}
|
||||
\image html sample-manual-resampling.jpg
|
||||
|
||||
Application would setup the media ports using the following pseudo-
|
||||
code:
|
||||
|
|
|
@ -49,7 +49,7 @@
|
|||
* The connection between \ref PJMED_STRM and media transport is shown in
|
||||
* the diagram below:
|
||||
|
||||
\img{pjmedia/docs/media-transport.PNG}
|
||||
\image html media-transport.PNG
|
||||
|
||||
|
||||
* \section PJMEDIA_TRANSPORT_H_USING Basic Media Transport Usage
|
||||
|
@ -513,9 +513,6 @@ struct pjmedia_transport
|
|||
|
||||
/** Application/user data */
|
||||
void *user_data;
|
||||
|
||||
/** Group lock, for synchronization between destroy() & callbacks. */
|
||||
pj_grp_lock_t *grp_lock;
|
||||
};
|
||||
|
||||
/**
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
* media transport during stream creation), and the interconnection can be
|
||||
* depicted from the diagram below:
|
||||
*
|
||||
\img{pjmedia/docs/media-transport.PNG}
|
||||
\image html media-transport.PNG
|
||||
|
||||
* I think the diagram above is self-explanatory.
|
||||
*
|
||||
|
@ -53,7 +53,7 @@
|
|||
* sending/receiving RTP/RTCP packets. When SRTP is used, the interconnection
|
||||
* between stream and transport is like the diagram below:
|
||||
*
|
||||
\img{pjmedia/docs/media-srtp-transport.PNG}
|
||||
\image html media-srtp-transport.PNG
|
||||
|
||||
* So to stream, the SRTP transport behaves as if it is a media transport
|
||||
* (because it is a media transport), and to the media transport it behaves
|
||||
|
|
|
@ -58,11 +58,6 @@ typedef enum pjmedia_vid_dev_hwnd_type
|
|||
*/
|
||||
PJMEDIA_VID_DEV_HWND_TYPE_WINDOWS,
|
||||
|
||||
/**
|
||||
* Native view on Cocoa Mac.
|
||||
*/
|
||||
PJMEDIA_VID_DEV_HWND_TYPE_COCOA,
|
||||
|
||||
/**
|
||||
* Native view on iOS.
|
||||
*/
|
||||
|
|
|
@ -150,9 +150,9 @@ static int AndroidRecorderCallback(void *userData)
|
|||
{
|
||||
struct android_aud_stream *stream = (struct android_aud_stream *)userData;
|
||||
jmethodID read_method=0, record_method=0, stop_method=0;
|
||||
int size = stream->rec_buf_size / 2;
|
||||
jshortArray inputBuffer;
|
||||
jshort *buf;
|
||||
int size = stream->rec_buf_size;
|
||||
jbyteArray inputBuffer;
|
||||
jbyte *buf;
|
||||
JNIEnv *jni_env = 0;
|
||||
pj_bool_t attached = attach_jvm(&jni_env);
|
||||
|
||||
|
@ -166,7 +166,7 @@ static int AndroidRecorderCallback(void *userData)
|
|||
|
||||
/* Get methods ids */
|
||||
read_method = (*jni_env)->GetMethodID(jni_env, stream->record_class,
|
||||
"read", "([SII)I");
|
||||
"read", "([BII)I");
|
||||
record_method = (*jni_env)->GetMethodID(jni_env, stream->record_class,
|
||||
"startRecording", "()V");
|
||||
stop_method = (*jni_env)->GetMethodID(jni_env, stream->record_class,
|
||||
|
@ -177,7 +177,7 @@ static int AndroidRecorderCallback(void *userData)
|
|||
}
|
||||
|
||||
/* Create a buffer for frames read */
|
||||
inputBuffer = (*jni_env)->NewShortArray(jni_env, size);
|
||||
inputBuffer = (*jni_env)->NewByteArray(jni_env, size);
|
||||
if (inputBuffer == 0) {
|
||||
PJ_LOG(3, (THIS_FILE, "Unable to allocate input buffer"));
|
||||
goto on_return;
|
||||
|
@ -190,7 +190,7 @@ static int AndroidRecorderCallback(void *userData)
|
|||
while (!stream->quit_flag) {
|
||||
pjmedia_frame frame;
|
||||
pj_status_t status;
|
||||
int shortRead;
|
||||
int bytesRead;
|
||||
|
||||
if (!stream->running) {
|
||||
(*jni_env)->CallVoidMethod(jni_env, stream->record, stop_method);
|
||||
|
@ -200,25 +200,25 @@ static int AndroidRecorderCallback(void *userData)
|
|||
(*jni_env)->CallVoidMethod(jni_env, stream->record, record_method);
|
||||
}
|
||||
|
||||
shortRead = (*jni_env)->CallIntMethod(jni_env, stream->record,
|
||||
bytesRead = (*jni_env)->CallIntMethod(jni_env, stream->record,
|
||||
read_method, inputBuffer,
|
||||
0, size);
|
||||
if (shortRead <= 0 || shortRead != size) {
|
||||
if (bytesRead <= 0 || bytesRead != size) {
|
||||
PJ_LOG (4, (THIS_FILE, "Record thread : error %d reading data",
|
||||
shortRead));
|
||||
bytesRead));
|
||||
continue;
|
||||
}
|
||||
|
||||
buf = (*jni_env)->GetShortArrayElements(jni_env, inputBuffer, 0);
|
||||
buf = (*jni_env)->GetByteArrayElements(jni_env, inputBuffer, 0);
|
||||
frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
|
||||
frame.size = stream->rec_buf_size;
|
||||
frame.size = size;
|
||||
frame.bit_info = 0;
|
||||
frame.buf = (void *)buf;
|
||||
frame.timestamp.u64 = stream->rec_timestamp.u64;
|
||||
|
||||
status = (*stream->rec_cb)(stream->user_data, &frame);
|
||||
(*jni_env)->ReleaseShortArrayElements(jni_env, inputBuffer, buf,
|
||||
JNI_ABORT);
|
||||
(*jni_env)->ReleaseByteArrayElements(jni_env, inputBuffer, buf,
|
||||
JNI_ABORT);
|
||||
if (status != PJ_SUCCESS || stream->quit_flag)
|
||||
break;
|
||||
|
||||
|
@ -241,9 +241,9 @@ static int AndroidTrackCallback(void *userData)
|
|||
{
|
||||
struct android_aud_stream *stream = (struct android_aud_stream*) userData;
|
||||
jmethodID write_method=0, play_method=0, stop_method=0, flush_method=0;
|
||||
int size = stream->play_buf_size / 2;
|
||||
jshortArray outputBuffer;
|
||||
jshort *buf;
|
||||
int size = stream->play_buf_size;
|
||||
jbyteArray outputBuffer;
|
||||
jbyte *buf;
|
||||
JNIEnv *jni_env = 0;
|
||||
pj_bool_t attached = attach_jvm(&jni_env);
|
||||
|
||||
|
@ -255,7 +255,7 @@ static int AndroidTrackCallback(void *userData)
|
|||
|
||||
/* Get methods ids */
|
||||
write_method = (*jni_env)->GetMethodID(jni_env, stream->track_class,
|
||||
"write", "([SII)I");
|
||||
"write", "([BII)I");
|
||||
play_method = (*jni_env)->GetMethodID(jni_env, stream->track_class,
|
||||
"play", "()V");
|
||||
stop_method = (*jni_env)->GetMethodID(jni_env, stream->track_class,
|
||||
|
@ -269,12 +269,12 @@ static int AndroidTrackCallback(void *userData)
|
|||
goto on_return;
|
||||
}
|
||||
|
||||
outputBuffer = (*jni_env)->NewShortArray(jni_env, size);
|
||||
outputBuffer = (*jni_env)->NewByteArray(jni_env, size);
|
||||
if (outputBuffer == 0) {
|
||||
PJ_LOG(3, (THIS_FILE, "Unable to allocate output buffer"));
|
||||
goto on_return;
|
||||
}
|
||||
buf = (*jni_env)->GetShortArrayElements(jni_env, outputBuffer, 0);
|
||||
buf = (*jni_env)->GetByteArrayElements(jni_env, outputBuffer, 0);
|
||||
|
||||
/* Start playing */
|
||||
pj_thread_set_prio(NULL, THREAD_PRIORITY_URGENT_AUDIO);
|
||||
|
@ -283,7 +283,7 @@ static int AndroidTrackCallback(void *userData)
|
|||
while (!stream->quit_flag) {
|
||||
pjmedia_frame frame;
|
||||
pj_status_t status;
|
||||
int shortWritten;
|
||||
int bytesWritten;
|
||||
|
||||
if (!stream->running) {
|
||||
(*jni_env)->CallVoidMethod(jni_env, stream->track, stop_method);
|
||||
|
@ -295,7 +295,7 @@ static int AndroidTrackCallback(void *userData)
|
|||
}
|
||||
|
||||
frame.type = PJMEDIA_FRAME_TYPE_AUDIO;
|
||||
frame.size = stream->play_buf_size;
|
||||
frame.size = size;
|
||||
frame.buf = (void *)buf;
|
||||
frame.timestamp.u64 = stream->play_timestamp.u64;
|
||||
frame.bit_info = 0;
|
||||
|
@ -307,16 +307,16 @@ static int AndroidTrackCallback(void *userData)
|
|||
if (frame.type != PJMEDIA_FRAME_TYPE_AUDIO)
|
||||
pj_bzero(frame.buf, frame.size);
|
||||
|
||||
(*jni_env)->ReleaseShortArrayElements(jni_env, outputBuffer, buf,
|
||||
(*jni_env)->ReleaseByteArrayElements(jni_env, outputBuffer, buf,
|
||||
JNI_COMMIT);
|
||||
|
||||
/* Write to the device output. */
|
||||
shortWritten = (*jni_env)->CallIntMethod(jni_env, stream->track,
|
||||
bytesWritten = (*jni_env)->CallIntMethod(jni_env, stream->track,
|
||||
write_method, outputBuffer,
|
||||
0, size);
|
||||
if (shortWritten <= 0 || shortWritten != size) {
|
||||
if (bytesWritten <= 0 || bytesWritten != size) {
|
||||
PJ_LOG(4, (THIS_FILE, "Player thread: Error %d writing data",
|
||||
shortWritten));
|
||||
bytesWritten));
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -324,7 +324,7 @@ static int AndroidTrackCallback(void *userData)
|
|||
stream->param.channel_count;
|
||||
};
|
||||
|
||||
(*jni_env)->ReleaseShortArrayElements(jni_env, outputBuffer, buf, 0);
|
||||
(*jni_env)->ReleaseByteArrayElements(jni_env, outputBuffer, buf, 0);
|
||||
(*jni_env)->DeleteLocalRef(jni_env, outputBuffer);
|
||||
|
||||
on_return:
|
||||
|
@ -476,8 +476,7 @@ static pj_status_t android_create_stream(pjmedia_aud_dev_factory *f,
|
|||
|
||||
PJ_ASSERT_RETURN(param->channel_count >= 1 && param->channel_count <= 2,
|
||||
PJ_EINVAL);
|
||||
PJ_ASSERT_RETURN(/* param->bits_per_sample==8 || */
|
||||
param->bits_per_sample==16,
|
||||
PJ_ASSERT_RETURN(param->bits_per_sample==8 || param->bits_per_sample==16,
|
||||
PJ_EINVAL);
|
||||
PJ_ASSERT_RETURN(play_cb && rec_cb && p_aud_strm, PJ_EINVAL);
|
||||
|
||||
|
@ -501,11 +500,8 @@ static pj_status_t android_create_stream(pjmedia_aud_dev_factory *f,
|
|||
12 /*CHANNEL_IN_STEREO*/;
|
||||
channelOutCfg = (param->channel_count == 1)? 4 /*CHANNEL_OUT_MONO*/:
|
||||
12 /*CHANNEL_OUT_STEREO*/;
|
||||
|
||||
// The 8bit/byte read/write methods no longer support 16bit
|
||||
//sampleFormat = (param->bits_per_sample == 8)? 3 /*ENCODING_PCM_8BIT*/:
|
||||
// 2 /*ENCODING_PCM_16BIT*/;
|
||||
sampleFormat = 2 /*ENCODING_PCM_16BIT*/;
|
||||
sampleFormat = (param->bits_per_sample == 8)? 3 /*ENCODING_PCM_8BIT*/:
|
||||
2 /*ENCODING_PCM_16BIT*/;
|
||||
|
||||
attached = attach_jvm(&jni_env);
|
||||
|
||||
|
|
|
@ -29,12 +29,6 @@
|
|||
#define COREAUDIO_MAC 1
|
||||
#endif
|
||||
|
||||
#if (TARGET_OS_OSX && defined(__MAC_12_0))
|
||||
#define AUDIO_OBJECT_ELEMENT_MAIN kAudioObjectPropertyElementMain;
|
||||
#else
|
||||
#define AUDIO_OBJECT_ELEMENT_MAIN kAudioObjectPropertyElementMaster;
|
||||
#endif
|
||||
|
||||
#include <AudioUnit/AudioUnit.h>
|
||||
#include <AudioToolbox/AudioConverter.h>
|
||||
#if COREAUDIO_MAC
|
||||
|
@ -453,7 +447,7 @@ static pj_status_t ca_factory_refresh(pjmedia_aud_dev_factory *f)
|
|||
/* Find out how many audio devices there are */
|
||||
addr.mSelector = kAudioHardwarePropertyDevices;
|
||||
addr.mScope = kAudioObjectPropertyScopeGlobal;
|
||||
addr.mElement = AUDIO_OBJECT_ELEMENT_MAIN;
|
||||
addr.mElement = kAudioObjectPropertyElementMaster;
|
||||
ostatus = AudioObjectGetPropertyDataSize(kAudioObjectSystemObject, &addr,
|
||||
0, NULL, &dev_size);
|
||||
if (ostatus != noErr) {
|
||||
|
@ -498,7 +492,7 @@ static pj_status_t ca_factory_refresh(pjmedia_aud_dev_factory *f)
|
|||
/* Find default audio input device */
|
||||
addr.mSelector = kAudioHardwarePropertyDefaultInputDevice;
|
||||
addr.mScope = kAudioObjectPropertyScopeGlobal;
|
||||
addr.mElement = AUDIO_OBJECT_ELEMENT_MAIN;
|
||||
addr.mElement = kAudioObjectPropertyElementMaster;
|
||||
size = sizeof(dev_id);
|
||||
|
||||
ostatus = AudioObjectGetPropertyData(kAudioObjectSystemObject,
|
||||
|
@ -550,7 +544,7 @@ static pj_status_t ca_factory_refresh(pjmedia_aud_dev_factory *f)
|
|||
/* Get device name */
|
||||
addr.mSelector = kAudioDevicePropertyDeviceName;
|
||||
addr.mScope = kAudioObjectPropertyScopeGlobal;
|
||||
addr.mElement = AUDIO_OBJECT_ELEMENT_MAIN;
|
||||
addr.mElement = kAudioObjectPropertyElementMaster;
|
||||
size = sizeof(cdi->info.name);
|
||||
AudioObjectGetPropertyData(cdi->dev_id, &addr,
|
||||
0, NULL,
|
||||
|
|
|
@ -1141,8 +1141,7 @@ static pj_status_t and_media_codec_encode(pjmedia_codec *codec,
|
|||
} else {
|
||||
PJ_LOG(4,(THIS_FILE, "Encoder getInputBuffer "
|
||||
"size: %lu, expecting %d.",
|
||||
(unsigned long)output_size,
|
||||
input_size));
|
||||
output_size, input_size));
|
||||
}
|
||||
goto on_return;
|
||||
}
|
||||
|
@ -1263,8 +1262,7 @@ static pj_status_t and_media_codec_decode(pjmedia_codec *codec,
|
|||
&input_size);
|
||||
if (input_buf == 0) {
|
||||
PJ_LOG(4,(THIS_FILE, "Decoder getInputBuffer failed "
|
||||
"return input_buf=%d, size=%lu", *input_buf,
|
||||
(unsigned long)input_size));
|
||||
"return input_buf=%d, size=%lu", *input_buf, input_size));
|
||||
goto on_return;
|
||||
}
|
||||
|
||||
|
|
|
@ -1033,8 +1033,7 @@ static pj_status_t and_media_codec_encode_begin(pjmedia_vid_codec *codec,
|
|||
} else {
|
||||
PJ_LOG(4,(THIS_FILE, "Encoder getInputBuffer "
|
||||
"size: %lu, expecting %lu.",
|
||||
(unsigned long)output_size,
|
||||
(unsigned long)input->size));
|
||||
output_size, input->size));
|
||||
}
|
||||
goto on_return;
|
||||
}
|
||||
|
@ -1746,8 +1745,6 @@ static pj_status_t decode_h264(pjmedia_vid_codec *codec,
|
|||
buf_pos += frm_size;
|
||||
}
|
||||
|
||||
PJ_UNUSED_ARG(frm_cnt);
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -1182,7 +1182,7 @@ static pj_status_t oh264_codec_decode(pjmedia_vid_codec *codec,
|
|||
|
||||
PJ_LOG(5,(THIS_FILE, "Decode couldn't produce picture, "
|
||||
"input nframes=%lu, concatenated size=%d bytes, ret=%d",
|
||||
(unsigned long)count, whole_len, ret));
|
||||
count, whole_len, ret));
|
||||
}
|
||||
|
||||
return status;
|
||||
|
|
|
@ -931,7 +931,7 @@ static pj_status_t codec_parse( pjmedia_codec *codec,
|
|||
sizeof(tmp_buf));
|
||||
if (size < 0) {
|
||||
PJ_LOG(5, (THIS_FILE, "Parse failed! (pkt_size=%lu, err=%d)",
|
||||
(unsigned long)pkt_size, size));
|
||||
pkt_size, size));
|
||||
pj_mutex_unlock (opus_data->mutex);
|
||||
return PJMEDIA_CODEC_EFAILED;
|
||||
}
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#include <pjmedia/errno.h>
|
||||
#include <pjmedia/endpoint.h>
|
||||
#include <pjmedia/port.h>
|
||||
#include <speex/speex.h>
|
||||
#include <pj/assert.h>
|
||||
#include <pj/log.h>
|
||||
#include <pj/pool.h>
|
||||
|
@ -33,7 +34,6 @@
|
|||
*/
|
||||
#if defined(PJMEDIA_HAS_SPEEX_CODEC) && PJMEDIA_HAS_SPEEX_CODEC!=0
|
||||
|
||||
#include <speex/speex.h>
|
||||
|
||||
#define THIS_FILE "speex_codec.c"
|
||||
|
||||
|
|
|
@ -164,7 +164,7 @@ typedef struct vtool_codec_data
|
|||
pj_uint8_t *dec_buf;
|
||||
unsigned dec_buf_size;
|
||||
CMFormatDescriptionRef dec_format;
|
||||
OSStatus dec_status;
|
||||
OSStatus dec_status;
|
||||
|
||||
unsigned dec_sps_size;
|
||||
unsigned dec_pps_size;
|
||||
|
@ -554,20 +554,17 @@ static OSStatus create_encoder(vtool_codec_data *vtool_data)
|
|||
|
||||
ret = VTSessionCopySupportedPropertyDictionary(vtool_data->enc,
|
||||
&supported_prop);
|
||||
if (ret == noErr) {
|
||||
if (CFDictionaryContainsKey(supported_prop,
|
||||
if (ret == noErr &&
|
||||
CFDictionaryContainsKey(supported_prop,
|
||||
kVTCompressionPropertyKey_MaxH264SliceBytes))
|
||||
{
|
||||
/* kVTCompressionPropertyKey_MaxH264SliceBytes is not yet supported
|
||||
* by Apple. We leave it here for possible future enhancements.
|
||||
SET_PROPERTY(vtool_data->enc,
|
||||
kVTCompressionPropertyKey_MaxH264SliceBytes,
|
||||
// param->enc_mtu - NAL_HEADER_ADD_0X30BYTES
|
||||
(__bridge CFTypeRef)@(param->enc_mtu - 50));
|
||||
*/
|
||||
}
|
||||
|
||||
CFRelease(supported_prop);
|
||||
{
|
||||
/* kVTCompressionPropertyKey_MaxH264SliceBytes is not yet supported
|
||||
* by Apple. We leave it here for possible future enhancements.
|
||||
SET_PROPERTY(vtool_data->enc,
|
||||
kVTCompressionPropertyKey_MaxH264SliceBytes,
|
||||
// param->enc_mtu - NAL_HEADER_ADD_0X30BYTES
|
||||
(__bridge CFTypeRef)@(param->enc_mtu - 50));
|
||||
*/
|
||||
}
|
||||
|
||||
VTCompressionSessionPrepareToEncodeFrames(vtool_data->enc);
|
||||
|
@ -1045,7 +1042,7 @@ static void decode_cb(void *decompressionOutputRefCon,
|
|||
CMTime presentationDuration)
|
||||
{
|
||||
struct vtool_codec_data *vtool_data;
|
||||
pj_size_t width, height, len = 0;
|
||||
pj_size_t width, height, len;
|
||||
|
||||
/* This callback can be called from another, unregistered thread.
|
||||
* So do not call pjlib functions here.
|
||||
|
@ -1071,12 +1068,7 @@ static void decode_cb(void *decompressionOutputRefCon,
|
|||
vtool_data->dec_fmt_change = PJ_FALSE;
|
||||
}
|
||||
|
||||
if (vtool_data->dec_frame->size >= width * height * 3 / 2) {
|
||||
len = process_i420(imageBuffer,
|
||||
(pj_uint8_t *)vtool_data->dec_frame->buf);
|
||||
} else {
|
||||
vtool_data->dec_status = (OSStatus)PJMEDIA_CODEC_EFRMTOOSHORT;
|
||||
}
|
||||
len = process_i420(imageBuffer, (pj_uint8_t *)vtool_data->dec_frame->buf);
|
||||
vtool_data->dec_frame->size = len;
|
||||
|
||||
CVPixelBufferUnlockBaseAddress(imageBuffer,0);
|
||||
|
@ -1316,7 +1308,6 @@ static pj_status_t vtool_codec_decode(pjmedia_vid_codec *codec,
|
|||
|
||||
if (ret == noErr) {
|
||||
vtool_data->dec_frame = output;
|
||||
vtool_data->dec_frame->size = out_size;
|
||||
ret = VTDecompressionSessionDecodeFrame(
|
||||
vtool_data->dec, sample_buf, 0,
|
||||
NULL, NULL);
|
||||
|
@ -1354,9 +1345,8 @@ static pj_status_t vtool_codec_decode(pjmedia_vid_codec *codec,
|
|||
}
|
||||
|
||||
if ((ret != noErr) || (vtool_data->dec_status != noErr)) {
|
||||
char *ret_err = (ret != noErr)?"decode err":"cb err";
|
||||
OSStatus err_code = (ret != noErr)? ret:
|
||||
vtool_data->dec_status;
|
||||
char *ret_err = (ret != noErr)?"decode err":"cb err";
|
||||
OSStatus err_code = (ret != noErr)?ret:vtool_data->dec_status;
|
||||
|
||||
PJ_LOG(5,(THIS_FILE, "Failed to decode frame %d of size "
|
||||
"%d %s:%d", nalu_type, frm_size, ret_err,
|
||||
|
@ -1407,8 +1397,8 @@ on_return:
|
|||
PJMEDIA_EVENT_PUBLISH_DEFAULT);
|
||||
|
||||
PJ_LOG(5,(THIS_FILE, "Decode couldn't produce picture, "
|
||||
"input nframes=%lu, concatenated size=%d bytes",
|
||||
(unsigned long)count, whole_len));
|
||||
"input nframes=%ld, concatenated size=%d bytes",
|
||||
count, whole_len));
|
||||
|
||||
output->type = PJMEDIA_FRAME_TYPE_NONE;
|
||||
output->size = 0;
|
||||
|
|
|
@ -830,7 +830,7 @@ on_return:
|
|||
|
||||
PJ_LOG(4,(THIS_FILE, "Decode couldn't produce picture, "
|
||||
"input nframes=%lu, concatenated size=%d bytes",
|
||||
(unsigned long)count, whole_len));
|
||||
count, whole_len));
|
||||
|
||||
output->type = PJMEDIA_FRAME_TYPE_NONE;
|
||||
output->size = 0;
|
||||
|
|
|
@ -313,34 +313,23 @@ static pj_status_t darwin_factory_refresh(pjmedia_vid_dev_factory *f)
|
|||
if (NSClassFromString(@"AVCaptureSession")) {
|
||||
NSArray *dev_list = NULL;
|
||||
|
||||
if (@available(macOS 10.15, iOS 10.0, *)) {
|
||||
#if (TARGET_OS_IPHONE && defined(__IPHONE_10_0)) || \
|
||||
(TARGET_OS_OSX && defined(__MAC_10_15))
|
||||
if (__builtin_available(macOS 10.15, iOS 10.0, *)) {
|
||||
/* Starting in iOS 10 and macOS 10.15, [AVCaptureDevice devices]
|
||||
* is deprecated and replaced by AVCaptureDeviceDiscoverySession.
|
||||
*/
|
||||
AVCaptureDeviceDiscoverySession *dds;
|
||||
NSMutableArray<AVCaptureDeviceType> *dev_types =
|
||||
[NSMutableArray arrayWithCapacity:5];
|
||||
|
||||
[dev_types addObject:AVCaptureDeviceTypeBuiltInWideAngleCamera];
|
||||
NSArray<AVCaptureDeviceType> *dev_types =
|
||||
@[AVCaptureDeviceTypeBuiltInWideAngleCamera
|
||||
#if TARGET_OS_OSX && defined(__MAC_10_15)
|
||||
, AVCaptureDeviceTypeExternalUnknown
|
||||
#endif
|
||||
#if TARGET_OS_IPHONE && defined(__IPHONE_10_0)
|
||||
// Deprecated in iOS 10.2
|
||||
// AVCaptureDeviceTypeBuiltInDuoCamera
|
||||
[dev_types addObject:AVCaptureDeviceTypeBuiltInTelephotoCamera];
|
||||
#endif
|
||||
|
||||
#if (TARGET_OS_IPHONE && defined(__IPHONE_17_0)) || \
|
||||
(TARGET_OS_OSX && defined(__MAC_14_0))
|
||||
if (@available(macOS 14.0, iOS 17.0, *)) {
|
||||
[dev_types addObject:AVCaptureDeviceTypeExternal];
|
||||
} else {
|
||||
# if (TARGET_OS_OSX && __MAC_OS_X_VERSION_MIN_REQUIRED < 140000)
|
||||
[dev_types addObject:AVCaptureDeviceTypeExternalUnknown];
|
||||
# endif
|
||||
}
|
||||
|
||||
#elif TARGET_OS_OSX
|
||||
[dev_types addObject:AVCaptureDeviceTypeExternalUnknown];
|
||||
, AVCaptureDeviceTypeBuiltInDuoCamera
|
||||
, AVCaptureDeviceTypeBuiltInTelephotoCamera
|
||||
#endif
|
||||
];
|
||||
|
||||
dds = [AVCaptureDeviceDiscoverySession
|
||||
discoverySessionWithDeviceTypes:dev_types
|
||||
|
@ -349,11 +338,13 @@ static pj_status_t darwin_factory_refresh(pjmedia_vid_dev_factory *f)
|
|||
|
||||
dev_list = [dds devices];
|
||||
} else {
|
||||
#if (TARGET_OS_OSX && __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_15) || \
|
||||
(TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED < __IPHONE_10_0)
|
||||
#if __MAC_OS_X_VERSION_MIN_REQUIRED < __MAC_10_15
|
||||
dev_list = [AVCaptureDevice devices];
|
||||
#endif
|
||||
}
|
||||
#else
|
||||
dev_list = [AVCaptureDevice devices];
|
||||
#endif
|
||||
|
||||
for (AVCaptureDevice *device in dev_list) {
|
||||
if (![device hasMediaType:AVMediaTypeVideo] ||
|
||||
|
@ -1049,32 +1040,6 @@ static pj_status_t darwin_stream_get_cap(pjmedia_vid_dev_stream *s,
|
|||
return PJMEDIA_EVID_INVCAP;
|
||||
}
|
||||
|
||||
static pj_bool_t set_orientation(struct darwin_stream *strm)
|
||||
{
|
||||
#if (TARGET_OS_OSX && __MAC_OS_X_VERSION_MIN_REQUIRED < 140000) || \
|
||||
(TARGET_OS_IPHONE && __IPHONE_OS_VERSION_MIN_REQUIRED < 170000)
|
||||
|
||||
const AVCaptureVideoOrientation cap_ori[4] =
|
||||
{
|
||||
AVCaptureVideoOrientationLandscapeLeft, /* NATURAL */
|
||||
AVCaptureVideoOrientationPortrait, /* 90DEG */
|
||||
AVCaptureVideoOrientationLandscapeRight, /* 180DEG */
|
||||
AVCaptureVideoOrientationPortraitUpsideDown, /* 270DEG */
|
||||
};
|
||||
AVCaptureConnection *vidcon;
|
||||
|
||||
vidcon = [strm->video_output
|
||||
connectionWithMediaType:AVMediaTypeVideo];
|
||||
if ([vidcon isVideoOrientationSupported]) {
|
||||
vidcon.videoOrientation = cap_ori[strm->param.orient-1];
|
||||
return PJ_TRUE;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
return PJ_FALSE;
|
||||
}
|
||||
|
||||
/* API: set capability */
|
||||
static pj_status_t darwin_stream_set_cap(pjmedia_vid_dev_stream *s,
|
||||
pjmedia_vid_dev_cap cap,
|
||||
|
@ -1277,7 +1242,6 @@ static pj_status_t darwin_stream_set_cap(pjmedia_vid_dev_stream *s,
|
|||
case PJMEDIA_VID_DEV_CAP_ORIENTATION:
|
||||
{
|
||||
pjmedia_orient orient = *(pjmedia_orient *)pval;
|
||||
pj_bool_t support_ori = PJ_FALSE;
|
||||
|
||||
pj_assert(orient >= PJMEDIA_ORIENT_UNKNOWN &&
|
||||
orient <= PJMEDIA_ORIENT_ROTATE_270DEG);
|
||||
|
@ -1299,35 +1263,30 @@ static pj_status_t darwin_stream_set_cap(pjmedia_vid_dev_stream *s,
|
|||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
const AVCaptureVideoOrientation cap_ori[4] =
|
||||
{
|
||||
AVCaptureVideoOrientationLandscapeLeft, /* NATURAL */
|
||||
AVCaptureVideoOrientationPortrait, /* 90DEG */
|
||||
AVCaptureVideoOrientationLandscapeRight, /* 180DEG */
|
||||
AVCaptureVideoOrientationPortraitUpsideDown, /* 270DEG */
|
||||
};
|
||||
AVCaptureConnection *vidcon;
|
||||
pj_bool_t support_ori = PJ_TRUE;
|
||||
|
||||
pj_assert(strm->param.dir == PJMEDIA_DIR_CAPTURE);
|
||||
|
||||
|
||||
if (!strm->video_output)
|
||||
return PJMEDIA_EVID_NOTREADY;
|
||||
|
||||
#if (TARGET_OS_IPHONE && defined(__IPHONE_17_0)) || \
|
||||
(TARGET_OS_OSX && defined(__MAC_14_0))
|
||||
if (@available(macOS 14.0, iOS 17.0, *)) {
|
||||
|
||||
const CGFloat cap_ori[4] = { 0, 90, 180, 270};
|
||||
AVCaptureConnection *vidcon;
|
||||
|
||||
vidcon = [strm->video_output
|
||||
connectionWithMediaType:AVMediaTypeVideo];
|
||||
if ([vidcon isVideoRotationAngleSupported:
|
||||
cap_ori[strm->param.orient-1]])
|
||||
{
|
||||
vidcon.videoRotationAngle = cap_ori[strm->param.orient-1];
|
||||
support_ori = PJ_TRUE;
|
||||
}
|
||||
|
||||
vidcon = [strm->video_output
|
||||
connectionWithMediaType:AVMediaTypeVideo];
|
||||
if ([vidcon isVideoOrientationSupported]) {
|
||||
vidcon.videoOrientation = cap_ori[strm->param.orient-1];
|
||||
} else {
|
||||
support_ori = set_orientation(strm);
|
||||
support_ori = PJ_FALSE;
|
||||
}
|
||||
#else
|
||||
support_ori = set_orientation(strm);
|
||||
#endif
|
||||
|
||||
|
||||
if (!strm->conv.conv) {
|
||||
pj_status_t status;
|
||||
pjmedia_rect_size orig_size;
|
||||
|
|
|
@ -1,971 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2024 Teluu Inc. (http://www.teluu.com)
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
#include "util.h"
|
||||
#include <pjmedia-videodev/videodev_imp.h>
|
||||
#include <pj/assert.h>
|
||||
#include <pj/log.h>
|
||||
#include <pj/os.h>
|
||||
|
||||
#if defined(PJMEDIA_HAS_VIDEO) && PJMEDIA_HAS_VIDEO != 0 && \
|
||||
defined(PJMEDIA_VIDEO_DEV_HAS_METAL) && PJMEDIA_VIDEO_DEV_HAS_METAL != 0
|
||||
|
||||
#import "MetalKit/MetalKit.h"
|
||||
#include "TargetConditionals.h"
|
||||
|
||||
#define THIS_FILE "metal_dev.m"
|
||||
#define DEFAULT_CLOCK_RATE 90000
|
||||
#define DEFAULT_WIDTH 640
|
||||
#define DEFAULT_HEIGHT 480
|
||||
#define DEFAULT_FPS 15
|
||||
|
||||
#if TARGET_OS_IPHONE
|
||||
# define NSView UIView
|
||||
# define NSWindow UIWindow
|
||||
#endif
|
||||
|
||||
typedef struct metal_fmt_info
|
||||
{
|
||||
pjmedia_format_id pjmedia_format;
|
||||
MTLPixelFormat metal_format;
|
||||
} metal_fmt_info;
|
||||
|
||||
static metal_fmt_info metal_fmts[] =
|
||||
{
|
||||
{ PJMEDIA_FORMAT_BGRA, MTLPixelFormatBGRA8Unorm },
|
||||
{ PJMEDIA_FORMAT_RGBA, MTLPixelFormatRGBA8Unorm },
|
||||
};
|
||||
|
||||
struct metal_dev_info
|
||||
{
|
||||
pjmedia_vid_dev_info info;
|
||||
};
|
||||
|
||||
/* metal factory */
|
||||
struct metal_factory
|
||||
{
|
||||
pjmedia_vid_dev_factory base;
|
||||
pj_pool_t *pool;
|
||||
pj_pool_factory *pf;
|
||||
|
||||
unsigned dev_count;
|
||||
struct metal_dev_info dev_info[1];
|
||||
};
|
||||
|
||||
@interface MetalRenderer : NSObject<MTKViewDelegate>
|
||||
@end
|
||||
|
||||
/* Video stream. */
|
||||
struct metal_stream
|
||||
{
|
||||
pjmedia_vid_dev_stream base; /**< Base stream */
|
||||
pjmedia_vid_dev_param param; /**< Settings */
|
||||
pj_pool_t *pool; /**< Memory pool */
|
||||
struct metal_factory *factory; /**< Factory */
|
||||
|
||||
pjmedia_vid_dev_cb vid_cb; /**< Stream callback */
|
||||
void *user_data; /**< Application data */
|
||||
|
||||
pjmedia_rect_size size;
|
||||
unsigned bytes_per_row;
|
||||
unsigned frame_size; /**< Frame size (bytes)*/
|
||||
pj_bool_t is_planar;
|
||||
|
||||
pjmedia_vid_dev_conv conv;
|
||||
pjmedia_rect_size vid_size;
|
||||
|
||||
MetalRenderer *renderer;
|
||||
MTKView *view;
|
||||
MTLPixelFormat format;
|
||||
|
||||
NSWindow *window;
|
||||
|
||||
pj_bool_t is_running;
|
||||
pj_bool_t is_rendering;
|
||||
void *render_buf;
|
||||
pj_size_t render_buf_size;
|
||||
|
||||
pj_timestamp frame_ts;
|
||||
unsigned ts_inc;
|
||||
};
|
||||
|
||||
|
||||
/* Prototypes */
|
||||
static pj_status_t metal_factory_init(pjmedia_vid_dev_factory *f);
|
||||
static pj_status_t metal_factory_destroy(pjmedia_vid_dev_factory *f);
|
||||
static pj_status_t metal_factory_refresh(pjmedia_vid_dev_factory *f);
|
||||
static unsigned metal_factory_get_dev_count(pjmedia_vid_dev_factory *f);
|
||||
static pj_status_t metal_factory_get_dev_info(pjmedia_vid_dev_factory *f,
|
||||
unsigned index,
|
||||
pjmedia_vid_dev_info *info);
|
||||
static pj_status_t metal_factory_default_param(pj_pool_t *pool,
|
||||
pjmedia_vid_dev_factory *f,
|
||||
unsigned index,
|
||||
pjmedia_vid_dev_param *param);
|
||||
static pj_status_t metal_factory_create_stream(
|
||||
pjmedia_vid_dev_factory *f,
|
||||
pjmedia_vid_dev_param *param,
|
||||
const pjmedia_vid_dev_cb *cb,
|
||||
void *user_data,
|
||||
pjmedia_vid_dev_stream **p_vid_strm);
|
||||
|
||||
static pj_status_t metal_stream_get_param(pjmedia_vid_dev_stream *strm,
|
||||
pjmedia_vid_dev_param *param);
|
||||
static pj_status_t metal_stream_get_cap(pjmedia_vid_dev_stream *strm,
|
||||
pjmedia_vid_dev_cap cap,
|
||||
void *value);
|
||||
static pj_status_t metal_stream_set_cap(pjmedia_vid_dev_stream *strm,
|
||||
pjmedia_vid_dev_cap cap,
|
||||
const void *value);
|
||||
static pj_status_t metal_stream_start(pjmedia_vid_dev_stream *strm);
|
||||
static pj_status_t metal_stream_put_frame(pjmedia_vid_dev_stream *strm,
|
||||
const pjmedia_frame *frame);
|
||||
static pj_status_t metal_stream_stop(pjmedia_vid_dev_stream *strm);
|
||||
static pj_status_t metal_stream_destroy(pjmedia_vid_dev_stream *strm);
|
||||
|
||||
/* Operations */
|
||||
static pjmedia_vid_dev_factory_op factory_op =
|
||||
{
|
||||
&metal_factory_init,
|
||||
&metal_factory_destroy,
|
||||
&metal_factory_get_dev_count,
|
||||
&metal_factory_get_dev_info,
|
||||
&metal_factory_default_param,
|
||||
&metal_factory_create_stream,
|
||||
&metal_factory_refresh
|
||||
};
|
||||
|
||||
static pjmedia_vid_dev_stream_op stream_op =
|
||||
{
|
||||
&metal_stream_get_param,
|
||||
&metal_stream_get_cap,
|
||||
&metal_stream_set_cap,
|
||||
&metal_stream_start,
|
||||
NULL,
|
||||
&metal_stream_put_frame,
|
||||
&metal_stream_stop,
|
||||
&metal_stream_destroy
|
||||
};
|
||||
|
||||
static void dispatch_sync_on_main_queue(void (^block)(void))
|
||||
{
|
||||
if ([NSThread isMainThread]) {
|
||||
block();
|
||||
} else {
|
||||
dispatch_sync(dispatch_get_main_queue(), block);
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
* Factory operations
|
||||
*/
|
||||
/*
|
||||
* Init metal_ video driver.
|
||||
*/
|
||||
pjmedia_vid_dev_factory* pjmedia_metal_factory(pj_pool_factory *pf)
|
||||
{
|
||||
struct metal_factory *f;
|
||||
pj_pool_t *pool;
|
||||
|
||||
pool = pj_pool_create(pf, "metal video", 8000, 4000, NULL);
|
||||
f = PJ_POOL_ZALLOC_T(pool, struct metal_factory);
|
||||
f->pf = pf;
|
||||
f->pool = pool;
|
||||
f->base.op = &factory_op;
|
||||
|
||||
return &f->base;
|
||||
}
|
||||
|
||||
|
||||
/* API: init factory */
|
||||
static pj_status_t metal_factory_init(pjmedia_vid_dev_factory *f)
|
||||
{
|
||||
return metal_factory_refresh(f);
|
||||
}
|
||||
|
||||
/* API: destroy factory */
|
||||
static pj_status_t metal_factory_destroy(pjmedia_vid_dev_factory *f)
|
||||
{
|
||||
struct metal_factory *qf = (struct metal_factory*)f;
|
||||
pj_pool_t *pool = qf->pool;
|
||||
|
||||
qf->pool = NULL;
|
||||
pj_pool_release(pool);
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
/* API: refresh the list of devices */
|
||||
static pj_status_t metal_factory_refresh(pjmedia_vid_dev_factory *f)
|
||||
{
|
||||
struct metal_factory *qf = (struct metal_factory*)f;
|
||||
|
||||
if (@available(macOS 10.14, iOS 12.0, *)) {
|
||||
struct metal_dev_info *qdi;
|
||||
unsigned l;
|
||||
id<MTLDevice> device;
|
||||
|
||||
device = MTLCreateSystemDefaultDevice();
|
||||
if (!device) {
|
||||
PJ_LOG(3, (THIS_FILE, "No Metal device found"));
|
||||
return PJ_SUCCESS;
|
||||
} else {
|
||||
[device release];
|
||||
}
|
||||
|
||||
/* Init output device */
|
||||
qdi = &qf->dev_info[qf->dev_count++];
|
||||
pj_bzero(qdi, sizeof(*qdi));
|
||||
pj_ansi_strxcpy(qdi->info.name, "Metal", sizeof(qdi->info.name));
|
||||
pj_ansi_strxcpy(qdi->info.driver, "Apple", sizeof(qdi->info.driver));
|
||||
qdi->info.dir = PJMEDIA_DIR_RENDER;
|
||||
qdi->info.has_callback = PJ_FALSE;
|
||||
|
||||
/* Set supported formats */
|
||||
qdi->info.caps |= PJMEDIA_VID_DEV_CAP_FORMAT |
|
||||
PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW |
|
||||
PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE |
|
||||
PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION |
|
||||
PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE |
|
||||
PJMEDIA_VID_DEV_CAP_ORIENTATION;
|
||||
|
||||
for (l = 0; l < PJ_ARRAY_SIZE(metal_fmts); l++) {
|
||||
pjmedia_format *fmt = &qdi->info.fmt[qdi->info.fmt_cnt++];
|
||||
pjmedia_format_init_video(fmt, metal_fmts[l].pjmedia_format,
|
||||
DEFAULT_WIDTH, DEFAULT_HEIGHT,
|
||||
DEFAULT_FPS, 1);
|
||||
}
|
||||
}
|
||||
|
||||
PJ_LOG(4, (THIS_FILE, "Metal video initialized with %d devices",
|
||||
qf->dev_count));
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
/* API: get number of devices */
|
||||
static unsigned metal_factory_get_dev_count(pjmedia_vid_dev_factory *f)
|
||||
{
|
||||
struct metal_factory *qf = (struct metal_factory*)f;
|
||||
return qf->dev_count;
|
||||
}
|
||||
|
||||
/* API: get device info */
|
||||
static pj_status_t metal_factory_get_dev_info(pjmedia_vid_dev_factory *f,
|
||||
unsigned index,
|
||||
pjmedia_vid_dev_info *info)
|
||||
{
|
||||
struct metal_factory *qf = (struct metal_factory*)f;
|
||||
|
||||
PJ_ASSERT_RETURN(index < qf->dev_count, PJMEDIA_EVID_INVDEV);
|
||||
|
||||
pj_memcpy(info, &qf->dev_info[index].info, sizeof(*info));
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
/* API: create default device parameter */
|
||||
static pj_status_t metal_factory_default_param(pj_pool_t *pool,
|
||||
pjmedia_vid_dev_factory *f,
|
||||
unsigned index,
|
||||
pjmedia_vid_dev_param *param)
|
||||
{
|
||||
struct metal_factory *qf = (struct metal_factory*)f;
|
||||
struct metal_dev_info *di;
|
||||
|
||||
PJ_ASSERT_RETURN(index < qf->dev_count, PJMEDIA_EVID_INVDEV);
|
||||
PJ_UNUSED_ARG(pool);
|
||||
|
||||
di = &qf->dev_info[index];
|
||||
|
||||
pj_bzero(param, sizeof(*param));
|
||||
if (di->info.dir & PJMEDIA_DIR_RENDER) {
|
||||
param->dir = PJMEDIA_DIR_RENDER;
|
||||
param->rend_id = index;
|
||||
param->cap_id = PJMEDIA_VID_INVALID_DEV;
|
||||
} else {
|
||||
return PJMEDIA_EVID_INVDEV;
|
||||
}
|
||||
|
||||
param->flags = PJMEDIA_VID_DEV_CAP_FORMAT;
|
||||
param->clock_rate = DEFAULT_CLOCK_RATE;
|
||||
pj_memcpy(¶m->fmt, &di->info.fmt[0], sizeof(param->fmt));
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
@implementation MetalRenderer
|
||||
{
|
||||
MTKView *_view;
|
||||
id<MTLDevice> device;
|
||||
id<MTLCommandQueue> commandQueue;
|
||||
id<MTLRenderPipelineState> pipelineState;
|
||||
id<MTLBuffer> vertexBuffer;
|
||||
id<MTLBuffer> textureCoordBuffer;
|
||||
|
||||
@public
|
||||
struct metal_stream *stream;
|
||||
}
|
||||
|
||||
#define _STRINGIFY( _x ) # _x
|
||||
|
||||
- (nonnull instancetype)initWithMetalKitView:(nonnull MTKView *)mtkView
|
||||
{
|
||||
self = [super init];
|
||||
if (self) {
|
||||
NSString *code;
|
||||
NSError *error = nil;
|
||||
id<MTLLibrary> shaderLibrary;
|
||||
id <MTLFunction> fragmentProgram;
|
||||
id <MTLFunction> vertexProgram;
|
||||
MTLRenderPipelineDescriptor *pQuadPipelineStateDescriptor;
|
||||
|
||||
/* Create a buffer for a full-screen quad */
|
||||
static const float vertexData[] = {
|
||||
-1.0, -1.0, 0.0, 1.0,
|
||||
1.0, -1.0, 0.0, 1.0,
|
||||
-1.0, 1.0, 0.0, 1.0,
|
||||
1.0, 1.0, 0.0, 1.0,
|
||||
};
|
||||
|
||||
/* Create texture coordinates for a full-screen quad */
|
||||
static const float textureCoordinates[] = {
|
||||
0.0, 1.0,
|
||||
1.0, 1.0,
|
||||
0.0, 0.0,
|
||||
1.0, 0.0,
|
||||
};
|
||||
|
||||
_view = mtkView;
|
||||
device = mtkView.device;
|
||||
/* Create the command queue */
|
||||
commandQueue = [device newCommandQueue];
|
||||
|
||||
/* Metal shader code */
|
||||
code = [NSString stringWithFormat:@"#include <metal_stdlib>\n%s",
|
||||
_STRINGIFY(
|
||||
using namespace metal;
|
||||
|
||||
struct VertexInOut
|
||||
{
|
||||
float4 m_Position [[position]];
|
||||
float2 m_TexCoord [[user(texturecoord)]];
|
||||
};
|
||||
|
||||
vertex VertexInOut
|
||||
texturedVertex(constant float4 *pPosition [[ buffer(0) ]],
|
||||
constant packed_float2 *pTexCoords [[ buffer(1) ]],
|
||||
constant float4x4 *pMVP [[ buffer(2) ]],
|
||||
uint vid [[ vertex_id ]])
|
||||
{
|
||||
VertexInOut outVertices;
|
||||
|
||||
outVertices.m_Position = pPosition[vid];
|
||||
outVertices.m_TexCoord = pTexCoords[vid];
|
||||
|
||||
return outVertices;
|
||||
}
|
||||
|
||||
fragment half4
|
||||
texturedFrag(VertexInOut inFrag [[ stage_in ]],
|
||||
texture2d<half> tex2D [[ texture(0) ]])
|
||||
{
|
||||
constexpr sampler quad_sampler;
|
||||
half4 color = tex2D.sample(quad_sampler, inFrag.m_TexCoord);
|
||||
|
||||
return color;
|
||||
}
|
||||
)];
|
||||
|
||||
/* Create a Metal library instance by compiling the code */
|
||||
shaderLibrary = [device newLibraryWithSource:code options:nil
|
||||
error:&error];
|
||||
if (error) {
|
||||
NSLog(@"Unable to create Metal library err: %@", error);
|
||||
return self;
|
||||
}
|
||||
|
||||
fragmentProgram = [shaderLibrary newFunctionWithName:@"texturedFrag"];
|
||||
vertexProgram = [shaderLibrary newFunctionWithName:@"texturedVertex"];
|
||||
if (!fragmentProgram || !vertexProgram) {
|
||||
NSLog(@"Unable to load Metal functions");
|
||||
return self;
|
||||
}
|
||||
|
||||
/* Create a pipeline state */
|
||||
pQuadPipelineStateDescriptor = [MTLRenderPipelineDescriptor new];
|
||||
pQuadPipelineStateDescriptor.colorAttachments[0].pixelFormat =
|
||||
stream->format;
|
||||
pQuadPipelineStateDescriptor.vertexFunction = vertexProgram;
|
||||
pQuadPipelineStateDescriptor.fragmentFunction = fragmentProgram;
|
||||
|
||||
pipelineState = [device
|
||||
newRenderPipelineStateWithDescriptor:pQuadPipelineStateDescriptor
|
||||
error:&error];
|
||||
if (error) {
|
||||
NSLog(@"newRenderPipelineStateWithDescriptor err: %@", error);
|
||||
return self;
|
||||
}
|
||||
|
||||
vertexBuffer = [device newBufferWithBytes:vertexData
|
||||
length:sizeof(vertexData)
|
||||
options:MTLResourceStorageModeShared];
|
||||
|
||||
textureCoordBuffer = [device newBufferWithBytes:textureCoordinates
|
||||
length:sizeof(textureCoordinates)
|
||||
options:MTLResourceStorageModeShared];
|
||||
|
||||
[pQuadPipelineStateDescriptor release];
|
||||
[fragmentProgram release];
|
||||
[vertexProgram release];
|
||||
[shaderLibrary release];
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)dealloc {
|
||||
if (vertexBuffer) {
|
||||
[vertexBuffer release];
|
||||
vertexBuffer = nil;
|
||||
}
|
||||
if (textureCoordBuffer) {
|
||||
[textureCoordBuffer release];
|
||||
textureCoordBuffer = nil;
|
||||
}
|
||||
if (device) {
|
||||
[device release];
|
||||
device = nil;
|
||||
}
|
||||
if (commandQueue) {
|
||||
[commandQueue release];
|
||||
commandQueue = nil;
|
||||
}
|
||||
if (pipelineState) {
|
||||
[pipelineState release];
|
||||
pipelineState = nil;
|
||||
}
|
||||
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
- (void)update_image
|
||||
{
|
||||
MTLRenderPassDescriptor *renderPassDescriptor;
|
||||
id<MTLCommandBuffer> commandBuffer;
|
||||
id<MTLRenderCommandEncoder> renderEncoder;
|
||||
id<MTLDrawable> drawable;
|
||||
id<MTLTexture> texture;
|
||||
MTLTextureDescriptor *textureDescriptor;
|
||||
MTLRegion region;
|
||||
unsigned width = stream->size.w, height = stream->size.h;
|
||||
|
||||
/* Place the buffer into a texture */
|
||||
textureDescriptor = [MTLTextureDescriptor
|
||||
texture2DDescriptorWithPixelFormat:stream->format
|
||||
width:width height:height mipmapped:NO];
|
||||
|
||||
texture = [device newTextureWithDescriptor:textureDescriptor];
|
||||
region = MTLRegionMake2D(0, 0, width, height);
|
||||
[texture replaceRegion:region mipmapLevel:0 withBytes:stream->render_buf
|
||||
bytesPerRow:stream->bytes_per_row];
|
||||
|
||||
/* The render pass descriptor references the texture into which Metal
|
||||
* should draw.
|
||||
*/
|
||||
renderPassDescriptor = _view.currentRenderPassDescriptor;
|
||||
if (renderPassDescriptor == nil)
|
||||
return;
|
||||
|
||||
commandBuffer = [commandQueue commandBuffer];
|
||||
|
||||
renderEncoder = [commandBuffer renderCommandEncoderWithDescriptor:
|
||||
renderPassDescriptor];
|
||||
[renderEncoder setRenderPipelineState:pipelineState];
|
||||
[renderEncoder setVertexBuffer:vertexBuffer offset:0 atIndex:0];
|
||||
[renderEncoder setVertexBuffer:textureCoordBuffer offset:0 atIndex:1];
|
||||
|
||||
[renderEncoder setFragmentTexture:texture atIndex:0];
|
||||
[renderEncoder drawPrimitives:MTLPrimitiveTypeTriangleStrip vertexStart:0
|
||||
vertexCount:4];
|
||||
|
||||
[renderEncoder endEncoding];
|
||||
|
||||
/* Get the drawable that will be presented at the end of the frame */
|
||||
drawable = _view.currentDrawable;
|
||||
|
||||
/* Request that the drawable texture be presented by the windowing system
|
||||
* once drawing is done.
|
||||
*/
|
||||
[commandBuffer presentDrawable:drawable];
|
||||
[commandBuffer commit];
|
||||
|
||||
[texture release];
|
||||
|
||||
stream->is_rendering = PJ_FALSE;
|
||||
}
|
||||
|
||||
|
||||
/* Called whenever the view needs to render a frame. */
|
||||
- (void)drawInMTKView:(nonnull MTKView *)view
|
||||
{
|
||||
}
|
||||
|
||||
/* Called whenever view changes orientation or is resized */
|
||||
- (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size
|
||||
{
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
static pj_status_t metal_init_view(struct metal_stream *strm)
|
||||
{
|
||||
pjmedia_vid_dev_param *param = &strm->param;
|
||||
CGRect view_rect = CGRectMake(0, 0, param->fmt.det.vid.size.w,
|
||||
param->fmt.det.vid.size.h);
|
||||
|
||||
if (param->flags & PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE) {
|
||||
view_rect.size.width = param->disp_size.w;
|
||||
view_rect.size.height = param->disp_size.h;
|
||||
}
|
||||
|
||||
if (param->flags & PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION) {
|
||||
view_rect.origin.x = param->window_pos.x;
|
||||
view_rect.origin.y = param->window_pos.y;
|
||||
}
|
||||
|
||||
strm->view = [[MTKView alloc] initWithFrame:view_rect];
|
||||
if (!strm->view)
|
||||
return PJMEDIA_EVID_SYSERR;
|
||||
|
||||
strm->view.enableSetNeedsDisplay = NO;
|
||||
strm->view.paused = NO;
|
||||
strm->view.device = MTLCreateSystemDefaultDevice();
|
||||
strm->view.clearColor = MTLClearColorMake(0.0, 0.0, 0.0, 1.0);
|
||||
strm->param.window.info.window = strm->view;
|
||||
|
||||
strm->renderer = [MetalRenderer alloc];
|
||||
if (!strm->renderer)
|
||||
return PJ_ENOMEM;
|
||||
|
||||
strm->renderer->stream = strm;
|
||||
strm->view.delegate = strm->renderer;
|
||||
[strm->renderer initWithMetalKitView:strm->view];
|
||||
|
||||
if (param->flags & PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW) {
|
||||
PJ_ASSERT_RETURN(param->window.info.ios.window, PJ_EINVAL);
|
||||
metal_stream_set_cap(&strm->base, PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW,
|
||||
param->window.info.ios.window);
|
||||
} else {
|
||||
#if !TARGET_OS_IPHONE
|
||||
/* Create the main window */
|
||||
strm->window = [[NSWindow alloc] initWithContentRect:view_rect
|
||||
styleMask:(NSWindowStyleMaskTitled |
|
||||
NSWindowStyleMaskClosable |
|
||||
NSWindowStyleMaskResizable)
|
||||
backing:NSBackingStoreBuffered
|
||||
defer:NO];
|
||||
if (!strm->window)
|
||||
return PJMEDIA_EVID_SYSERR;
|
||||
|
||||
/* Make the window visible */
|
||||
[strm->window.contentView addSubview:strm->view];
|
||||
[strm->window makeKeyAndOrderFront:strm->window];
|
||||
strm->param.window.info.window = strm->window;
|
||||
#endif
|
||||
}
|
||||
if (param->flags & PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE) {
|
||||
metal_stream_set_cap(&strm->base, PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE,
|
||||
¶m->window_hide);
|
||||
}
|
||||
if (param->flags & PJMEDIA_VID_DEV_CAP_ORIENTATION) {
|
||||
metal_stream_set_cap(&strm->base, PJMEDIA_VID_DEV_CAP_ORIENTATION,
|
||||
¶m->orient);
|
||||
}
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
static metal_fmt_info* get_metal_format_info(pjmedia_format_id id)
|
||||
{
|
||||
unsigned i;
|
||||
|
||||
for (i = 0; i < PJ_ARRAY_SIZE(metal_fmts); i++) {
|
||||
if (metal_fmts[i].pjmedia_format == id)
|
||||
return &metal_fmts[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* API: create stream */
|
||||
static pj_status_t metal_factory_create_stream(
|
||||
pjmedia_vid_dev_factory *f,
|
||||
pjmedia_vid_dev_param *param,
|
||||
const pjmedia_vid_dev_cb *cb,
|
||||
void *user_data,
|
||||
pjmedia_vid_dev_stream **p_vid_strm)
|
||||
{
|
||||
struct metal_factory *qf = (struct metal_factory*)f;
|
||||
pj_pool_t *pool;
|
||||
struct metal_stream *strm;
|
||||
pjmedia_video_format_detail *vfd;
|
||||
const pjmedia_video_format_info *vfi;
|
||||
metal_fmt_info *mfi;
|
||||
pj_status_t status = PJ_SUCCESS;
|
||||
|
||||
PJ_ASSERT_RETURN(f && param && p_vid_strm, PJ_EINVAL);
|
||||
PJ_ASSERT_RETURN(param->fmt.type == PJMEDIA_TYPE_VIDEO &&
|
||||
param->fmt.detail_type == PJMEDIA_FORMAT_DETAIL_VIDEO &&
|
||||
param->dir == PJMEDIA_DIR_RENDER,
|
||||
PJ_EINVAL);
|
||||
|
||||
if (!(mfi = get_metal_format_info(param->fmt.id)))
|
||||
return PJMEDIA_EVID_BADFORMAT;
|
||||
|
||||
vfi = pjmedia_get_video_format_info(NULL, param->fmt.id);
|
||||
if (!vfi)
|
||||
return PJMEDIA_EVID_BADFORMAT;
|
||||
|
||||
/* Create and Initialize stream descriptor */
|
||||
pool = pj_pool_create(qf->pf, "metal-dev", 4000, 4000, NULL);
|
||||
PJ_ASSERT_RETURN(pool != NULL, PJ_ENOMEM);
|
||||
|
||||
strm = PJ_POOL_ZALLOC_T(pool, struct metal_stream);
|
||||
pj_memcpy(&strm->param, param, sizeof(*param));
|
||||
strm->pool = pool;
|
||||
pj_memcpy(&strm->vid_cb, cb, sizeof(*cb));
|
||||
strm->user_data = user_data;
|
||||
strm->factory = qf;
|
||||
|
||||
vfd = pjmedia_format_get_video_format_detail(&strm->param.fmt, PJ_TRUE);
|
||||
pj_memcpy(&strm->size, &vfd->size, sizeof(vfd->size));
|
||||
strm->bytes_per_row = strm->size.w * vfi->bpp / 8;
|
||||
strm->frame_size = strm->bytes_per_row * strm->size.h;
|
||||
strm->ts_inc = PJMEDIA_SPF2(param->clock_rate, &vfd->fps, 1);
|
||||
strm->is_planar = vfi->plane_cnt > 1;
|
||||
strm->format = mfi->metal_format;
|
||||
|
||||
if (param->dir & PJMEDIA_DIR_RENDER) {
|
||||
/* Create renderer stream here */
|
||||
|
||||
dispatch_sync_on_main_queue(^{
|
||||
metal_init_view(strm);
|
||||
});
|
||||
|
||||
strm->render_buf = pj_pool_alloc(pool, strm->frame_size);
|
||||
strm->render_buf_size = strm->frame_size;
|
||||
|
||||
PJ_LOG(4, (THIS_FILE, "Metal renderer initialized"));
|
||||
}
|
||||
|
||||
/* Done */
|
||||
strm->base.op = &stream_op;
|
||||
*p_vid_strm = &strm->base;
|
||||
|
||||
return PJ_SUCCESS;
|
||||
|
||||
on_error:
|
||||
metal_stream_destroy((pjmedia_vid_dev_stream *)strm);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
/* API: Get stream info. */
|
||||
static pj_status_t metal_stream_get_param(pjmedia_vid_dev_stream *s,
|
||||
pjmedia_vid_dev_param *pi)
|
||||
{
|
||||
struct metal_stream *strm = (struct metal_stream*)s;
|
||||
|
||||
PJ_ASSERT_RETURN(strm && pi, PJ_EINVAL);
|
||||
|
||||
pj_memcpy(pi, &strm->param, sizeof(*pi));
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
/* API: get capability */
|
||||
static pj_status_t metal_stream_get_cap(pjmedia_vid_dev_stream *s,
|
||||
pjmedia_vid_dev_cap cap,
|
||||
void *pval)
|
||||
{
|
||||
struct metal_stream *strm = (struct metal_stream*)s;
|
||||
|
||||
PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
|
||||
PJ_UNUSED_ARG(strm);
|
||||
|
||||
switch (cap) {
|
||||
case PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW:
|
||||
{
|
||||
pjmedia_vid_dev_hwnd *hwnd = (pjmedia_vid_dev_hwnd *) pval;
|
||||
hwnd->type = TARGET_OS_IPHONE? PJMEDIA_VID_DEV_HWND_TYPE_IOS:
|
||||
PJMEDIA_VID_DEV_HWND_TYPE_COCOA;
|
||||
hwnd->info.window = (void *)strm->view;
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return PJMEDIA_EVID_INVCAP;
|
||||
}
|
||||
|
||||
/* API: set capability */
|
||||
static pj_status_t metal_stream_set_cap(pjmedia_vid_dev_stream *s,
|
||||
pjmedia_vid_dev_cap cap,
|
||||
const void *pval)
|
||||
{
|
||||
struct metal_stream *strm = (struct metal_stream*)s;
|
||||
|
||||
PJ_ASSERT_RETURN(s && pval, PJ_EINVAL);
|
||||
|
||||
switch (cap) {
|
||||
case PJMEDIA_VID_DEV_CAP_FORMAT:
|
||||
{
|
||||
const pjmedia_video_format_info *vfi;
|
||||
pjmedia_video_format_detail *vfd;
|
||||
pjmedia_format *fmt = (pjmedia_format *)pval;
|
||||
metal_fmt_info *ifi;
|
||||
|
||||
if (!(ifi = get_metal_format_info(fmt->id)))
|
||||
return PJMEDIA_EVID_BADFORMAT;
|
||||
|
||||
vfi = pjmedia_get_video_format_info(
|
||||
pjmedia_video_format_mgr_instance(),
|
||||
fmt->id);
|
||||
if (!vfi)
|
||||
return PJMEDIA_EVID_BADFORMAT;
|
||||
|
||||
pjmedia_format_copy(&strm->param.fmt, fmt);
|
||||
|
||||
vfd = pjmedia_format_get_video_format_detail(fmt, PJ_TRUE);
|
||||
pj_memcpy(&strm->size, &vfd->size, sizeof(vfd->size));
|
||||
strm->bytes_per_row = strm->size.w * vfi->bpp / 8;
|
||||
strm->frame_size = strm->bytes_per_row * strm->size.h;
|
||||
if (strm->render_buf_size < strm->frame_size) {
|
||||
/* Realloc only when needed */
|
||||
strm->render_buf = pj_pool_alloc(strm->pool, strm->frame_size);
|
||||
strm->render_buf_size = strm->frame_size;
|
||||
}
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
case PJMEDIA_VID_DEV_CAP_OUTPUT_WINDOW:
|
||||
{
|
||||
strm->param.window.info.window = (void *)pval;
|
||||
dispatch_sync_on_main_queue(^{
|
||||
[(NSView *)pval addSubview:strm->view];
|
||||
});
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
case PJMEDIA_VID_DEV_CAP_OUTPUT_RESIZE:
|
||||
{
|
||||
pj_memcpy(&strm->param.disp_size, pval,
|
||||
sizeof(strm->param.disp_size));
|
||||
dispatch_sync_on_main_queue(^{
|
||||
CGRect r = (strm->window)? strm->window.frame:
|
||||
strm->view.bounds;
|
||||
r.size = CGSizeMake(strm->param.disp_size.w,
|
||||
strm->param.disp_size.h);
|
||||
if (!strm->window)
|
||||
strm->view.bounds = r;
|
||||
#if !TARGET_OS_IPHONE
|
||||
else
|
||||
[strm->window setFrame:r display:YES];
|
||||
#endif
|
||||
});
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
case PJMEDIA_VID_DEV_CAP_OUTPUT_POSITION:
|
||||
{
|
||||
pj_memcpy(&strm->param.window_pos, pval,
|
||||
sizeof(strm->param.window_pos));
|
||||
dispatch_sync_on_main_queue(^{
|
||||
#if TARGET_OS_IPHONE
|
||||
strm->view.center =
|
||||
CGPointMake(strm->param.window_pos.x +
|
||||
strm->param.disp_size.w/2.0,
|
||||
strm->param.window_pos.y +
|
||||
strm->param.disp_size.h/2.0);
|
||||
#else
|
||||
if (strm->window) {
|
||||
[strm->window setFrameOrigin:
|
||||
NSMakePoint(strm->param.window_pos.x,
|
||||
strm->param.window_pos.y)];
|
||||
} else {
|
||||
[strm->view setFrameOrigin:
|
||||
NSMakePoint(strm->param.window_pos.x,
|
||||
strm->param.window_pos.y)];
|
||||
}
|
||||
#endif
|
||||
});
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
case PJMEDIA_VID_DEV_CAP_OUTPUT_HIDE:
|
||||
{
|
||||
dispatch_sync_on_main_queue(^{
|
||||
pj_bool_t hide = *((pj_bool_t *)pval);
|
||||
if (strm->window) {
|
||||
#if !TARGET_OS_IPHONE
|
||||
if (hide)
|
||||
[strm->window orderOut: nil];
|
||||
else
|
||||
[strm->window orderFront: nil];
|
||||
#endif
|
||||
} else {
|
||||
strm->view.hidden = (BOOL)hide;
|
||||
}
|
||||
});
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
case PJMEDIA_VID_DEV_CAP_ORIENTATION:
|
||||
{
|
||||
pjmedia_orient orient = *(pjmedia_orient *)pval;
|
||||
|
||||
pj_assert(orient >= PJMEDIA_ORIENT_UNKNOWN &&
|
||||
orient <= PJMEDIA_ORIENT_ROTATE_270DEG);
|
||||
|
||||
if (orient == PJMEDIA_ORIENT_UNKNOWN)
|
||||
return PJ_EINVAL;
|
||||
|
||||
pj_memcpy(&strm->param.orient, pval,
|
||||
sizeof(strm->param.orient));
|
||||
|
||||
dispatch_sync_on_main_queue(^{
|
||||
CGFloat angle = -M_PI_2 * ((int)strm->param.orient-1);
|
||||
#if TARGET_OS_IPHONE
|
||||
strm->view.transform =
|
||||
CGAffineTransformMakeRotation(angle);
|
||||
#else
|
||||
strm->view.layer.affineTransform =
|
||||
CGAffineTransformMakeRotation(angle);
|
||||
#endif
|
||||
});
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return PJMEDIA_EVID_INVCAP;
|
||||
}
|
||||
|
||||
/* API: Start stream. */
|
||||
static pj_status_t metal_stream_start(pjmedia_vid_dev_stream *strm)
|
||||
{
|
||||
struct metal_stream *stream = (struct metal_stream*)strm;
|
||||
|
||||
PJ_LOG(4, (THIS_FILE, "Starting Metal video stream"));
|
||||
stream->is_running = PJ_TRUE;
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* API: Put frame from stream */
|
||||
static pj_status_t metal_stream_put_frame(pjmedia_vid_dev_stream *strm,
|
||||
const pjmedia_frame *frame)
|
||||
{
|
||||
struct metal_stream *stream = (struct metal_stream*)strm;
|
||||
|
||||
/* Video conference just trying to send heart beat for updating timestamp
|
||||
* or keep-alive, this port doesn't need any, just ignore.
|
||||
*/
|
||||
if (frame->size==0 || frame->buf==NULL)
|
||||
return PJ_SUCCESS;
|
||||
|
||||
if (!stream->is_running)
|
||||
return PJ_EINVALIDOP;
|
||||
|
||||
/* Prevent more than one async rendering task. */
|
||||
if (stream->is_rendering)
|
||||
return PJ_EIGNORED;
|
||||
|
||||
if (stream->frame_size >= frame->size)
|
||||
pj_memcpy(stream->render_buf, frame->buf, frame->size);
|
||||
else
|
||||
pj_memcpy(stream->render_buf, frame->buf, stream->frame_size);
|
||||
|
||||
/* Perform video display in the main thread */
|
||||
stream->is_rendering = PJ_TRUE;
|
||||
[stream->renderer performSelectorOnMainThread:@selector(update_image)
|
||||
withObject:nil waitUntilDone:NO];
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
/* API: Stop stream. */
|
||||
static pj_status_t metal_stream_stop(pjmedia_vid_dev_stream *strm)
|
||||
{
|
||||
struct metal_stream *stream = (struct metal_stream*)strm;
|
||||
unsigned i;
|
||||
|
||||
PJ_LOG(4, (THIS_FILE, "Stopping Metal video stream"));
|
||||
|
||||
stream->is_running = PJ_FALSE;
|
||||
|
||||
/* Wait until the rendering finishes */
|
||||
for (i = 0; i < 15; i++) pj_thread_sleep(10);
|
||||
while (stream->is_rendering);
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
|
||||
/* API: Destroy stream. */
|
||||
static pj_status_t metal_stream_destroy(pjmedia_vid_dev_stream *strm)
|
||||
{
|
||||
struct metal_stream *stream = (struct metal_stream*)strm;
|
||||
|
||||
PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);
|
||||
|
||||
metal_stream_stop(strm);
|
||||
|
||||
if (stream->renderer) {
|
||||
[stream->renderer release];
|
||||
stream->renderer = nil;
|
||||
}
|
||||
|
||||
if (stream->view) {
|
||||
[stream->view
|
||||
performSelectorOnMainThread:@selector(removeFromSuperview)
|
||||
withObject:nil waitUntilDone:YES];
|
||||
[stream->view release];
|
||||
stream->view = nil;
|
||||
}
|
||||
|
||||
if (stream->window) {
|
||||
[stream->window performSelectorOnMainThread:@selector(close)
|
||||
withObject:nil waitUntilDone:YES];
|
||||
stream->window = nil;
|
||||
}
|
||||
|
||||
pjmedia_vid_dev_conv_destroy_converter(&stream->conv);
|
||||
|
||||
pj_pool_release(stream->pool);
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
#endif /* PJMEDIA_VIDEO_DEV_HAS_METAL */
|
|
@ -34,10 +34,6 @@ pjmedia_vid_dev_factory* pjmedia_dshow_factory(pj_pool_factory *pf);
|
|||
pjmedia_vid_dev_factory* pjmedia_cbar_factory(pj_pool_factory *pf);
|
||||
#endif
|
||||
|
||||
#if PJMEDIA_VIDEO_DEV_HAS_METAL
|
||||
pjmedia_vid_dev_factory* pjmedia_metal_factory(pj_pool_factory *pf);
|
||||
#endif
|
||||
|
||||
#if PJMEDIA_VIDEO_DEV_HAS_SDL
|
||||
pjmedia_vid_dev_factory* pjmedia_sdl_factory(pj_pool_factory *pf);
|
||||
#endif
|
||||
|
@ -101,9 +97,6 @@ PJ_DEF(pj_status_t) pjmedia_vid_dev_subsys_init(pj_pool_factory *pf)
|
|||
#if PJMEDIA_VIDEO_DEV_HAS_QT
|
||||
vid_subsys->drv[vid_subsys->drv_cnt++].create = &pjmedia_qt_factory;
|
||||
#endif
|
||||
#if PJMEDIA_VIDEO_DEV_HAS_METAL
|
||||
vid_subsys->drv[vid_subsys->drv_cnt++].create = &pjmedia_metal_factory;
|
||||
#endif
|
||||
#if PJMEDIA_VIDEO_DEV_HAS_OPENGL
|
||||
vid_subsys->drv[vid_subsys->drv_cnt++].create = &pjmedia_opengl_factory;
|
||||
#endif
|
||||
|
|
|
@ -79,8 +79,7 @@ pjmedia_clock_src_get_time_msec( const pjmedia_clock_src *clocksrc )
|
|||
{
|
||||
pj_timestamp ts;
|
||||
|
||||
if (pjmedia_clock_src_get_current_timestamp(clocksrc, &ts) != PJ_SUCCESS)
|
||||
return 0;
|
||||
pjmedia_clock_src_get_current_timestamp(clocksrc, &ts);
|
||||
|
||||
#if PJ_HAS_INT64
|
||||
if (ts.u64 > PJ_UINT64(0x3FFFFFFFFFFFFF))
|
||||
|
|
|
@ -366,8 +366,7 @@ PJ_DEF(pj_status_t) pjmedia_codec_mgr_unregister_factory(
|
|||
pj_bool_t found;
|
||||
pj_str_t codec_str = pj_str(mgr->codec_desc[i].id);
|
||||
|
||||
codec_idx = (pj_int8_t)pjmedia_codec_mgr_find_codec(
|
||||
mgr->dyn_codecs,
|
||||
codec_idx = pjmedia_codec_mgr_find_codec(mgr->dyn_codecs,
|
||||
mgr->dyn_codecs_cnt,
|
||||
&codec_str,
|
||||
&found);
|
||||
|
@ -816,8 +815,8 @@ pj_status_t pjmedia_codec_mgr_get_dyn_codecs(pjmedia_codec_mgr* mgr,
|
|||
|
||||
pj_mutex_lock(mgr->mutex);
|
||||
|
||||
if (mgr->dyn_codecs_cnt < (unsigned)*count)
|
||||
*count = (pj_int8_t)mgr->dyn_codecs_cnt;
|
||||
if (mgr->dyn_codecs_cnt < *count)
|
||||
*count = mgr->dyn_codecs_cnt;
|
||||
|
||||
pj_memcpy(dyn_codecs, mgr->dyn_codecs, *count * sizeof(pj_str_t));
|
||||
|
||||
|
|
|
@ -1049,7 +1049,6 @@ PJ_DEF(pj_status_t) pjmedia_conf_disconnect_port( pjmedia_conf *conf,
|
|||
unsigned sink_slot )
|
||||
{
|
||||
struct conf_port *src_port, *dst_port;
|
||||
pj_bool_t no_conn = PJ_FALSE;
|
||||
unsigned i;
|
||||
|
||||
/* Check arguments */
|
||||
|
@ -1099,12 +1098,9 @@ PJ_DEF(pj_status_t) pjmedia_conf_disconnect_port( pjmedia_conf *conf,
|
|||
pjmedia_delay_buf_reset(src_port->delay_buf);
|
||||
}
|
||||
|
||||
/* Evaluate connect_cnt with mutex, but pause sound dev outside mutex */
|
||||
no_conn = (conf->connect_cnt == 0);
|
||||
|
||||
pj_mutex_unlock(conf->mutex);
|
||||
|
||||
if (no_conn) {
|
||||
if (conf->connect_cnt == 0) {
|
||||
pause_sound(conf);
|
||||
}
|
||||
|
||||
|
|
|
@ -243,8 +243,6 @@ PJ_DEF(void) pjmedia_event_mgr_destroy(pjmedia_event_mgr *mgr)
|
|||
mgr->is_quitting = PJ_TRUE;
|
||||
pj_sem_post(mgr->sem);
|
||||
pj_thread_join(mgr->thread);
|
||||
pj_thread_destroy(mgr->thread);
|
||||
mgr->thread = NULL;
|
||||
}
|
||||
|
||||
if (mgr->sem) {
|
||||
|
|
|
@ -24,12 +24,14 @@
|
|||
#include <pj/log.h>
|
||||
#include <pj/pool.h>
|
||||
|
||||
#define THIS_FILE "resample.c"
|
||||
|
||||
#if PJMEDIA_RESAMPLE_IMP==PJMEDIA_RESAMPLE_LIBRESAMPLE
|
||||
|
||||
#include <third_party/resample/include/resamplesubs.h>
|
||||
|
||||
#define THIS_FILE "resample.c"
|
||||
|
||||
|
||||
|
||||
struct pjmedia_resample
|
||||
{
|
||||
|
@ -156,7 +158,7 @@ PJ_DEF(void) pjmedia_resample_run( pjmedia_resample *resample,
|
|||
* So here comes the trick.
|
||||
*
|
||||
* First of all, because of the history and lookahead requirement,
|
||||
* resample->buffer need to accommodate framesize+2*xoff samples in its
|
||||
* resample->buffer need to accomodate framesize+2*xoff samples in its
|
||||
* buffer. This is done when the buffer is created.
|
||||
*
|
||||
* On the first run, the input frame (supplied by application) is
|
||||
|
@ -174,8 +176,8 @@ PJ_DEF(void) pjmedia_resample_run( pjmedia_resample *resample,
|
|||
* | 0000 | 0000 | frame0... |
|
||||
* +------+------+--------------+
|
||||
* ^ ^ ^ ^
|
||||
* 0 xoff 2*xoff size+2*xoff
|
||||
*
|
||||
* 0 xoff 2*xoff size+2*xoff
|
||||
*
|
||||
* (Note again: resample algorithm is called at resample->buffer+xoff)
|
||||
*
|
||||
* At the end of the run, 2*xoff samples from the end of
|
||||
|
@ -202,7 +204,7 @@ PJ_DEF(void) pjmedia_resample_run( pjmedia_resample *resample,
|
|||
* | frm0 | frm0 | frame1... |
|
||||
* +------+------+--------------+
|
||||
* ^ ^ ^ ^
|
||||
* 0 xoff 2*xoff size+2*xoff
|
||||
* 0 xoff 2*xoff size+2*xoff
|
||||
*
|
||||
* As you can see from above diagram, the resampling algorithm is
|
||||
* actually called from the last xoff part of previous frame (frm0).
|
||||
|
@ -318,8 +320,6 @@ PJ_DEF(pj_status_t) pjmedia_resample_create( pj_pool_t *pool,
|
|||
PJ_UNUSED_ARG(samples_per_frame);
|
||||
PJ_UNUSED_ARG(p_resample);
|
||||
|
||||
PJ_LOG(3, (THIS_FILE, "No resampler created (sample rate conversion is "
|
||||
"disabled or no resample implementation selected)"));
|
||||
return PJ_EINVALIDOP;
|
||||
}
|
||||
|
||||
|
|
|
@ -597,8 +597,8 @@ PJ_DEF(pj_status_t) pjmedia_sdp_rtpmap_to_attr(pj_pool_t *pool,
|
|||
PJ_ASSERT_RETURN(pool && rtpmap && p_attr, PJ_EINVAL);
|
||||
|
||||
/* Check that mandatory attributes are specified. */
|
||||
PJ_ASSERT_RETURN(rtpmap->pt.slen && rtpmap->enc_name.slen &&
|
||||
rtpmap->clock_rate, PJMEDIA_SDP_EINRTPMAP);
|
||||
PJ_ASSERT_RETURN(rtpmap->enc_name.slen && rtpmap->clock_rate,
|
||||
PJMEDIA_SDP_EINRTPMAP);
|
||||
|
||||
|
||||
attr = PJ_POOL_ALLOC_T(pool, pjmedia_sdp_attr);
|
||||
|
@ -617,7 +617,7 @@ PJ_DEF(pj_status_t) pjmedia_sdp_rtpmap_to_attr(pj_pool_t *pool,
|
|||
rtpmap->clock_rate,
|
||||
(rtpmap->param.slen ? "/" : ""),
|
||||
(int)rtpmap->param.slen,
|
||||
rtpmap->param.slen ? rtpmap->param.ptr : "");
|
||||
rtpmap->param.ptr);
|
||||
|
||||
if (len < 1 || len >= (int)sizeof(tempbuf))
|
||||
return PJMEDIA_SDP_ERTPMAPTOOLONG;
|
||||
|
@ -895,11 +895,9 @@ static int print_session(const pjmedia_sdp_session *ses,
|
|||
int printed;
|
||||
|
||||
/* Check length for v= and o= lines. */
|
||||
if (len < 5 + 2 + ses->origin.user.slen +
|
||||
20 + 20 + 3 + /* max digits of origin.id and version +
|
||||
* whitespaces */
|
||||
ses->origin.net_type.slen + ses->origin.addr_type.slen +
|
||||
ses->origin.addr.slen + 2 + 2)
|
||||
if (len < 5+
|
||||
2+ses->origin.user.slen+18+
|
||||
ses->origin.net_type.slen+ses->origin.addr.slen + 2)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
@ -961,7 +959,7 @@ static int print_session(const pjmedia_sdp_session *ses,
|
|||
}
|
||||
|
||||
/* Time */
|
||||
if ((end-p) < 2+20+1+20+2) {
|
||||
if ((end-p) < 24) {
|
||||
return -1;
|
||||
}
|
||||
*p++ = 't';
|
||||
|
@ -1772,7 +1770,7 @@ PJ_DEF(pj_uint32_t) pjmedia_sdp_transport_get_proto(const pj_str_t *tp)
|
|||
PJ_ASSERT_RETURN(tp, PJMEDIA_TP_PROTO_NONE);
|
||||
|
||||
idx = pj_strtok2(tp, "/", &token, 0);
|
||||
if ((idx != tp->slen) && (tp->slen != token.slen))
|
||||
if (idx != tp->slen)
|
||||
pj_strset(&rest, tp->ptr + token.slen + 1, tp->slen - token.slen - 1);
|
||||
|
||||
if (pj_stricmp2(&token, "RTP") == 0) {
|
||||
|
|
|
@ -1573,28 +1573,18 @@ static pj_status_t create_answer( pj_pool_t *pool,
|
|||
const pjmedia_sdp_media *om; /* offer */
|
||||
const pjmedia_sdp_media *im; /* initial media */
|
||||
pjmedia_sdp_media *am = NULL; /* answer/result */
|
||||
pj_uint32_t om_tp;
|
||||
unsigned j;
|
||||
|
||||
om = offer->media[i];
|
||||
|
||||
om_tp = pjmedia_sdp_transport_get_proto(&om->desc.transport);
|
||||
PJMEDIA_TP_PROTO_TRIM_FLAG(om_tp, PJMEDIA_TP_PROFILE_RTCP_FB);
|
||||
|
||||
/* Find media description in our initial capability that matches
|
||||
* the media type and transport type of offer's media, has
|
||||
* matching codec, and has not been used to answer other offer.
|
||||
*/
|
||||
for (im=NULL, j=0; j<initial->media_count; ++j) {
|
||||
pj_uint32_t im_tp;
|
||||
|
||||
im = initial->media[j];
|
||||
|
||||
im_tp = pjmedia_sdp_transport_get_proto(&im->desc.transport);
|
||||
PJMEDIA_TP_PROTO_TRIM_FLAG(im_tp, PJMEDIA_TP_PROFILE_RTCP_FB);
|
||||
|
||||
if (pj_strcmp(&om->desc.media, &im->desc.media)==0 &&
|
||||
om_tp == im_tp &&
|
||||
pj_strcmp(&om->desc.transport, &im->desc.transport)==0 &&
|
||||
media_used[j] == 0)
|
||||
{
|
||||
pj_status_t status2;
|
||||
|
@ -1715,8 +1705,6 @@ static pj_status_t assign_pt_and_update_map(pj_pool_t *pool,
|
|||
{
|
||||
unsigned i, j;
|
||||
|
||||
PJ_UNUSED_ARG(pool);
|
||||
|
||||
for (i = 0; i < sess->media_count; ++i) {
|
||||
pjmedia_type med_type;
|
||||
unsigned count;
|
||||
|
@ -1797,8 +1785,8 @@ static pj_status_t assign_pt_and_update_map(pj_pool_t *pool,
|
|||
codec = rtpmap.enc_name;
|
||||
}
|
||||
|
||||
codec_idx = (pj_int8_t)pjmedia_codec_mgr_find_codec(dyn_codecs,
|
||||
count, &codec, NULL);
|
||||
codec_idx = pjmedia_codec_mgr_find_codec(dyn_codecs, count,
|
||||
&codec, NULL);
|
||||
if (codec_idx < 0) {
|
||||
/* This typically happens when remote offers unknown
|
||||
* codec.
|
||||
|
@ -1810,7 +1798,7 @@ static pj_status_t assign_pt_and_update_map(pj_pool_t *pool,
|
|||
/* Update the mapping. */
|
||||
neg->pt_to_codec[i][pt - START_DYNAMIC_PT] = codec_idx;
|
||||
if (codec_idx != UNKNOWN_CODEC)
|
||||
neg->codec_to_pt[i][codec_idx] = (pj_int8_t)pt;
|
||||
neg->codec_to_pt[i][codec_idx] = pt;
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -1853,15 +1841,15 @@ static pj_status_t assign_pt_and_update_map(pj_pool_t *pool,
|
|||
* find the first unused one.
|
||||
*/
|
||||
if (need_new_pt && new_pt == 0) {
|
||||
new_pt = (pj_int8_t)find_new_pt(&neg->pt_to_codec[i], pt_used,
|
||||
&codec, codec_idx);
|
||||
new_pt = find_new_pt(&neg->pt_to_codec[i], pt_used,
|
||||
&codec, codec_idx);
|
||||
}
|
||||
|
||||
if (new_pt != 0 && new_pt != (pj_int8_t)pt) {
|
||||
if (new_pt != 0 && new_pt != pt) {
|
||||
rewrite_pt2(neg->pool_active, (pj_str_t *)&attr->value,
|
||||
pt, new_pt);
|
||||
} else {
|
||||
new_pt = (pj_int8_t)pt;
|
||||
new_pt = pt;
|
||||
}
|
||||
|
||||
/* Mark the PT number as used and keep track of the change
|
||||
|
|
|
@ -1087,11 +1087,10 @@ static pj_status_t send_rtcp(pjmedia_stream *stream,
|
|||
pj_status_t status;
|
||||
|
||||
/* We need to prevent data race since there is only a single instance
|
||||
* of rtcp packet buffer. And to avoid deadlock with media transport,
|
||||
* we use the transport's group lock.
|
||||
* of rtcp packet buffer. Let's just use the JB mutex for this instead
|
||||
* of creating a separate lock.
|
||||
*/
|
||||
if (stream->transport->grp_lock)
|
||||
pj_grp_lock_acquire(stream->transport->grp_lock);
|
||||
pj_mutex_lock(stream->jb_mutex);
|
||||
|
||||
/* Build RTCP RR/SR packet */
|
||||
pjmedia_rtcp_build_rtcp(&stream->rtcp, &sr_rr_pkt, &len);
|
||||
|
@ -1212,8 +1211,7 @@ static pj_status_t send_rtcp(pjmedia_stream *stream,
|
|||
}
|
||||
}
|
||||
|
||||
if (stream->transport->grp_lock)
|
||||
pj_grp_lock_release(stream->transport->grp_lock);
|
||||
pj_mutex_unlock(stream->jb_mutex);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -2658,14 +2656,14 @@ PJ_DEF(pj_status_t) pjmedia_stream_create( pjmedia_endpt *endpt,
|
|||
|
||||
ptime = afd->frame_time_usec;
|
||||
|
||||
if (stream->codec_param.info.enc_ptime * (unsigned)1000 >
|
||||
if (stream->codec_param.info.enc_ptime * 1000 >
|
||||
ptime * stream->codec_param.info.enc_ptime_denum)
|
||||
{
|
||||
ptime = stream->codec_param.info.enc_ptime * 1000 /
|
||||
stream->codec_param.info.enc_ptime_denum;
|
||||
}
|
||||
|
||||
if (stream->codec_param.info.frm_ptime * (unsigned)1000 >
|
||||
if (stream->codec_param.info.frm_ptime * 1000 >
|
||||
ptime * stream->codec_param.info.frm_ptime_denum)
|
||||
{
|
||||
ptime = stream->codec_param.info.frm_ptime * 1000 /
|
||||
|
@ -3070,7 +3068,7 @@ PJ_DEF(pj_status_t) pjmedia_stream_destroy( pjmedia_stream *stream )
|
|||
PJ_ASSERT_RETURN(stream != NULL, PJ_EINVAL);
|
||||
|
||||
/* Send RTCP BYE (also SDES & XR) */
|
||||
if (stream->transport && !stream->rtcp_sdes_bye_disabled) {
|
||||
if (stream->transport && stream->jb_mutex && !stream->rtcp_sdes_bye_disabled) {
|
||||
#if defined(PJMEDIA_HAS_RTCP_XR) && (PJMEDIA_HAS_RTCP_XR != 0)
|
||||
send_rtcp(stream, PJ_TRUE, PJ_TRUE, stream->rtcp.xr_enabled, PJ_FALSE);
|
||||
#else
|
||||
|
|
|
@ -106,9 +106,6 @@ struct tp_adapter
|
|||
};
|
||||
|
||||
|
||||
static void adapter_on_destroy(void *arg);
|
||||
|
||||
|
||||
/*
|
||||
* Create the adapter.
|
||||
*/
|
||||
|
@ -138,15 +135,6 @@ PJ_DEF(pj_status_t) pjmedia_tp_adapter_create( pjmedia_endpt *endpt,
|
|||
adapter->slave_tp = transport;
|
||||
adapter->del_base = del_base;
|
||||
|
||||
/* Setup group lock handler for destroy and callback synchronization */
|
||||
if (transport && transport->grp_lock) {
|
||||
pj_grp_lock_t *grp_lock = transport->grp_lock;
|
||||
|
||||
adapter->base.grp_lock = grp_lock;
|
||||
pj_grp_lock_add_ref(grp_lock);
|
||||
pj_grp_lock_add_handler(grp_lock, pool, adapter, &adapter_on_destroy);
|
||||
}
|
||||
|
||||
/* Done */
|
||||
*p_tp = &adapter->base;
|
||||
return PJ_SUCCESS;
|
||||
|
@ -433,14 +421,6 @@ static pj_status_t transport_simulate_lost(pjmedia_transport *tp,
|
|||
return pjmedia_transport_simulate_lost(adapter->slave_tp, dir, pct_lost);
|
||||
}
|
||||
|
||||
|
||||
static void adapter_on_destroy(void *arg)
|
||||
{
|
||||
struct tp_adapter *adapter = (struct tp_adapter*)arg;
|
||||
|
||||
pj_pool_release(adapter->pool);
|
||||
}
|
||||
|
||||
/*
|
||||
* destroy() is called when the transport is no longer needed.
|
||||
*/
|
||||
|
@ -453,11 +433,8 @@ static pj_status_t transport_destroy (pjmedia_transport *tp)
|
|||
pjmedia_transport_close(adapter->slave_tp);
|
||||
}
|
||||
|
||||
if (adapter->base.grp_lock) {
|
||||
pj_grp_lock_dec_ref(adapter->base.grp_lock);
|
||||
} else {
|
||||
adapter_on_destroy(tp);
|
||||
}
|
||||
/* Self destruct.. */
|
||||
pj_pool_release(adapter->pool);
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -338,7 +338,6 @@ PJ_DEF(pj_status_t) pjmedia_ice_create3(pjmedia_endpt *endpt,
|
|||
pj_grp_lock_t *grp_lock = pj_ice_strans_get_grp_lock(tp_ice->ice_st);
|
||||
pj_grp_lock_add_ref(grp_lock);
|
||||
pj_grp_lock_add_handler(grp_lock, pool, tp_ice, &tp_ice_on_destroy);
|
||||
tp_ice->base.grp_lock = grp_lock;
|
||||
}
|
||||
|
||||
/* Done */
|
||||
|
@ -2737,8 +2736,6 @@ static pj_status_t transport_simulate_lost(pjmedia_transport *tp,
|
|||
static void tp_ice_on_destroy(void *arg)
|
||||
{
|
||||
struct transport_ice *tp_ice = (struct transport_ice*)arg;
|
||||
|
||||
PJ_LOG(4, (tp_ice->base.name, "ICE transport destroyed"));
|
||||
pj_pool_safe_release(&tp_ice->pool);
|
||||
}
|
||||
|
||||
|
@ -2749,8 +2746,6 @@ static pj_status_t transport_destroy(pjmedia_transport *tp)
|
|||
{
|
||||
struct transport_ice *tp_ice = (struct transport_ice*)tp;
|
||||
|
||||
PJ_LOG(4, (tp_ice->base.name, "Destroying ICE transport"));
|
||||
|
||||
/* Reset callback and user data */
|
||||
pj_bzero(&tp_ice->cb, sizeof(tp_ice->cb));
|
||||
tp_ice->base.user_data = NULL;
|
||||
|
|
|
@ -130,7 +130,6 @@ static pjmedia_transport_op transport_udp_op =
|
|||
&transport_attach2
|
||||
};
|
||||
|
||||
static void tp_loop_on_destroy(void *arg);
|
||||
|
||||
/**
|
||||
* Initialize loopback media transport setting with its default values.
|
||||
|
@ -165,8 +164,6 @@ pjmedia_transport_loop_create2(pjmedia_endpt *endpt,
|
|||
{
|
||||
struct transport_loop *tp;
|
||||
pj_pool_t *pool;
|
||||
pj_grp_lock_t *grp_lock;
|
||||
pj_status_t status;
|
||||
|
||||
/* Sanity check */
|
||||
PJ_ASSERT_RETURN(endpt && p_tp, PJ_EINVAL);
|
||||
|
@ -182,15 +179,6 @@ pjmedia_transport_loop_create2(pjmedia_endpt *endpt,
|
|||
tp->base.op = &transport_udp_op;
|
||||
tp->base.type = PJMEDIA_TRANSPORT_TYPE_UDP;
|
||||
|
||||
/* Create group lock */
|
||||
status = pj_grp_lock_create(pool, NULL, &grp_lock);
|
||||
if (status != PJ_SUCCESS)
|
||||
return status;
|
||||
|
||||
tp->base.grp_lock = grp_lock;
|
||||
pj_grp_lock_add_ref(grp_lock);
|
||||
pj_grp_lock_add_handler(grp_lock, pool, tp, &tp_loop_on_destroy);
|
||||
|
||||
if (opt) {
|
||||
tp->setting = *opt;
|
||||
} else {
|
||||
|
@ -234,25 +222,17 @@ PJ_DEF(pj_status_t) pjmedia_transport_loop_disable_rx( pjmedia_transport *tp,
|
|||
return PJ_ENOTFOUND;
|
||||
}
|
||||
|
||||
|
||||
static void tp_loop_on_destroy(void *arg)
|
||||
{
|
||||
struct transport_loop *loop = (struct transport_loop*) arg;
|
||||
|
||||
PJ_LOG(4, (loop->base.name, "Loop transport destroyed"));
|
||||
pj_pool_release(loop->pool);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Close loopback transport.
|
||||
*/
|
||||
static pj_status_t transport_destroy(pjmedia_transport *tp)
|
||||
{
|
||||
struct transport_loop *loop = (struct transport_loop*) tp;
|
||||
|
||||
/* Sanity check */
|
||||
PJ_ASSERT_RETURN(tp, PJ_EINVAL);
|
||||
|
||||
pj_grp_lock_dec_ref(tp->grp_lock);
|
||||
pj_pool_release(loop->pool);
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
@ -398,8 +378,6 @@ static pj_status_t transport_send_rtp( pjmedia_transport *tp,
|
|||
}
|
||||
}
|
||||
|
||||
pj_grp_lock_add_ref(tp->grp_lock);
|
||||
|
||||
/* Distribute to users */
|
||||
for (i=0; i<loop->user_cnt; ++i) {
|
||||
if (loop->users[i].rx_disabled) continue;
|
||||
|
@ -417,8 +395,6 @@ static pj_status_t transport_send_rtp( pjmedia_transport *tp,
|
|||
}
|
||||
}
|
||||
|
||||
pj_grp_lock_dec_ref(tp->grp_lock);
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -444,8 +420,6 @@ static pj_status_t transport_send_rtcp2(pjmedia_transport *tp,
|
|||
PJ_UNUSED_ARG(addr_len);
|
||||
PJ_UNUSED_ARG(addr);
|
||||
|
||||
pj_grp_lock_add_ref(tp->grp_lock);
|
||||
|
||||
/* Distribute to users */
|
||||
for (i=0; i<loop->user_cnt; ++i) {
|
||||
if (!loop->users[i].rx_disabled && loop->users[i].rtcp_cb)
|
||||
|
@ -453,8 +427,6 @@ static pj_status_t transport_send_rtcp2(pjmedia_transport *tp,
|
|||
size);
|
||||
}
|
||||
|
||||
pj_grp_lock_dec_ref(tp->grp_lock);
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -434,8 +434,6 @@ static pj_status_t create_srtp_ctx(transport_srtp *srtp,
|
|||
/* Destroy SRTP context */
|
||||
static void destroy_srtp_ctx(transport_srtp *p_srtp, srtp_context *ctx);
|
||||
|
||||
/* SRTP destroy handler */
|
||||
static void srtp_on_destroy(void *arg);
|
||||
|
||||
/* This function may also be used by other module, e.g: pjmedia/errno.c,
|
||||
* it should have C compatible declaration.
|
||||
|
@ -541,7 +539,6 @@ PJ_DEF(pj_status_t) pjmedia_srtp_init_lib(pjmedia_endpt *endpt)
|
|||
if (err != srtp_err_status_ok) {
|
||||
PJ_LOG(4, (THIS_FILE, "Failed to initialize libsrtp: %s",
|
||||
get_libsrtp_errstr(err)));
|
||||
pjmedia_srtp_deinit_lib(endpt);
|
||||
return PJMEDIA_ERRNO_FROM_LIBSRTP(err);
|
||||
}
|
||||
}
|
||||
|
@ -807,13 +804,6 @@ PJ_DEF(pj_status_t) pjmedia_transport_srtp_create(
|
|||
/* Set underlying transport */
|
||||
srtp->member_tp = tp;
|
||||
|
||||
/* Setup group lock handler for destroy and callback synchronization */
|
||||
if (tp && tp->grp_lock) {
|
||||
srtp->base.grp_lock = tp->grp_lock;
|
||||
pj_grp_lock_add_ref(tp->grp_lock);
|
||||
pj_grp_lock_add_handler(tp->grp_lock, pool, srtp, &srtp_on_destroy);
|
||||
}
|
||||
|
||||
/* Initialize peer's SRTP usage mode. */
|
||||
srtp->peer_use = srtp->setting.use;
|
||||
|
||||
|
@ -848,8 +838,6 @@ PJ_DEF(pj_status_t) pjmedia_transport_srtp_create(
|
|||
/* Done */
|
||||
*p_tp = &srtp->base;
|
||||
|
||||
PJ_LOG(4, (srtp->pool->obj_name, "SRTP transport created"));
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1470,19 +1458,6 @@ static pj_status_t transport_simulate_lost(pjmedia_transport *tp,
|
|||
return pjmedia_transport_simulate_lost(srtp->member_tp, dir, pct_lost);
|
||||
}
|
||||
|
||||
|
||||
/* SRTP real destroy */
|
||||
static void srtp_on_destroy(void *arg)
|
||||
{
|
||||
transport_srtp *srtp = (transport_srtp*)arg;
|
||||
|
||||
PJ_LOG(4, (srtp->pool->obj_name, "SRTP transport destroyed"));
|
||||
|
||||
pj_lock_destroy(srtp->mutex);
|
||||
pj_pool_safe_release(&srtp->pool);
|
||||
}
|
||||
|
||||
|
||||
static pj_status_t transport_destroy (pjmedia_transport *tp)
|
||||
{
|
||||
transport_srtp *srtp = (transport_srtp *) tp;
|
||||
|
@ -1491,8 +1466,6 @@ static pj_status_t transport_destroy (pjmedia_transport *tp)
|
|||
|
||||
PJ_ASSERT_RETURN(tp, PJ_EINVAL);
|
||||
|
||||
PJ_LOG(4, (srtp->pool->obj_name, "Destroying SRTP transport"));
|
||||
|
||||
/* Close all keying. Note that any keying should not be destroyed before
|
||||
* SRTP transport is destroyed as re-INVITE may initiate new keying method
|
||||
* without destroying SRTP transport.
|
||||
|
@ -1507,25 +1480,12 @@ static pj_status_t transport_destroy (pjmedia_transport *tp)
|
|||
|
||||
status = pjmedia_transport_srtp_stop(tp);
|
||||
|
||||
if (srtp->base.grp_lock) {
|
||||
pj_grp_lock_dec_ref(srtp->base.grp_lock);
|
||||
} else {
|
||||
/* Only get here when the underlying transport does not have
|
||||
* a group lock, race condition with callbacks may occur.
|
||||
* Currently UDP, ICE, and loop have a group lock already.
|
||||
*/
|
||||
PJ_LOG(4,(srtp->pool->obj_name,
|
||||
"Warning: underlying transport does not have group lock"));
|
||||
/* In case mutex is being acquired by other thread */
|
||||
pj_lock_acquire(srtp->mutex);
|
||||
pj_lock_release(srtp->mutex);
|
||||
|
||||
/* In case mutex is being acquired by other thread.
|
||||
* An effort to synchronize destroy() & callbacks when the underlying
|
||||
* transport does not provide a group lock.
|
||||
*/
|
||||
pj_lock_acquire(srtp->mutex);
|
||||
pj_lock_release(srtp->mutex);
|
||||
|
||||
srtp_on_destroy(srtp);
|
||||
}
|
||||
pj_lock_destroy(srtp->mutex);
|
||||
pj_pool_release(srtp->pool);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
@ -80,8 +80,6 @@ static void on_ice_complete2(pjmedia_transport *tp,
|
|||
pj_status_t status,
|
||||
void *user_data);
|
||||
|
||||
static void dtls_on_destroy(void *arg);
|
||||
|
||||
|
||||
static pjmedia_transport_op dtls_op =
|
||||
{
|
||||
|
@ -136,7 +134,6 @@ typedef struct dtls_srtp
|
|||
pj_bool_t pending_start; /* media_start() invoked but DTLS
|
||||
nego not done yet, so start
|
||||
the SRTP once the nego done */
|
||||
pj_bool_t is_destroying; /* DTLS being destroyed? */
|
||||
pj_bool_t got_keys; /* DTLS nego done & keys ready */
|
||||
pjmedia_srtp_crypto tx_crypto[NUM_CHANNEL];
|
||||
pjmedia_srtp_crypto rx_crypto[NUM_CHANNEL];
|
||||
|
@ -272,7 +269,7 @@ static pj_status_t dtls_create(transport_srtp *srtp,
|
|||
{
|
||||
dtls_srtp *ds;
|
||||
pj_pool_t *pool;
|
||||
pj_status_t status;
|
||||
pj_status_t status;
|
||||
|
||||
pool = pj_pool_create(srtp->pool->factory, "dtls%p",
|
||||
2000, 256, NULL);
|
||||
|
@ -285,19 +282,10 @@ static pj_status_t dtls_create(transport_srtp *srtp,
|
|||
ds->base.user_data = srtp;
|
||||
ds->srtp = srtp;
|
||||
|
||||
/* Setup group lock handler for destroy and callback synchronization */
|
||||
if (srtp->base.grp_lock) {
|
||||
pj_grp_lock_t *grp_lock = srtp->base.grp_lock;
|
||||
|
||||
ds->base.grp_lock = grp_lock;
|
||||
pj_grp_lock_add_ref(grp_lock);
|
||||
pj_grp_lock_add_handler(grp_lock, pool, ds, &dtls_on_destroy);
|
||||
} else {
|
||||
status = pj_lock_create_recursive_mutex(ds->pool, "dtls_ssl_lock%p",
|
||||
&ds->ossl_lock);
|
||||
if (status != PJ_SUCCESS)
|
||||
return status;
|
||||
}
|
||||
status = pj_lock_create_simple_mutex(ds->pool, "dtls_ssl_lock%p",
|
||||
&ds->ossl_lock);
|
||||
if (status != PJ_SUCCESS)
|
||||
return status;
|
||||
|
||||
*p_keying = &ds->base;
|
||||
PJ_LOG(5,(srtp->pool->obj_name, "SRTP keying DTLS-SRTP created"));
|
||||
|
@ -305,30 +293,6 @@ static pj_status_t dtls_create(transport_srtp *srtp,
|
|||
}
|
||||
|
||||
|
||||
/* Lock/unlock for DTLS states access protection */
|
||||
|
||||
static void DTLS_LOCK(dtls_srtp *ds) {
|
||||
if (ds->base.grp_lock)
|
||||
pj_grp_lock_acquire(ds->base.grp_lock);
|
||||
else
|
||||
pj_lock_acquire(ds->ossl_lock);
|
||||
}
|
||||
|
||||
static pj_status_t DTLS_TRY_LOCK(dtls_srtp *ds) {
|
||||
if (ds->base.grp_lock)
|
||||
return pj_grp_lock_tryacquire(ds->base.grp_lock);
|
||||
else
|
||||
return pj_lock_tryacquire(ds->ossl_lock);
|
||||
}
|
||||
|
||||
static void DTLS_UNLOCK(dtls_srtp *ds) {
|
||||
if (ds->base.grp_lock)
|
||||
pj_grp_lock_release(ds->base.grp_lock);
|
||||
else
|
||||
pj_lock_release(ds->ossl_lock);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Mapping from OpenSSL error codes to pjlib error space.
|
||||
*/
|
||||
|
@ -464,7 +428,7 @@ static pj_status_t ssl_generate_cert(X509 **p_cert, EVP_PKEY **p_priv_key)
|
|||
if (!X509_set_pubkey(cert, priv_key)) goto on_error;
|
||||
|
||||
/* Sign with the private key */
|
||||
if (!X509_sign(cert, priv_key, EVP_sha256())) goto on_error;
|
||||
if (!X509_sign(cert, priv_key, EVP_sha1())) goto on_error;
|
||||
|
||||
/* Free big number */
|
||||
BN_free(bne);
|
||||
|
@ -581,7 +545,7 @@ static pj_status_t ssl_create(dtls_srtp *ds, unsigned idx)
|
|||
/* Destroy SSL context and instance */
|
||||
static void ssl_destroy(dtls_srtp *ds, unsigned idx)
|
||||
{
|
||||
DTLS_LOCK(ds);
|
||||
pj_lock_acquire(ds->ossl_lock);
|
||||
|
||||
/* Destroy SSL instance */
|
||||
if (ds->ossl_ssl[idx]) {
|
||||
|
@ -606,7 +570,7 @@ static void ssl_destroy(dtls_srtp *ds, unsigned idx)
|
|||
ds->ossl_ctx[idx] = NULL;
|
||||
}
|
||||
|
||||
DTLS_UNLOCK(ds);
|
||||
pj_lock_release(ds->ossl_lock);
|
||||
}
|
||||
|
||||
static pj_status_t ssl_get_srtp_material(dtls_srtp *ds, unsigned idx)
|
||||
|
@ -617,7 +581,7 @@ static pj_status_t ssl_get_srtp_material(dtls_srtp *ds, unsigned idx)
|
|||
pjmedia_srtp_crypto *tx, *rx;
|
||||
pj_status_t status = PJ_SUCCESS;
|
||||
|
||||
DTLS_LOCK(ds);
|
||||
pj_lock_acquire(ds->ossl_lock);
|
||||
|
||||
if (!ds->ossl_ssl[idx]) {
|
||||
status = PJ_EGONE;
|
||||
|
@ -688,7 +652,7 @@ static pj_status_t ssl_get_srtp_material(dtls_srtp *ds, unsigned idx)
|
|||
}
|
||||
|
||||
on_return:
|
||||
DTLS_UNLOCK(ds);
|
||||
pj_lock_release(ds->ossl_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
|
@ -712,16 +676,16 @@ static pj_status_t ssl_match_fingerprint(dtls_srtp *ds, unsigned idx)
|
|||
return PJ_ENOTSUP;
|
||||
}
|
||||
|
||||
DTLS_LOCK(ds);
|
||||
pj_lock_acquire(ds->ossl_lock);
|
||||
if (!ds->ossl_ssl[idx]) {
|
||||
DTLS_UNLOCK(ds);
|
||||
pj_lock_release(ds->ossl_lock);
|
||||
return PJ_EGONE;
|
||||
}
|
||||
|
||||
/* Get remote cert & calculate the hash */
|
||||
rem_cert = SSL_get_peer_certificate(ds->ossl_ssl[idx]);
|
||||
|
||||
DTLS_UNLOCK(ds);
|
||||
pj_lock_release(ds->ossl_lock);
|
||||
|
||||
if (!rem_cert)
|
||||
return PJMEDIA_SRTP_DTLS_EPEERNOCERT;
|
||||
|
@ -745,7 +709,7 @@ static pj_status_t send_raw(dtls_srtp *ds, unsigned idx, const void *buf,
|
|||
{
|
||||
#if DTLS_DEBUG
|
||||
PJ_LOG(2,(ds->base.name, "DTLS-SRTP %s sending %lu bytes",
|
||||
CHANNEL_TO_STRING(idx), (unsigned long)len));
|
||||
CHANNEL_TO_STRING(idx), len));
|
||||
#endif
|
||||
|
||||
return (idx == RTP_CHANNEL?
|
||||
|
@ -784,10 +748,10 @@ static pj_status_t ssl_flush_wbio(dtls_srtp *ds, unsigned idx)
|
|||
pj_size_t len;
|
||||
pj_status_t status = PJ_SUCCESS;
|
||||
|
||||
DTLS_LOCK(ds);
|
||||
pj_lock_acquire(ds->ossl_lock);
|
||||
|
||||
if (!ds->ossl_wbio[idx]) {
|
||||
DTLS_UNLOCK(ds);
|
||||
pj_lock_release(ds->ossl_lock);
|
||||
return PJ_EGONE;
|
||||
}
|
||||
|
||||
|
@ -796,7 +760,7 @@ static pj_status_t ssl_flush_wbio(dtls_srtp *ds, unsigned idx)
|
|||
/* Yes, get and send it */
|
||||
len = BIO_read(ds->ossl_wbio[idx], ds->buf[idx], sizeof(ds->buf));
|
||||
if (len > 0) {
|
||||
DTLS_UNLOCK(ds);
|
||||
pj_lock_release(ds->ossl_lock);
|
||||
|
||||
status = send_raw(ds, idx, ds->buf[idx], len);
|
||||
if (status != PJ_SUCCESS) {
|
||||
|
@ -807,12 +771,12 @@ static pj_status_t ssl_flush_wbio(dtls_srtp *ds, unsigned idx)
|
|||
* its packet when not receiving from us.
|
||||
*/
|
||||
}
|
||||
DTLS_LOCK(ds);
|
||||
pj_lock_acquire(ds->ossl_lock);
|
||||
}
|
||||
}
|
||||
|
||||
if (!ds->ossl_ssl[idx]) {
|
||||
DTLS_UNLOCK(ds);
|
||||
pj_lock_release(ds->ossl_lock);
|
||||
return PJ_EGONE;
|
||||
}
|
||||
|
||||
|
@ -820,7 +784,7 @@ static pj_status_t ssl_flush_wbio(dtls_srtp *ds, unsigned idx)
|
|||
* verification, etc) has been done or handshake is still in progress.
|
||||
*/
|
||||
if (ds->nego_completed[idx] || !SSL_is_init_finished(ds->ossl_ssl[idx])) {
|
||||
DTLS_UNLOCK(ds);
|
||||
pj_lock_release(ds->ossl_lock);
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -829,6 +793,8 @@ static pj_status_t ssl_flush_wbio(dtls_srtp *ds, unsigned idx)
|
|||
PJ_LOG(2,(ds->base.name, "DTLS-SRTP negotiation for %s completed!",
|
||||
CHANNEL_TO_STRING(idx)));
|
||||
|
||||
pj_lock_release(ds->ossl_lock);
|
||||
|
||||
/* Stop the retransmission clock. Note that the clock may not be stopped
|
||||
* if this function is called from clock thread context. We'll try again
|
||||
* later in socket context.
|
||||
|
@ -836,8 +802,6 @@ static pj_status_t ssl_flush_wbio(dtls_srtp *ds, unsigned idx)
|
|||
if (ds->clock[idx])
|
||||
pjmedia_clock_stop(ds->clock[idx]);
|
||||
|
||||
DTLS_UNLOCK(ds);
|
||||
|
||||
/* Get SRTP key material */
|
||||
status = ssl_get_srtp_material(ds, idx);
|
||||
if (status != PJ_SUCCESS) {
|
||||
|
@ -900,38 +864,21 @@ static void clock_cb(const pj_timestamp *ts, void *user_data)
|
|||
dtls_srtp_channel *ds_ch = (dtls_srtp_channel*)user_data;
|
||||
dtls_srtp *ds = ds_ch->dtls_srtp;
|
||||
unsigned idx = ds_ch->channel;
|
||||
pj_status_t status;
|
||||
|
||||
PJ_UNUSED_ARG(ts);
|
||||
|
||||
while (1) {
|
||||
/* Check if we should quit before trying to acquire the lock. */
|
||||
if (ds->nego_completed[idx])
|
||||
return;
|
||||
|
||||
/* To avoid deadlock, we must use TRY_LOCK here. */
|
||||
status = DTLS_TRY_LOCK(ds);
|
||||
if (status == PJ_SUCCESS)
|
||||
break;
|
||||
|
||||
/* Acquiring lock failed, check if we have been signaled to quit. */
|
||||
if (ds->nego_completed[idx])
|
||||
return;
|
||||
|
||||
pj_thread_sleep(20);
|
||||
}
|
||||
|
||||
pj_lock_acquire(ds->ossl_lock);
|
||||
|
||||
if (!ds->ossl_ssl[idx]) {
|
||||
DTLS_UNLOCK(ds);
|
||||
pj_lock_release(ds->ossl_lock);
|
||||
return;
|
||||
}
|
||||
|
||||
if (DTLSv1_handle_timeout(ds->ossl_ssl[idx]) > 0) {
|
||||
DTLS_UNLOCK(ds);
|
||||
pj_lock_release(ds->ossl_lock);
|
||||
ssl_flush_wbio(ds, idx);
|
||||
} else {
|
||||
DTLS_UNLOCK(ds);
|
||||
pj_lock_release(ds->ossl_lock);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -942,18 +889,18 @@ static pj_status_t ssl_handshake_channel(dtls_srtp *ds, unsigned idx)
|
|||
pj_status_t status;
|
||||
int err;
|
||||
|
||||
DTLS_LOCK(ds);
|
||||
pj_lock_acquire(ds->ossl_lock);
|
||||
|
||||
/* Init DTLS (if not yet) */
|
||||
status = ssl_create(ds, idx);
|
||||
if (status != PJ_SUCCESS) {
|
||||
DTLS_UNLOCK(ds);
|
||||
pj_lock_release(ds->ossl_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Check if handshake has been initiated or even completed */
|
||||
if (ds->nego_started[idx] || SSL_is_init_finished(ds->ossl_ssl[idx])) {
|
||||
DTLS_UNLOCK(ds);
|
||||
pj_lock_release(ds->ossl_lock);
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -967,7 +914,7 @@ static pj_status_t ssl_handshake_channel(dtls_srtp *ds, unsigned idx)
|
|||
if (err < 0) {
|
||||
err = SSL_get_error(ds->ossl_ssl[idx], err);
|
||||
|
||||
DTLS_UNLOCK(ds);
|
||||
pj_lock_release(ds->ossl_lock);
|
||||
|
||||
if (err == SSL_ERROR_WANT_READ) {
|
||||
status = ssl_flush_wbio(ds, idx);
|
||||
|
@ -980,7 +927,7 @@ static pj_status_t ssl_handshake_channel(dtls_srtp *ds, unsigned idx)
|
|||
goto on_return;
|
||||
}
|
||||
} else {
|
||||
DTLS_UNLOCK(ds);
|
||||
pj_lock_release(ds->ossl_lock);
|
||||
}
|
||||
|
||||
/* Create and start clock @4Hz for retransmission */
|
||||
|
@ -1005,7 +952,6 @@ static pj_status_t ssl_handshake_channel(dtls_srtp *ds, unsigned idx)
|
|||
|
||||
on_return:
|
||||
if (status != PJ_SUCCESS) {
|
||||
ds->nego_completed[idx] = PJ_TRUE;
|
||||
if (ds->clock[idx])
|
||||
pjmedia_clock_stop(ds->clock[idx]);
|
||||
}
|
||||
|
@ -1189,10 +1135,10 @@ static pj_status_t ssl_on_recv_packet(dtls_srtp *ds, unsigned idx,
|
|||
char tmp[128];
|
||||
pj_size_t nwritten;
|
||||
|
||||
DTLS_LOCK(ds);
|
||||
pj_lock_acquire(ds->ossl_lock);
|
||||
|
||||
if (!ds->ossl_rbio[idx]) {
|
||||
DTLS_UNLOCK(ds);
|
||||
pj_lock_release(ds->ossl_lock);
|
||||
return PJ_EGONE;
|
||||
}
|
||||
|
||||
|
@ -1204,12 +1150,12 @@ static pj_status_t ssl_on_recv_packet(dtls_srtp *ds, unsigned idx,
|
|||
#if DTLS_DEBUG
|
||||
pj_perror(2, ds->base.name, status, "BIO_write() error");
|
||||
#endif
|
||||
DTLS_UNLOCK(ds);
|
||||
pj_lock_release(ds->ossl_lock);
|
||||
return status;
|
||||
}
|
||||
|
||||
if (!ds->ossl_ssl[idx]) {
|
||||
DTLS_UNLOCK(ds);
|
||||
pj_lock_release(ds->ossl_lock);
|
||||
return PJ_EGONE;
|
||||
}
|
||||
|
||||
|
@ -1226,7 +1172,7 @@ static pj_status_t ssl_on_recv_packet(dtls_srtp *ds, unsigned idx,
|
|||
}
|
||||
}
|
||||
|
||||
DTLS_UNLOCK(ds);
|
||||
pj_lock_release(ds->ossl_lock);
|
||||
|
||||
/* Flush anything pending in the write BIO */
|
||||
return ssl_flush_wbio(ds, idx);
|
||||
|
@ -1265,22 +1211,18 @@ static pj_status_t dtls_on_recv(pjmedia_transport *tp, unsigned idx,
|
|||
{
|
||||
dtls_srtp *ds = (dtls_srtp*)tp;
|
||||
|
||||
DTLS_LOCK(ds);
|
||||
|
||||
/* Destroy the retransmission clock if handshake has been completed. */
|
||||
if (ds->clock[idx] && ds->nego_completed[idx]) {
|
||||
pjmedia_clock_destroy(ds->clock[idx]);
|
||||
ds->clock[idx] = NULL;
|
||||
}
|
||||
|
||||
if (size < 1 || !IS_DTLS_PKT(pkt, size) || ds->is_destroying) {
|
||||
DTLS_UNLOCK(ds);
|
||||
if (size < 1 || !IS_DTLS_PKT(pkt, size))
|
||||
return PJ_EIGNORED;
|
||||
}
|
||||
|
||||
#if DTLS_DEBUG
|
||||
PJ_LOG(2,(ds->base.name, "DTLS-SRTP %s receiving %lu bytes",
|
||||
CHANNEL_TO_STRING(idx), (unsigned long)size));
|
||||
CHANNEL_TO_STRING(idx), size));
|
||||
#endif
|
||||
|
||||
/* This is DTLS packet, let's process it. Note that if DTLS nego has
|
||||
|
@ -1289,66 +1231,44 @@ static pj_status_t dtls_on_recv(pjmedia_transport *tp, unsigned idx,
|
|||
*/
|
||||
|
||||
/* Check remote address info, reattach member tp if changed */
|
||||
if (!ds->use_ice && !ds->nego_completed[idx]) {
|
||||
if (idx == RTP_CHANNEL && !ds->use_ice && !ds->nego_completed[idx]) {
|
||||
pjmedia_transport_info info;
|
||||
pj_bool_t reattach_tp = PJ_FALSE;
|
||||
|
||||
pjmedia_transport_get_info(ds->srtp->member_tp, &info);
|
||||
|
||||
if (idx == RTP_CHANNEL &&
|
||||
pj_sockaddr_cmp(&ds->rem_addr, &info.src_rtp_name))
|
||||
{
|
||||
pj_sockaddr_cp(&ds->rem_addr, &info.src_rtp_name);
|
||||
reattach_tp = PJ_TRUE;
|
||||
} else if (idx == RTCP_CHANNEL && !ds->srtp->use_rtcp_mux &&
|
||||
pj_sockaddr_has_addr(&info.src_rtcp_name) &&
|
||||
pj_sockaddr_cmp(&ds->rem_rtcp, &info.src_rtcp_name))
|
||||
{
|
||||
pj_sockaddr_cp(&ds->rem_rtcp, &info.src_rtcp_name);
|
||||
reattach_tp = PJ_TRUE;
|
||||
}
|
||||
|
||||
if (reattach_tp) {
|
||||
if (pj_sockaddr_cmp(&ds->rem_addr, &info.src_rtp_name)) {
|
||||
pjmedia_transport_attach_param ap;
|
||||
pj_status_t status;
|
||||
|
||||
/* Attach member transport */
|
||||
pj_bzero(&ap, sizeof(ap));
|
||||
ap.user_data = ds->srtp;
|
||||
if (pj_sockaddr_has_addr(&ds->rem_addr)) {
|
||||
pj_sockaddr_cp(&ap.rem_addr, &ds->rem_addr);
|
||||
} else {
|
||||
pj_sockaddr_init(pj_AF_INET(), &ap.rem_addr, 0, 0);
|
||||
}
|
||||
if (ds->srtp->use_rtcp_mux) {
|
||||
pj_sockaddr_cp(&ds->rem_addr, &info.src_rtp_name);
|
||||
pj_sockaddr_cp(&ap.rem_addr, &ds->rem_addr);
|
||||
ap.addr_len = pj_sockaddr_get_len(&ap.rem_addr);
|
||||
if (pj_sockaddr_cmp(&info.sock_info.rtp_addr_name,
|
||||
&info.sock_info.rtcp_addr_name) == 0)
|
||||
{
|
||||
/* Using RTP & RTCP multiplexing */
|
||||
pj_sockaddr_cp(&ap.rem_rtcp, &ap.rem_addr);
|
||||
pj_sockaddr_cp(&ds->rem_rtcp, &ds->rem_addr);
|
||||
pj_sockaddr_cp(&ap.rem_rtcp, &ds->rem_rtcp);
|
||||
} else if (pj_sockaddr_has_addr(&ds->rem_rtcp)) {
|
||||
pj_sockaddr_cp(&ap.rem_rtcp, &ds->rem_rtcp);
|
||||
} else if (pj_sockaddr_has_addr(&ds->rem_addr)) {
|
||||
} else {
|
||||
pj_sockaddr_cp(&ap.rem_rtcp, &ds->rem_addr);
|
||||
pj_sockaddr_set_port(&ap.rem_rtcp,
|
||||
pj_sockaddr_get_port(&ap.rem_rtcp) + 1);
|
||||
} else {
|
||||
pj_sockaddr_init(pj_AF_INET(), &ap.rem_rtcp, 0, 0);
|
||||
pj_sockaddr_get_port(&ds->rem_addr)+1);
|
||||
}
|
||||
ap.addr_len = pj_sockaddr_get_len(&ap.rem_addr);
|
||||
|
||||
status = pjmedia_transport_attach2(&ds->srtp->base, &ap);
|
||||
if (status != PJ_SUCCESS) {
|
||||
DTLS_UNLOCK(ds);
|
||||
if (status != PJ_SUCCESS)
|
||||
return status;
|
||||
}
|
||||
|
||||
#if DTLS_DEBUG
|
||||
{
|
||||
char addr[PJ_INET6_ADDRSTRLEN];
|
||||
char addr2[PJ_INET6_ADDRSTRLEN];
|
||||
PJ_LOG(2,(ds->base.name, "Re-attached transport to update "
|
||||
"remote addr=%s remote rtcp=%s",
|
||||
"remote addr=%s:%d",
|
||||
pj_sockaddr_print(&ap.rem_addr, addr,
|
||||
sizeof(addr), 3),
|
||||
pj_sockaddr_print(&ap.rem_rtcp, addr2,
|
||||
sizeof(addr2), 3)));
|
||||
sizeof(addr), 2),
|
||||
pj_sockaddr_get_port(&ap.rem_addr)));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1363,17 +1283,12 @@ static pj_status_t dtls_on_recv(pjmedia_transport *tp, unsigned idx,
|
|||
pj_status_t status;
|
||||
ds->setup = DTLS_SETUP_PASSIVE;
|
||||
status = ssl_handshake_channel(ds, idx);
|
||||
if (status != PJ_SUCCESS) {
|
||||
DTLS_UNLOCK(ds);
|
||||
if (status != PJ_SUCCESS)
|
||||
return status;
|
||||
}
|
||||
}
|
||||
|
||||
DTLS_UNLOCK(ds);
|
||||
|
||||
/* Send it to OpenSSL */
|
||||
ssl_on_recv_packet(ds, idx, pkt, size);
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -1472,7 +1387,6 @@ on_return:
|
|||
|
||||
static void dtls_media_stop_channel(dtls_srtp *ds, unsigned idx)
|
||||
{
|
||||
ds->nego_completed[idx] = PJ_TRUE;
|
||||
if (ds->clock[idx])
|
||||
pjmedia_clock_stop(ds->clock[idx]);
|
||||
|
||||
|
@ -1673,11 +1587,9 @@ static pj_status_t dtls_encode_sdp( pjmedia_transport *tp,
|
|||
#if DTLS_DEBUG
|
||||
{
|
||||
char addr[PJ_INET6_ADDRSTRLEN];
|
||||
char addr2[PJ_INET6_ADDRSTRLEN];
|
||||
PJ_LOG(2,(ds->base.name, "Attached transport, remote addr=%s "
|
||||
"remote rtcp=%s",
|
||||
pj_sockaddr_print(&ap.rem_addr, addr2, sizeof(addr2), 3),
|
||||
pj_sockaddr_print(&ap.rem_rtcp, addr, sizeof(addr), 3)));
|
||||
PJ_LOG(2,(ds->base.name, "Attached transport, remote addr=%s:%d",
|
||||
pj_sockaddr_print(&ap.rem_addr, addr, sizeof(addr), 2),
|
||||
pj_sockaddr_get_port(&ap.rem_addr)));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
@ -1857,13 +1769,11 @@ static pj_status_t dtls_media_start( pjmedia_transport *tp,
|
|||
#if DTLS_DEBUG
|
||||
{
|
||||
char addr[PJ_INET6_ADDRSTRLEN];
|
||||
char addr2[PJ_INET6_ADDRSTRLEN];
|
||||
PJ_LOG(2,(ds->base.name, "Attached transport, "
|
||||
"remote addr=%s remote rtcp=%s",
|
||||
"remote addr=%s:%d",
|
||||
pj_sockaddr_print(&ap.rem_addr, addr,
|
||||
sizeof(addr), 3),
|
||||
pj_sockaddr_print(&ap.rem_rtcp, addr2,
|
||||
sizeof(addr2), 3)));
|
||||
sizeof(addr), 2),
|
||||
pj_sockaddr_get_port(&ap.rem_addr)));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
@ -1890,10 +1800,8 @@ static pj_status_t dtls_media_stop(pjmedia_transport *tp)
|
|||
PJ_LOG(2,(ds->base.name, "dtls_media_stop()"));
|
||||
#endif
|
||||
|
||||
DTLS_LOCK(ds);
|
||||
dtls_media_stop_channel(ds, RTP_CHANNEL);
|
||||
dtls_media_stop_channel(ds, RTCP_CHANNEL);
|
||||
DTLS_UNLOCK(ds);
|
||||
|
||||
ds->setup = DTLS_SETUP_UNKNOWN;
|
||||
ds->use_ice = PJ_FALSE;
|
||||
|
@ -1907,22 +1815,12 @@ static pj_status_t dtls_media_stop(pjmedia_transport *tp)
|
|||
static void dtls_destroy_channel(dtls_srtp *ds, unsigned idx)
|
||||
{
|
||||
if (ds->clock[idx]) {
|
||||
ds->nego_completed[idx] = PJ_TRUE;
|
||||
pjmedia_clock_destroy(ds->clock[idx]);
|
||||
ds->clock[idx] = NULL;
|
||||
}
|
||||
ssl_destroy(ds, idx);
|
||||
}
|
||||
|
||||
static void dtls_on_destroy(void *arg) {
|
||||
dtls_srtp *ds = (dtls_srtp *)arg;
|
||||
|
||||
if (ds->ossl_lock)
|
||||
pj_lock_destroy(ds->ossl_lock);
|
||||
|
||||
pj_pool_safe_release(&ds->pool);
|
||||
}
|
||||
|
||||
static pj_status_t dtls_destroy(pjmedia_transport *tp)
|
||||
{
|
||||
dtls_srtp *ds = (dtls_srtp *)tp;
|
||||
|
@ -1931,21 +1829,16 @@ static pj_status_t dtls_destroy(pjmedia_transport *tp)
|
|||
PJ_LOG(2,(ds->base.name, "dtls_destroy()"));
|
||||
#endif
|
||||
|
||||
ds->is_destroying = PJ_TRUE;
|
||||
|
||||
DTLS_LOCK(ds);
|
||||
|
||||
dtls_destroy_channel(ds, RTP_CHANNEL);
|
||||
dtls_destroy_channel(ds, RTCP_CHANNEL);
|
||||
|
||||
DTLS_UNLOCK(ds);
|
||||
|
||||
if (ds->base.grp_lock) {
|
||||
pj_grp_lock_dec_ref(ds->base.grp_lock);
|
||||
} else {
|
||||
dtls_on_destroy(tp);
|
||||
if (ds->ossl_lock) {
|
||||
pj_lock_destroy(ds->ossl_lock);
|
||||
ds->ossl_lock = NULL;
|
||||
}
|
||||
|
||||
pj_pool_safe_release(&ds->pool);
|
||||
|
||||
return PJ_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -2025,11 +1918,9 @@ PJ_DEF(pj_status_t) pjmedia_transport_srtp_dtls_start_nego(
|
|||
#if DTLS_DEBUG
|
||||
{
|
||||
char addr[PJ_INET6_ADDRSTRLEN];
|
||||
char addr2[PJ_INET6_ADDRSTRLEN];
|
||||
PJ_LOG(2,(ds->base.name, "Attached transport, remote addr=%s "
|
||||
"remote rtcp=%s",
|
||||
pj_sockaddr_print(&ap.rem_addr, addr, sizeof(addr), 3),
|
||||
pj_sockaddr_print(&ap.rem_addr, addr2, sizeof(addr2), 3)));
|
||||
PJ_LOG(2,(ds->base.name, "Attached transport, remote addr=%s:%d",
|
||||
pj_sockaddr_print(&ap.rem_addr, addr, sizeof(addr), 2),
|
||||
pj_sockaddr_get_port(&ap.rem_addr)));
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -34,9 +34,6 @@
|
|||
# endif
|
||||
#endif
|
||||
|
||||
#if (PJ_SSL_SOCK_IMP == PJ_SSL_SOCK_IMP_APPLE)
|
||||
#include <Security/SecRandom.h>
|
||||
#endif
|
||||
|
||||
#include <pj/rand.h>
|
||||
|
||||
|
@ -137,16 +134,6 @@ static pj_status_t generate_crypto_attr_value(pj_pool_t *pool,
|
|||
"(native err=%d)", err));
|
||||
return PJMEDIA_ERRNO_FROM_LIBSRTP(1);
|
||||
}
|
||||
#elif defined(PJ_HAS_SSL_SOCK) && (PJ_HAS_SSL_SOCK != 0) && \
|
||||
(PJ_SSL_SOCK_IMP == PJ_SSL_SOCK_IMP_APPLE)
|
||||
int err = SecRandomCopyBytes(kSecRandomDefault,
|
||||
crypto_suites[cs_idx].cipher_key_len,
|
||||
&key);
|
||||
if (err != errSecSuccess) {
|
||||
PJ_LOG(4,(THIS_FILE, "Failed generating random key "
|
||||
"(native err=%d)", err));
|
||||
return PJMEDIA_ERRNO_FROM_LIBSRTP(1);
|
||||
}
|
||||
#else
|
||||
PJ_LOG(3,(THIS_FILE, "Warning: simple random generator is used "
|
||||
"for generating SRTP key"));
|
||||
|
|
|
@ -298,7 +298,6 @@ PJ_DEF(pj_status_t) pjmedia_transport_udp_attach( pjmedia_endpt *endpt,
|
|||
pj_pool_t *pool;
|
||||
pj_ioqueue_t *ioqueue;
|
||||
pj_ioqueue_callback rtp_cb, rtcp_cb;
|
||||
pj_grp_lock_t *grp_lock;
|
||||
pj_status_t status;
|
||||
|
||||
|
||||
|
@ -349,29 +348,18 @@ PJ_DEF(pj_status_t) pjmedia_transport_udp_attach( pjmedia_endpt *endpt,
|
|||
pj_sockaddr_get_addr_len(&tp->rtp_addr_name));
|
||||
}
|
||||
|
||||
/* Create group lock */
|
||||
status = pj_grp_lock_create(pool, NULL, &grp_lock);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_error;
|
||||
|
||||
pj_grp_lock_add_ref(grp_lock);
|
||||
tp->base.grp_lock = grp_lock;
|
||||
|
||||
/* Setup RTP socket with the ioqueue */
|
||||
pj_bzero(&rtp_cb, sizeof(rtp_cb));
|
||||
rtp_cb.on_read_complete = &on_rx_rtp;
|
||||
rtp_cb.on_write_complete = &on_rtp_data_sent;
|
||||
|
||||
status = pj_ioqueue_register_sock2(pool, ioqueue, tp->rtp_sock, grp_lock,
|
||||
tp, &rtp_cb, &tp->rtp_key);
|
||||
status = pj_ioqueue_register_sock(pool, ioqueue, tp->rtp_sock, tp,
|
||||
&rtp_cb, &tp->rtp_key);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_error;
|
||||
|
||||
/* Disallow concurrency so that detach() and destroy() are
|
||||
* synchronized with the callback.
|
||||
*
|
||||
* Note that we still need this even after group lock is added to
|
||||
* maintain the above behavior.
|
||||
*/
|
||||
status = pj_ioqueue_set_concurrency(tp->rtp_key, PJ_FALSE);
|
||||
if (status != PJ_SUCCESS)
|
||||
|
@ -400,8 +388,8 @@ PJ_DEF(pj_status_t) pjmedia_transport_udp_attach( pjmedia_endpt *endpt,
|
|||
pj_bzero(&rtcp_cb, sizeof(rtcp_cb));
|
||||
rtcp_cb.on_read_complete = &on_rx_rtcp;
|
||||
|
||||
status = pj_ioqueue_register_sock2(pool, ioqueue, tp->rtcp_sock, grp_lock,
|
||||
tp, &rtcp_cb, &tp->rtcp_key);
|
||||
status = pj_ioqueue_register_sock(pool, ioqueue, tp->rtcp_sock, tp,
|
||||
&rtcp_cb, &tp->rtcp_key);
|
||||
if (status != PJ_SUCCESS)
|
||||
goto on_error;
|
||||
|
||||
|
@ -448,13 +436,12 @@ static pj_status_t transport_destroy(pjmedia_transport *tp)
|
|||
|
||||
/* Must not close while application is using this */
|
||||
//PJ_ASSERT_RETURN(!udp->attached, PJ_EINVALIDOP);
|
||||
|
||||
/* The following calls to pj_ioqueue_unregister() will block the execution
|
||||
* if callback is still being called because allow_concurrent is false.
|
||||
* So it is safe to release the pool immediately after.
|
||||
*/
|
||||
|
||||
|
||||
if (udp->rtp_key) {
|
||||
/* This will block the execution if callback is still
|
||||
* being called.
|
||||
*/
|
||||
pj_ioqueue_unregister(udp->rtp_key);
|
||||
udp->rtp_key = NULL;
|
||||
udp->rtp_sock = PJ_INVALID_SOCKET;
|
||||
|
@ -472,8 +459,6 @@ static pj_status_t transport_destroy(pjmedia_transport *tp)
|
|||
udp->rtcp_sock = PJ_INVALID_SOCKET;
|
||||
}
|
||||
|
||||
pj_grp_lock_dec_ref(tp->grp_lock);
|
||||
|
||||
PJ_LOG(4,(udp->base.name, "UDP media transport destroyed"));
|
||||
pj_pool_release(udp->pool);
|
||||
|
||||
|
|
|
@ -299,8 +299,7 @@ PJ_DEF(pj_status_t) pjmedia_vid_codec_mgr_unregister_factory(
|
|||
pj_bool_t found;
|
||||
pj_str_t codec_str = pj_str(mgr->codec_desc[i].id);
|
||||
|
||||
codec_idx = (pj_int8_t)pjmedia_codec_mgr_find_codec(
|
||||
mgr->dyn_codecs,
|
||||
codec_idx = pjmedia_codec_mgr_find_codec(mgr->dyn_codecs,
|
||||
mgr->dyn_codecs_cnt,
|
||||
&codec_str,
|
||||
&found);
|
||||
|
@ -824,8 +823,8 @@ pj_status_t pjmedia_vid_codec_mgr_get_dyn_codecs(pjmedia_vid_codec_mgr* mgr,
|
|||
|
||||
pj_mutex_lock(mgr->mutex);
|
||||
|
||||
if (mgr->dyn_codecs_cnt < (unsigned)*count)
|
||||
*count = (pj_int8_t)mgr->dyn_codecs_cnt;
|
||||
if (mgr->dyn_codecs_cnt < *count)
|
||||
*count = mgr->dyn_codecs_cnt;
|
||||
|
||||
pj_memcpy(dyn_codecs, mgr->dyn_codecs, *count * sizeof(pj_str_t));
|
||||
|
||||
|
|
|
@ -1398,8 +1398,7 @@ static pj_status_t vid_pasv_port_put_frame(struct pjmedia_port *this_port,
|
|||
if (frame->size != vp->src_size) {
|
||||
if (frame->size > 0) {
|
||||
PJ_LOG(4,(THIS_FILE, "Unexpected frame size %lu, expected %lu",
|
||||
(unsigned long)frame->size,
|
||||
(unsigned long)vp->src_size));
|
||||
frame->size, vp->src_size));
|
||||
}
|
||||
|
||||
pj_memcpy(&frame_, frame, sizeof(pjmedia_frame));
|
||||
|
|
|
@ -584,12 +584,7 @@ static pj_status_t send_rtcp(pjmedia_vid_stream *stream,
|
|||
int len, max_len;
|
||||
pj_status_t status;
|
||||
|
||||
|
||||
/* To avoid deadlock with media transport, we use the transport's
|
||||
* group lock.
|
||||
*/
|
||||
if (stream->transport->grp_lock)
|
||||
pj_grp_lock_acquire( stream->transport->grp_lock );
|
||||
pj_grp_lock_acquire( stream->grp_lock );
|
||||
|
||||
/* Build RTCP RR/SR packet */
|
||||
pjmedia_rtcp_build_rtcp(&stream->rtcp, &sr_rr_pkt, &len);
|
||||
|
@ -672,8 +667,7 @@ static pj_status_t send_rtcp(pjmedia_vid_stream *stream,
|
|||
}
|
||||
}
|
||||
|
||||
if (stream->transport->grp_lock)
|
||||
pj_grp_lock_release( stream->transport->grp_lock );
|
||||
pj_grp_lock_release( stream->grp_lock );
|
||||
|
||||
return status;
|
||||
}
|
||||
|
@ -2197,7 +2191,7 @@ PJ_DEF(pj_status_t) pjmedia_vid_stream_destroy( pjmedia_vid_stream *stream )
|
|||
pjmedia_event_unsubscribe(NULL, &stream_event_cb, stream, &stream->rtcp);
|
||||
|
||||
/* Send RTCP BYE (also SDES) */
|
||||
if (stream->transport && !stream->rtcp_sdes_bye_disabled) {
|
||||
if (stream->transport && stream->grp_lock && !stream->rtcp_sdes_bye_disabled) {
|
||||
send_rtcp(stream, PJ_TRUE, PJ_TRUE, PJ_FALSE, PJ_FALSE);
|
||||
}
|
||||
|
||||
|
|
|
@ -220,7 +220,7 @@ PJ_DEF(pj_status_t) pjmedia_wav_writer_port_create( pj_pool_t *pool,
|
|||
(int)fport->base.info.name.slen,
|
||||
fport->base.info.name.ptr,
|
||||
PJMEDIA_PIA_SRATE(&fport->base.info),
|
||||
(unsigned long)(fport->bufsize / 1000)));
|
||||
fport->bufsize / 1000));
|
||||
|
||||
|
||||
return PJ_SUCCESS;
|
||||
|
|
|
@ -178,8 +178,7 @@ static int codec_test_encode(pjmedia_codec_mgr *mgr,
|
|||
break;
|
||||
}
|
||||
|
||||
PJ_LOG(1,(THIS_FILE," failed: mismatch at pos %lu",
|
||||
(unsigned long)(pos+i)));
|
||||
PJ_LOG(1,(THIS_FILE," failed: mismatch at pos %ld", pos+i));
|
||||
rc = -200;
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -1717,6 +1717,9 @@ static pjmedia_port* create_stream( pj_pool_t *pool,
|
|||
unsigned flags,
|
||||
struct test_entry *te)
|
||||
{
|
||||
PJ_UNUSED_ARG(srtp_enabled);
|
||||
PJ_UNUSED_ARG(srtp_80);
|
||||
PJ_UNUSED_ARG(srtp_auth);
|
||||
struct stream_port *sp;
|
||||
pj_str_t codec_id;
|
||||
pjmedia_port *port;
|
||||
|
@ -1726,12 +1729,6 @@ static pjmedia_port* create_stream( pj_pool_t *pool,
|
|||
pjmedia_stream_info si;
|
||||
pj_status_t status;
|
||||
|
||||
#if !PJMEDIA_HAS_SRTP
|
||||
PJ_UNUSED_ARG(srtp_enabled);
|
||||
PJ_UNUSED_ARG(srtp_80);
|
||||
PJ_UNUSED_ARG(srtp_auth);
|
||||
#endif
|
||||
|
||||
PJ_UNUSED_ARG(flags);
|
||||
|
||||
codec_id = pj_str((char*)codec);
|
||||
|
|
|
@ -240,7 +240,7 @@ static int loopback_test(void)
|
|||
if ((cdi.dir & PJMEDIA_DIR_CAPTURE) == 0)
|
||||
continue;
|
||||
|
||||
for (j=0; j<count; ++j) {
|
||||
for (j=i+1; j<count; ++j) {
|
||||
pjmedia_vid_dev_info rdi;
|
||||
unsigned k;
|
||||
|
||||
|
|
|
@ -94,7 +94,7 @@ provides the best example on how to do this.
|
|||
|
||||
\section ice_samples_sec Samples
|
||||
|
||||
The ICE demo sample \src{pjsip-apps/src/samples/icedemo.c} demonstrates how to use
|
||||
The \ref ice_demo_sample sample demonstrates how to use
|
||||
\ref PJNATH_ICE_STREAM_TRANSPORT <b>without</b> using signaling
|
||||
protocol such as <b>SIP</b>. It provides interactive user interface
|
||||
to create and manage the ICE sessions as well as to exchange SDP
|
||||
|
|
|
@ -25,24 +25,26 @@ below were taken on a Windows machine, but the library is very portable and
|
|||
it is known to run on platforms such as Linux, MacOS X, Windows Mobile,
|
||||
Symbian, and so on.
|
||||
|
||||
- ICE demo sample: \src{pjsip-apps/src/samples/icedemo.c} <br />\n
|
||||
- @ref ice_demo_sample \n
|
||||
This sample demonstrates how to use \ref PJNATH_ICE_STREAM_TRANSPORT
|
||||
<b>without</b> using signaling protocol such as <b>SIP</b>. It provides
|
||||
interactive user interface to create and manage the ICE sessions as well
|
||||
as to exchange SDP with another ICE demo instance.\n\n
|
||||
\img{pjnath/docs/ice_demo.jpg,ice_demo on WinXP}
|
||||
as to exchange SDP with another ice_demo instance.\n\n
|
||||
\image html ice_demo.jpg "ice_demo on WinXP"
|
||||
|
||||
- TURN client sample: \srcdir{pjnath/src/pjturn-client/} <br />\n
|
||||
- @ref turn_client_sample \n
|
||||
This sample demonstrates how to use \ref PJNATH_TURN_SOCK
|
||||
and also \ref PJNATH_STUN_SOCK. It provides interactive
|
||||
user interface to manage allocation, permissions, and
|
||||
channel bindings.\n\n
|
||||
\img{pjnath/docs/pjturn_client.jpg,pjturn_client on WinXP}
|
||||
\image html pjturn_client.jpg "pjturn_client on WinXP"
|
||||
|
||||
- TURN server sample: \srcdir{pjnath/src/pjturn-srv/} <br />\n
|
||||
- TURN server sample \n
|
||||
This is a simple sample TURN server application, which
|
||||
we mainly use for testing (as back then there is no TURN
|
||||
server available).\n
|
||||
The source code for this application are in <tt><b>pjnath/src/pjturn-srv</b></tt>
|
||||
directory.
|
||||
|
||||
*/
|
||||
|
||||
|
|
|
@ -259,10 +259,6 @@ GENERATE_DEPRECATEDLIST= YES
|
|||
# You can put \n's in the value part of an alias to insert newlines.
|
||||
|
||||
ALIASES =
|
||||
ALIASES += src{1}="\verbatim embed:rst:inline :source:`\1` \endverbatim"
|
||||
ALIASES += srcdir{1}="\verbatim embed:rst:inline :sourcedir:`\1` \endverbatim"
|
||||
ALIASES += img{1}="<img src=\"https://raw.githubusercontent.com/pjsip/pjproject/master/\1\" />"
|
||||
ALIASES += img{2}="<img src=\"https://raw.githubusercontent.com/pjsip/pjproject/master/\1\" alt=\"\2\" />"
|
||||
|
||||
# The ENABLED_SECTIONS tag can be used to enable conditional
|
||||
# documentation sections, marked by \if sectionname ... \endif.
|
||||
|
|
|
@ -223,14 +223,6 @@ typedef struct pj_turn_sock_tls_cfg
|
|||
*/
|
||||
pj_str_t password;
|
||||
|
||||
/**
|
||||
* Lookup certificate from OS certificate store with specified criteria.
|
||||
*
|
||||
* Currently only used by TLS backend Windows Schannel, please check
|
||||
* pj_ssl_cert_load_from_store() for more info.
|
||||
*/
|
||||
pj_ssl_cert_lookup_criteria cert_lookup;
|
||||
|
||||
/**
|
||||
* The ssl socket parameter.
|
||||
* These fields are used by TURN TLS:
|
||||
|
@ -363,8 +355,8 @@ typedef struct pj_turn_sock_cfg
|
|||
unsigned so_sndbuf_size;
|
||||
|
||||
/**
|
||||
* This specifies TLS settings for TLS transport. It's only applicable when
|
||||
* TLS is used to connect to the TURN server.
|
||||
* This specifies TLS settings for TLS transport. It is only be used
|
||||
* when this TLS is used to connect to the TURN server.
|
||||
*/
|
||||
pj_turn_sock_tls_cfg tls_cfg;
|
||||
|
||||
|
|
|
@ -679,7 +679,7 @@ static int perform_test2(const char *title,
|
|||
if (sess->caller.result.init_status != PJ_SUCCESS ||
|
||||
sess->callee.result.init_status != PJ_SUCCESS)
|
||||
{
|
||||
// rc = 0;
|
||||
rc = 0;
|
||||
goto on_return;
|
||||
}
|
||||
/* Init ICE on caller */
|
||||
|
|
|
@ -1047,8 +1047,8 @@ static pj_bool_t alloc_on_data_recvfrom(pj_activesock_t *asock,
|
|||
}
|
||||
}
|
||||
if (i==alloc->perm_cnt) {
|
||||
PJ_LOG(5,("", "Client %s received %lu bytes unauthorized data from peer %s",
|
||||
client_info, (unsigned long)size, peer_info));
|
||||
PJ_LOG(5,("", "Client %s received %ld bytes unauthorized data from peer %s",
|
||||
client_info, size, peer_info));
|
||||
if (alloc->perm_cnt == 0)
|
||||
PJ_LOG(5,("", "Client %s has no permission", client_info));
|
||||
return PJ_TRUE;
|
||||
|
@ -1073,8 +1073,8 @@ static pj_bool_t alloc_on_data_recvfrom(pj_activesock_t *asock,
|
|||
|
||||
/* Send */
|
||||
sent = size;
|
||||
PJ_LOG(5,("", "Forwarding %lu bytes data from peer %s to client %s",
|
||||
(unsigned long)sent, peer_info, client_info));
|
||||
PJ_LOG(5,("", "Forwarding %ld bytes data from peer %s to client %s",
|
||||
sent, peer_info, client_info));
|
||||
|
||||
pj_activesock_sendto(alloc->test_srv->turn_sock, &alloc->send_key, buffer,
|
||||
&sent, 0, &alloc->client_addr,
|
||||
|
|
|
@ -1677,8 +1677,8 @@ static pj_bool_t on_check_complete(pj_ice_sess *ice,
|
|||
}
|
||||
}
|
||||
|
||||
LOG5((ice->obj_name, "Check %d is successful%s",
|
||||
(int)GET_CHECK_ID(&ice->clist, check),
|
||||
LOG5((ice->obj_name, "Check %ld is successful%s",
|
||||
GET_CHECK_ID(&ice->clist, check),
|
||||
(check->nominated ? " and nominated" : "")));
|
||||
|
||||
/* On the first valid pair, we call the callback, if present */
|
||||
|
|
|
@ -414,8 +414,8 @@ static void end_session(nat_detect_session *sess,
|
|||
delay.sec = 0;
|
||||
delay.msec = 0;
|
||||
|
||||
pj_timer_heap_schedule_w_grp_lock(sess->timer_heap, &sess->timer, &delay,
|
||||
TIMER_DESTROY, sess->grp_lock);
|
||||
sess->timer.id = TIMER_DESTROY;
|
||||
pj_timer_heap_schedule(sess->timer_heap, &sess->timer, &delay);
|
||||
}
|
||||
|
||||
|
||||
|
@ -934,8 +934,7 @@ static void on_sess_timer(pj_timer_heap_t *th,
|
|||
|
||||
if (next_timer) {
|
||||
pj_time_val delay = {0, TEST_INTERVAL};
|
||||
pj_timer_heap_schedule_w_grp_lock(th, te, &delay,
|
||||
TIMER_TEST, sess->grp_lock);
|
||||
pj_timer_heap_schedule(th, te, &delay);
|
||||
} else {
|
||||
te->id = 0;
|
||||
}
|
||||
|
|
|
@ -2547,8 +2547,8 @@ PJ_DEF(pj_status_t) pj_stun_msg_decode(pj_pool_t *pool,
|
|||
if (pdu_len > 0) {
|
||||
/* Stray trailing bytes */
|
||||
PJ_LOG(4,(THIS_FILE,
|
||||
"Error decoding STUN message: unparsed trailing %lu bytes",
|
||||
(unsigned long)pdu_len));
|
||||
"Error decoding STUN message: unparsed trailing %ld bytes",
|
||||
pdu_len));
|
||||
return PJNATH_EINSTUNMSGLEN;
|
||||
}
|
||||
|
||||
|
|
|
@ -664,9 +664,7 @@ PJ_DEF(pj_status_t) pj_turn_session_set_server( pj_turn_session *sess,
|
|||
unsigned i, cnt;
|
||||
|
||||
/* Default port must be specified */
|
||||
PJ_ASSERT_ON_FAIL(default_port>0 && default_port<65536,
|
||||
{status=PJ_EINVAL; goto on_return;});
|
||||
|
||||
PJ_ASSERT_RETURN(default_port>0 && default_port<65536, PJ_EINVAL);
|
||||
sess->default_port = (pj_uint16_t)default_port;
|
||||
|
||||
cnt = PJ_TURN_MAX_DNS_SRV_CNT;
|
||||
|
@ -1201,7 +1199,7 @@ PJ_DEF(pj_status_t) pj_turn_session_connection_bind(
|
|||
PJ_STUN_ATTR_CONNECTION_ID,
|
||||
conn_id);
|
||||
|
||||
conn_bind = PJ_POOL_ZALLOC_T(tdata->pool, struct conn_bind_t);
|
||||
conn_bind = PJ_POOL_ZALLOC_T(pool, struct conn_bind_t);
|
||||
conn_bind->id = conn_id;
|
||||
pj_sockaddr_cp(&conn_bind->peer_addr, peer_addr);
|
||||
conn_bind->peer_addr_len = addr_len;
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue