mirror of
https://github.com/morgan9e/UxPlay
synced 2026-04-14 00:04:13 +09:00
fixed M1 video problem
This commit is contained in:
12
README.html
12
README.html
@@ -4,7 +4,7 @@
|
||||
<ul>
|
||||
<li>GPLv3, open source.</li>
|
||||
<li>Support for both AirPlay Mirror and AirPlay Audio-only (Apple Lossless ALAC) protocols f from current iOS/iPadOS 15.2 client devices.</li>
|
||||
<li>macOS computers (2011 or later) can act either as AirPlay clients, or as the server running UxPlay (tested on macOS 10.15 Catalina). Using AirPlay, UxPlay can emulate a second display for Intel macOS clients (a video format issue on “Apple Silicon” (M1) macOS clients is not yet resolved, see <a href="https://github.com/FDH2/UxPlay/issues/73">Issues</a>) .</li>
|
||||
<li>macOS computers (2011 or later) can act either as AirPlay clients, or as the server running UxPlay (tested on macOS 10.15 Catalina and 12.3 Monterey). Using AirPlay, UxPlay can emulate a second display for macOS clients. Both Intel and “Apple Silcon” M1 Macs are now fully supported in both roles.</li>
|
||||
<li>Support for older 32-bit iOS clients (such as iPad 2nd gen, iPhone 4S, when upgraded to iOS 9.3.5 or later), and a Windows AirPlay-client emulator, AirMyPC.</li>
|
||||
<li>Uses GStreamer, with options to select different output “videosinks” and “audiosinks”.</li>
|
||||
<li>Support for server behind a firewall.</li>
|
||||
@@ -53,15 +53,15 @@
|
||||
<li><p><strong>FreeBSD:</strong> (sudo pkg install) libplist gstreamer1, gstreamer1-libav, gstreamer1-plugins, gstreamer1-plugins-* (* = core, good, bad, x, gtk, gl, vulkan, pulse …), (+ gstreamer1-vaapi for Intel graphics). Either avahi-libdns or mDNSResponder must also be installed to provide the dns_sd library. OpenSSL is already installed as a System Library. “ZOOMFIX” is untested; don’t try to use it on FreeBSD unless you need it.</p></li>
|
||||
</ul>
|
||||
<h3 id="building-openssl-1.1.1-from-source.">Building OpenSSL >= 1.1.1 from source.</h3>
|
||||
<p>If you need to do this, note that you may be able to use a newer version (OpenSSL-3.0.1 is known to work). You will need the standard development toolset (autoconf, automake, libtool, etc.). Download the source code from <a href="https://www.openssl.org/source/">https://www.openssl.org/source/</a>. Install the downloaded openssl by opening a terminal in your Downloads directory, and unpacking the source distribution: (“tar -xvzf openssl-3.0.1.tar.gz ; cd openssl-3.0.1”). Then build/install with “./config ; make ; sudo make install_dev”. This will typically install the needed library <code>libcrypto.*</code>, either in /usr/local/lib or /usr/local/lib64. <em>(Ignore the following for builds on MacOS:)</em> Assuming the library was placed in /usr/local/lib64, you must “export OPENSSL_ROOT_DIR=/usr/local/lib64” before running cmake. On some systems like Debian or Ubuntu, you may also need to add a missing entry <code>/usr/local/lib64</code> in /etc/ld.so.conf (or place a file containing “/usr/local/lib64/libcrypto.so” in /etc/ld.so.conf.d) and then run “sudo ldconfig”.</p>
|
||||
<p>If you need to do this, note that you may be able to use a newer version (OpenSSL-3.0.1 is known to work). You will need the standard development toolset (autoconf, automake, libtool). Download the source code from <a href="https://www.openssl.org/source/">https://www.openssl.org/source/</a>. Install the downloaded openssl by opening a terminal in your Downloads directory, and unpacking the source distribution: (“tar -xvzf openssl-3.0.1.tar.gz ; cd openssl-3.0.1”). Then build/install with “./config ; make ; sudo make install_dev”. This will typically install the needed library <code>libcrypto.*</code>, either in /usr/local/lib or /usr/local/lib64. <em>(Ignore the following for builds on MacOS:)</em> Assuming the library was placed in /usr/local/lib64, you must “export OPENSSL_ROOT_DIR=/usr/local/lib64” before running cmake. On some systems like Debian or Ubuntu, you may also need to add a missing entry <code>/usr/local/lib64</code> in /etc/ld.so.conf (or place a file containing “/usr/local/lib64/libcrypto.so” in /etc/ld.so.conf.d) and then run “sudo ldconfig”.</p>
|
||||
<h3 id="bulding-libplist-2.0.0-from-source.">Bulding libplist >= 2.0.0 from source.</h3>
|
||||
<p><em>(Note: on Debian 9 “Stretch” or Ubuntu 16.04 LTS editions, you can avoid this step by installing libplist-dev and libplist3 from Debian 10 or Ubuntu 18.04.)</em> As well as the usual build tools, you may need to also install some libpython*-dev package. Download the latest source from <a href="https://github.com/libimobiledevice/libplist">https://github.com/libimobiledevice/libplist</a>: get <a href="https://github.com/libimobiledevice/libplist/archive/refs/heads/master.zip">libplist-master.zip</a>, then (“unzip libplist-master.zip ; cd libplist-master”), build/install (“./autogen.sh ; make ; sudo make install”). This will probably install libplist-2.0.* in /usr/local/lib. <em>(Ignore the following for builds on MacOS:)</em> On some systems like Debian or Ubuntu, you may also need to add a missing entry <code>/usr/local/lib</code> in /etc/ld.so.conf (or place a file containing “/usr/local/lib/libplist-2.0.so” in /etc/ld.so.conf.d) and then run “sudo ldconfig”.</p>
|
||||
<h2 id="building-uxplay-on-macos-only-tested-on-intel-x86_64-macs">Building UxPlay on macOS: <strong>(Only tested on Intel X86_64 Macs)</strong></h2>
|
||||
<p><em>(Note: on Debian 9 “Stretch” or Ubuntu 16.04 LTS editions, you can avoid this step by installing libplist-dev and libplist3 from Debian 10 or Ubuntu 18.04.)</em> As well as the usual build tools (autoconf, automake, libtool), you may need to also install some libpython*-dev package. Download the latest source from <a href="https://github.com/libimobiledevice/libplist">https://github.com/libimobiledevice/libplist</a>: get <a href="https://github.com/libimobiledevice/libplist/archive/refs/heads/master.zip">libplist-master.zip</a>, then (“unzip libplist-master.zip ; cd libplist-master”), build/install (“./autogen.sh ; make ; sudo make install”). This will probably install libplist-2.0.* in /usr/local/lib. <em>(Ignore the following for builds on MacOS:)</em> On some systems like Debian or Ubuntu, you may also need to add a missing entry <code>/usr/local/lib</code> in /etc/ld.so.conf (or place a file containing “/usr/local/lib/libplist-2.0.so” in /etc/ld.so.conf.d) and then run “sudo ldconfig”.</p>
|
||||
<h2 id="building-uxplay-on-macos-now-tested-on-both-intel-x86_64-and-apple-silicon-m1-macs">Building UxPlay on macOS: <strong>(Now tested on both Intel X86_64 and “Apple Silicon” M1 Macs)</strong></h2>
|
||||
<p><em>Note: A native AirPlay Server feature is included in macOS 12 Monterey, but is restricted to recent hardware. UxPlay can run on older macOS systems that will not be able to run Monterey, or can run Monterey but not AirPlay.</em></p>
|
||||
<p>These instructions for macOS asssume that the Xcode command-line developer tools are installed (if Xcode is installed, open the Terminal, type “sudo xcode-select –install” and accept the conditions).</p>
|
||||
<p>It is also assumed that CMake >= 3.13 is installed: this can be done with package managers <a href="http://www.macports.org">MacPorts</a>, <a href="http://finkproject.org">Fink</a> or <a href="http://brew.sh">Homebrew</a>, or by a download from <a href="https://cmake.org/download/">https://cmake.org/download/</a>.</p>
|
||||
<p>First get the latest macOS release of GStreamer-1.0 from <a href="https://gstreamer.freedesktop.org/download/">https://gstreamer.freedesktop.org/download/</a>. Install both the macOS runtime and development installer packages. Assuming that the latest release is 1.20.1. install <code>gstreamer-1.0-1.20.1-universal.pkg</code> and <code>gstreamer-1.0-devel-1.20.1-universal.pkg</code>. (If you have problems with the “universal” packages, you can also use <code>gstreamer-1.0-1.18.6-x86_64.pkg</code> and <code>gstreamer-1.0-devel-1.18.6-x86_64.pkg</code>.) Click on them to install (they install to /Library/FrameWorks/GStreamer.framework). It is recommended you use GStreamer.framework rather than install Gstreamer with Homebrew or MacPorts (see later).</p>
|
||||
<p>Next install OpenSSL and libplist: these can be built from source (see above); only the static forms of the two libraries will used for the macOS build, so you can uninstall them (“sudo make uninstall”) after you have built UxPlay. It may be easier to get them using MacPorts “sudo port install openssl libplist-devel” or Homebrew “brew install openssl libplist” (but not Fink). if you don’t have MacPorts or Homebrew installed, you can just install one of them before building uxplay, and uninstall afterwards if it is not wanted.</p>
|
||||
<p>First get the latest macOS release of GStreamer-1.0 from <a href="https://gstreamer.freedesktop.org/download/">https://gstreamer.freedesktop.org/download/</a>. Install both the macOS runtime and development installer packages. Assuming that the latest release is 1.20.1. install <code>gstreamer-1.0-1.20.1-universal.pkg</code> and <code>gstreamer-1.0-devel-1.20.1-universal.pkg</code>. (If you have an Intel-architecture Mac, and have problems with the “universal” packages, you can also use <code>gstreamer-1.0-1.18.6-x86_64.pkg</code> and <code>gstreamer-1.0-devel-1.18.6-x86_64.pkg</code>.) Click on them to install (they install to /Library/FrameWorks/GStreamer.framework). It is recommended you use GStreamer.framework rather than install Gstreamer with Homebrew or MacPorts (see later).</p>
|
||||
<p>Next install OpenSSL and libplist: these can be built from source (see above), in which case you may need to install the standard development tools auutoconf, automake, libtool, which can be done with MacPorts, HomeBrew, or Fink. Only the static forms of the two libraries will used for the macOS build, so you can uninstall them (“sudo make uninstall”) after you have built UxPlay. It may be easier to get them using MacPorts “sudo port install openssl libplist-devel” or Homebrew “brew install openssl libplist” (but not Fink). if you don’t have MacPorts or Homebrew installed, you can just install one of them before building uxplay, and uninstall afterwards if it is not wanted.</p>
|
||||
<p>Finally, build and install uxplay (without ZOOMFIX): open a terminal and change into the UxPlay source directory (“UxPlay-master” for zipfile downloads, “UxPlay” for “git clone” downloads) and build/install with “cmake . ; make ; sudo make install” (same as for Linux).</p>
|
||||
<ul>
|
||||
<li><p>On macOS with this installation of GStreamer, the only videosinks available seem to be glimagesink (default choice made by autovideosink) and osxvideosink. (It seems that vaapisink is not supported on macOS). The window title does not show the Airplay server name, but the window is visible to screen-sharing apps (e.g., Zoom). The only available audiosink seems to be osxaudiosink.</p></li>
|
||||
|
||||
30
README.md
30
README.md
@@ -7,12 +7,12 @@ Highlights:
|
||||
|
||||
* GPLv3, open source.
|
||||
* Support for both AirPlay Mirror and AirPlay Audio-only (Apple Lossless ALAC) protocols f
|
||||
from current iOS/iPadOS 15.2 client devices.
|
||||
from current iOS/iPadOS 15.2 client devices.
|
||||
* macOS computers (2011 or later) can act either as AirPlay clients, or as the server running UxPlay (tested
|
||||
on macOS 10.15 Catalina). Using AirPlay, UxPlay can emulate a second display for Intel macOS clients (a video format
|
||||
issue on "Apple Silicon" (M1) macOS clients is not yet resolved, see [Issues](https://github.com/FDH2/UxPlay/issues/73)) .
|
||||
on macOS 10.15 Catalina and 12.3 Monterey). Using AirPlay, UxPlay can emulate a second display for macOS clients.
|
||||
Both Intel and "Apple Silcon" M1 Macs are now fully supported in both roles.
|
||||
* Support for older 32-bit iOS clients (such as iPad 2nd gen, iPhone 4S, when upgraded to iOS 9.3.5 or later),
|
||||
and a Windows AirPlay-client emulator, AirMyPC.
|
||||
and a Windows AirPlay-client emulator, AirMyPC.
|
||||
* Uses GStreamer, with options to select different output "videosinks" and "audiosinks".
|
||||
* Support for server behind a firewall.
|
||||
* **New**: Support for Raspberry Pi, with hardware video acceleration by Video4Linux2 (replacement for OpenMAX, which
|
||||
@@ -188,7 +188,7 @@ OpenSSL is already installed as a System Library. "ZOOMFIX" is untested; don't
|
||||
### Building OpenSSL >= 1.1.1 from source.
|
||||
|
||||
If you need to do this, note that you may be able to use a newer version (OpenSSL-3.0.1 is known to work).
|
||||
You will need the standard development toolset (autoconf, automake, libtool, etc.).
|
||||
You will need the standard development toolset (autoconf, automake, libtool).
|
||||
Download the source code from
|
||||
[https://www.openssl.org/source/](https://www.openssl.org/source/).
|
||||
Install the downloaded
|
||||
@@ -208,7 +208,8 @@ and then run "sudo ldconfig".
|
||||
|
||||
_(Note: on Debian 9 "Stretch" or Ubuntu 16.04 LTS editions, you can avoid this step by installing libplist-dev
|
||||
and libplist3 from Debian 10 or Ubuntu 18.04.)_
|
||||
As well as the usual build tools, you may need to also install some libpython\*-dev package. Download the latest source
|
||||
As well as the usual build tools (autoconf, automake, libtool), you
|
||||
may need to also install some libpython\*-dev package. Download the latest source
|
||||
from [https://github.com/libimobiledevice/libplist](https://github.com/libimobiledevice/libplist): get
|
||||
[libplist-master.zip](https://github.com/libimobiledevice/libplist/archive/refs/heads/master.zip), then
|
||||
("unzip libplist-master.zip ; cd libplist-master"), build/install
|
||||
@@ -218,7 +219,7 @@ Debian or Ubuntu, you may also need to add a missing entry ```/usr/local/lib```
|
||||
in /etc/ld.so.conf (or place a file containing "/usr/local/lib/libplist-2.0.so" in /etc/ld.so.conf.d)
|
||||
and then run "sudo ldconfig".
|
||||
|
||||
## Building UxPlay on macOS: **(Only tested on Intel X86_64 Macs)**
|
||||
## Building UxPlay on macOS: **(Now tested on both Intel X86_64 and "Apple Silicon" M1 Macs)**
|
||||
|
||||
_Note: A native AirPlay Server feature is included in macOS 12 Monterey, but is restricted to recent hardware.
|
||||
UxPlay can run on older macOS systems that will not be able to run Monterey, or can run Monterey but not AirPlay._
|
||||
@@ -235,14 +236,15 @@ First get the latest macOS release of GStreamer-1.0
|
||||
from [https://gstreamer.freedesktop.org/download/](https://gstreamer.freedesktop.org/download/).
|
||||
Install both the macOS runtime and development installer packages. Assuming that the latest release is 1.20.1.
|
||||
install `gstreamer-1.0-1.20.1-universal.pkg` and ``gstreamer-1.0-devel-1.20.1-universal.pkg``. (If
|
||||
you have problems with the "universal" packages, you can also use `gstreamer-1.0-1.18.6-x86_64.pkg`
|
||||
and ``gstreamer-1.0-devel-1.18.6-x86_64.pkg``.) Click on them to install (they install to
|
||||
/Library/FrameWorks/GStreamer.framework). It is recommended you use GStreamer.framework rather than install
|
||||
Gstreamer with Homebrew or MacPorts (see later).
|
||||
you have an Intel-architecture Mac, and have problems with the "universal" packages, you can also
|
||||
use `gstreamer-1.0-1.18.6-x86_64.pkg` and ``gstreamer-1.0-devel-1.18.6-x86_64.pkg``.) Click on them to
|
||||
install (they install to /Library/FrameWorks/GStreamer.framework).
|
||||
It is recommended you use GStreamer.framework rather than install Gstreamer with Homebrew or MacPorts (see later).
|
||||
|
||||
Next install OpenSSL and libplist: these can be built from source (see above); only the
|
||||
static forms of the two libraries will used for the macOS build, so you can uninstall them ("sudo make uninstall")
|
||||
after you have built UxPlay. It may be easier to get them using
|
||||
Next install OpenSSL and libplist: these can be built from source (see above), in which case you may need to install
|
||||
the standard development tools auutoconf, automake, libtool, which can be done with MacPorts, HomeBrew, or Fink.
|
||||
Only the static forms of the two libraries will used for the macOS build, so you can uninstall them ("sudo
|
||||
make uninstall") after you have built UxPlay. It may be easier to get them using
|
||||
MacPorts "sudo port install openssl libplist-devel" or Homebrew "brew install openssl libplist" (but not Fink).
|
||||
if you don't have MacPorts or Homebrew installed, you can just install
|
||||
one of them before building uxplay, and uninstall afterwards if it is not wanted.
|
||||
|
||||
64
README.txt
64
README.txt
@@ -10,11 +10,10 @@ Highlights:
|
||||
Lossless ALAC) protocols f from current iOS/iPadOS 15.2 client
|
||||
devices.
|
||||
- macOS computers (2011 or later) can act either as AirPlay clients,
|
||||
or as the server running UxPlay (tested on macOS 10.15 Catalina).
|
||||
Using AirPlay, UxPlay can emulate a second display for Intel macOS
|
||||
clients (a video format issue on "Apple Silicon" (M1) macOS clients
|
||||
is not yet resolved, see
|
||||
[Issues](https://github.com/FDH2/UxPlay/issues/73)) .
|
||||
or as the server running UxPlay (tested on macOS 10.15 Catalina and
|
||||
12.3 Monterey). Using AirPlay, UxPlay can emulate a second display
|
||||
for macOS clients. Both Intel and "Apple Silcon" M1 Macs are now
|
||||
fully supported in both roles.
|
||||
- Support for older 32-bit iOS clients (such as iPad 2nd gen, iPhone
|
||||
4S, when upgraded to iOS 9.3.5 or later), and a Windows
|
||||
AirPlay-client emulator, AirMyPC.
|
||||
@@ -262,27 +261,28 @@ gstreamer1.0-gl is installed.
|
||||
|
||||
If you need to do this, note that you may be able to use a newer version
|
||||
(OpenSSL-3.0.1 is known to work). You will need the standard development
|
||||
toolset (autoconf, automake, libtool, etc.). Download the source code
|
||||
from <https://www.openssl.org/source/>. Install the downloaded openssl
|
||||
by opening a terminal in your Downloads directory, and unpacking the
|
||||
source distribution: ("tar -xvzf openssl-3.0.1.tar.gz ; cd
|
||||
openssl-3.0.1"). Then build/install with "./config ; make ; sudo make
|
||||
install\_dev". This will typically install the needed library
|
||||
`libcrypto.*`, either in /usr/local/lib or /usr/local/lib64. *(Ignore
|
||||
the following for builds on MacOS:)* Assuming the library was placed in
|
||||
/usr/local/lib64, you must "export OPENSSL\_ROOT\_DIR=/usr/local/lib64"
|
||||
before running cmake. On some systems like Debian or Ubuntu, you may
|
||||
also need to add a missing entry `/usr/local/lib64` in /etc/ld.so.conf
|
||||
(or place a file containing "/usr/local/lib64/libcrypto.so" in
|
||||
/etc/ld.so.conf.d) and then run "sudo ldconfig".
|
||||
toolset (autoconf, automake, libtool). Download the source code from
|
||||
<https://www.openssl.org/source/>. Install the downloaded openssl by
|
||||
opening a terminal in your Downloads directory, and unpacking the source
|
||||
distribution: ("tar -xvzf openssl-3.0.1.tar.gz ; cd openssl-3.0.1").
|
||||
Then build/install with "./config ; make ; sudo make install\_dev". This
|
||||
will typically install the needed library `libcrypto.*`, either in
|
||||
/usr/local/lib or /usr/local/lib64. *(Ignore the following for builds on
|
||||
MacOS:)* Assuming the library was placed in /usr/local/lib64, you must
|
||||
"export OPENSSL\_ROOT\_DIR=/usr/local/lib64" before running cmake. On
|
||||
some systems like Debian or Ubuntu, you may also need to add a missing
|
||||
entry `/usr/local/lib64` in /etc/ld.so.conf (or place a file containing
|
||||
"/usr/local/lib64/libcrypto.so" in /etc/ld.so.conf.d) and then run "sudo
|
||||
ldconfig".
|
||||
|
||||
### Bulding libplist \>= 2.0.0 from source.
|
||||
|
||||
*(Note: on Debian 9 "Stretch" or Ubuntu 16.04 LTS editions, you can
|
||||
avoid this step by installing libplist-dev and libplist3 from Debian 10
|
||||
or Ubuntu 18.04.)* As well as the usual build tools, you may need to
|
||||
also install some libpython\*-dev package. Download the latest source
|
||||
from <https://github.com/libimobiledevice/libplist>: get
|
||||
or Ubuntu 18.04.)* As well as the usual build tools (autoconf, automake,
|
||||
libtool), you may need to also install some libpython\*-dev package.
|
||||
Download the latest source from
|
||||
<https://github.com/libimobiledevice/libplist>: get
|
||||
[libplist-master.zip](https://github.com/libimobiledevice/libplist/archive/refs/heads/master.zip),
|
||||
then ("unzip libplist-master.zip ; cd libplist-master"), build/install
|
||||
("./autogen.sh ; make ; sudo make install"). This will probably install
|
||||
@@ -292,8 +292,8 @@ a missing entry `/usr/local/lib` in /etc/ld.so.conf (or place a file
|
||||
containing "/usr/local/lib/libplist-2.0.so" in /etc/ld.so.conf.d) and
|
||||
then run "sudo ldconfig".
|
||||
|
||||
Building UxPlay on macOS: **(Only tested on Intel X86\_64 Macs)**
|
||||
-----------------------------------------------------------------
|
||||
Building UxPlay on macOS: **(Now tested on both Intel X86\_64 and "Apple Silicon" M1 Macs)**
|
||||
--------------------------------------------------------------------------------------------
|
||||
|
||||
*Note: A native AirPlay Server feature is included in macOS 12 Monterey,
|
||||
but is restricted to recent hardware. UxPlay can run on older macOS
|
||||
@@ -313,20 +313,22 @@ First get the latest macOS release of GStreamer-1.0 from
|
||||
<https://gstreamer.freedesktop.org/download/>. Install both the macOS
|
||||
runtime and development installer packages. Assuming that the latest
|
||||
release is 1.20.1. install `gstreamer-1.0-1.20.1-universal.pkg` and
|
||||
`gstreamer-1.0-devel-1.20.1-universal.pkg`. (If you have problems with
|
||||
the "universal" packages, you can also use
|
||||
`gstreamer-1.0-1.18.6-x86_64.pkg` and
|
||||
`gstreamer-1.0-devel-1.20.1-universal.pkg`. (If you have an
|
||||
Intel-architecture Mac, and have problems with the "universal" packages,
|
||||
you can also use `gstreamer-1.0-1.18.6-x86_64.pkg` and
|
||||
`gstreamer-1.0-devel-1.18.6-x86_64.pkg`.) Click on them to install (they
|
||||
install to /Library/FrameWorks/GStreamer.framework). It is recommended
|
||||
you use GStreamer.framework rather than install Gstreamer with Homebrew
|
||||
or MacPorts (see later).
|
||||
|
||||
Next install OpenSSL and libplist: these can be built from source (see
|
||||
above); only the static forms of the two libraries will used for the
|
||||
macOS build, so you can uninstall them ("sudo make uninstall") after you
|
||||
have built UxPlay. It may be easier to get them using MacPorts "sudo
|
||||
port install openssl libplist-devel" or Homebrew "brew install openssl
|
||||
libplist" (but not Fink). if you don't have MacPorts or Homebrew
|
||||
above), in which case you may need to install the standard development
|
||||
tools auutoconf, automake, libtool, which can be done with MacPorts,
|
||||
HomeBrew, or Fink. Only the static forms of the two libraries will used
|
||||
for the macOS build, so you can uninstall them ("sudo make uninstall")
|
||||
after you have built UxPlay. It may be easier to get them using MacPorts
|
||||
"sudo port install openssl libplist-devel" or Homebrew "brew install
|
||||
openssl libplist" (but not Fink). if you don't have MacPorts or Homebrew
|
||||
installed, you can just install one of them before building uxplay, and
|
||||
uninstall afterwards if it is not wanted.
|
||||
|
||||
|
||||
@@ -80,10 +80,6 @@ struct raop_rtp_mirror_s {
|
||||
|
||||
unsigned short mirror_data_lport;
|
||||
|
||||
/* SPS and PPS */
|
||||
int sps_pps_len;
|
||||
unsigned char* sps_pps;
|
||||
|
||||
/* switch for displaying client FPS data */
|
||||
uint8_t show_client_FPS_data;
|
||||
};
|
||||
@@ -130,8 +126,6 @@ raop_rtp_mirror_t *raop_rtp_mirror_init(logger_t *logger, raop_callbacks_t *call
|
||||
}
|
||||
raop_rtp_mirror->logger = logger;
|
||||
raop_rtp_mirror->ntp = ntp;
|
||||
raop_rtp_mirror->sps_pps_len = 0;
|
||||
raop_rtp_mirror->sps_pps = NULL;
|
||||
|
||||
memcpy(&raop_rtp_mirror->callbacks, callbacks, sizeof(raop_callbacks_t));
|
||||
raop_rtp_mirror->buffer = mirror_buffer_init(logger, aeskey);
|
||||
@@ -178,7 +172,10 @@ raop_rtp_mirror_thread(void *arg)
|
||||
uint64_t ntp_timestamp_nal = 0;
|
||||
uint64_t ntp_timestamp_raw = 0;
|
||||
bool conn_started = false;
|
||||
|
||||
/* SPS and PPS */
|
||||
int sps_pps_len = 0;
|
||||
unsigned char* sps_pps = NULL;
|
||||
|
||||
#ifdef DUMP_H264
|
||||
// C decrypted
|
||||
FILE* file = fopen("/home/pi/Airplay.h264", "wb");
|
||||
@@ -199,7 +196,7 @@ raop_rtp_mirror_thread(void *arg)
|
||||
}
|
||||
MUTEX_UNLOCK(raop_rtp_mirror->run_mutex);
|
||||
|
||||
/* Set timeout value to 5ms */
|
||||
/* Set timeout valu to 5ms */
|
||||
tv.tv_sec = 0;
|
||||
tv.tv_usec = 5000;
|
||||
|
||||
@@ -335,12 +332,22 @@ raop_rtp_mirror_thread(void *arg)
|
||||
#endif
|
||||
unsigned char* payload_out;
|
||||
unsigned char* payload_decrypted;
|
||||
bool prepend_sps_pps = ((packet[5] != 0x00) && (raop_rtp_mirror->sps_pps_len > 0));
|
||||
bool prepend_sps_pps = ( sps_pps_len > 0);
|
||||
if (prepend_sps_pps) {
|
||||
payload_out = (unsigned char*) malloc(payload_size + raop_rtp_mirror->sps_pps_len);
|
||||
payload_decrypted = payload_out + raop_rtp_mirror->sps_pps_len;
|
||||
memcpy(payload_out, raop_rtp_mirror->sps_pps, raop_rtp_mirror->sps_pps_len);
|
||||
if (packet[5] != 0x10) {
|
||||
logger_log(raop_rtp_mirror->logger, LOGGER_WARNING, "Warning: prepending SPS and PPS NAL units, but packet[5] = 0x%2.2x is not 0x10", packet[5]);
|
||||
}
|
||||
payload_out = (unsigned char*) malloc(payload_size + sps_pps_len);
|
||||
payload_decrypted = payload_out + sps_pps_len;
|
||||
memcpy(payload_out, sps_pps, sps_pps_len);
|
||||
sps_pps_len = 0;
|
||||
free(sps_pps);
|
||||
sps_pps = NULL;
|
||||
} else {
|
||||
if (packet[5] != 0x00) {
|
||||
logger_log(raop_rtp_mirror->logger, LOGGER_WARNING, "Warning: regular NAL unit, but packet[5] = 0x%2.2x is not 0x00", packet[5]);
|
||||
}
|
||||
assert(packet[5] == 0);
|
||||
payload_out = (unsigned char*) malloc(payload_size);
|
||||
payload_decrypted = payload_out;
|
||||
}
|
||||
@@ -352,6 +359,7 @@ raop_rtp_mirror_thread(void *arg)
|
||||
bool valid_data = true;
|
||||
int nalu_size = 0;
|
||||
int nalus_count = 0;
|
||||
int nalu_type;
|
||||
while (nalu_size < payload_size) {
|
||||
int nc_len = byteutils_get_int_be(payload_decrypted, nalu_size);
|
||||
if (nc_len < 0 || nalu_size + 4 > payload_size) {
|
||||
@@ -364,26 +372,24 @@ raop_rtp_mirror_thread(void *arg)
|
||||
payload_decrypted[nalu_size + 3] = 1;
|
||||
nalu_size += 4;
|
||||
nalus_count++;
|
||||
nalu_type = payload[nalu_size] & 0x1f;
|
||||
nalu_size += nc_len;
|
||||
}
|
||||
logger_log(raop_rtp_mirror->logger, LOGGER_DEBUG, " nalu_type = %d, nalu_size = %d, processed bytes %d, payloadsize = %d nalus_count = %d",
|
||||
nalu_type, nc_len, nalu_size, payload_size, nalus_count);
|
||||
}
|
||||
if (nalu_size != payload_size) valid_data = false;
|
||||
|
||||
// int nalu_type = payload[4] & 0x1f;
|
||||
// logger_log(raop_rtp_mirror->logger, LOGGER_DEBUG, "nalutype = %d", nalu_type);
|
||||
// logger_log(raop_rtp_mirror->logger, LOGGER_DEBUG, "nalu_size = %d, payloadsize = %d nalus_count = %d",
|
||||
// nalu_size, payload_size, nalus_count);
|
||||
|
||||
if(!valid_data) {
|
||||
logger_log(raop_rtp_mirror->logger, LOGGER_DEBUG, "nalu marked as invalid");
|
||||
}
|
||||
#ifdef DUMP_H264
|
||||
fwrite(payload_decrypted, payload_size, 1, file);
|
||||
#endif
|
||||
|
||||
h264_decode_struct h264_data;
|
||||
h264_data.pts = ntp_timestamp;
|
||||
h264_data.frame_type = payload_decrypted[4] & 0x1f;
|
||||
if (h264_data.frame_type == 5) {
|
||||
assert(prepend_sps_pps);
|
||||
if (prepend_sps_pps) {
|
||||
h264_data.data = payload_out;
|
||||
h264_data.data_len = payload_size + raop_rtp_mirror->sps_pps_len;
|
||||
h264_data.data_len = payload_size + sps_pps_len;
|
||||
if (ntp_timestamp_raw != ntp_timestamp_nal) {
|
||||
logger_log(raop_rtp_mirror->logger, LOGGER_WARNING, "raop_rtp_mirror: prepended sps_pps timestamp does not match that of video payload");
|
||||
}
|
||||
@@ -392,13 +398,13 @@ raop_rtp_mirror_thread(void *arg)
|
||||
h264_data.data = payload_decrypted;
|
||||
}
|
||||
|
||||
|
||||
if (!valid_data) h264_data.data[0] = 1; /* mark video data as invalid h264 (failed decryption) */
|
||||
raop_rtp_mirror->callbacks.video_process(raop_rtp_mirror->callbacks.cls, raop_rtp_mirror->ntp, &h264_data);
|
||||
free(payload_out);
|
||||
break;
|
||||
case 0x01:
|
||||
// The information in the payload contains an SPS and a PPS NAL
|
||||
// The sps_pps is not encrypted
|
||||
ntp_timestamp_nal = byteutils_get_long(packet, 8);
|
||||
float width_source = byteutils_get_float(packet, 40);
|
||||
float height_source = byteutils_get_float(packet, 44);
|
||||
@@ -410,60 +416,63 @@ raop_rtp_mirror_thread(void *arg)
|
||||
logger_log(raop_rtp_mirror->logger, LOGGER_DEBUG, "raop_rtp_mirror width_source = %f height_source = %f width = %f height = %f",
|
||||
width_source, height_source, width, height);
|
||||
|
||||
// The sps_pps is not encrypted
|
||||
h264codec_t h264;
|
||||
h264.version = payload[0];
|
||||
h264.profile_high = payload[1];
|
||||
h264.compatibility = payload[2];
|
||||
h264.level = payload[3];
|
||||
h264.reserved_6_and_nal = payload[4];
|
||||
h264.reserved_3_and_sps = payload[5];
|
||||
h264.sps_size = (short) (((payload[6] & 255) << 8) + (payload[7] & 255));
|
||||
logger_log(raop_rtp_mirror->logger, LOGGER_DEBUG, "raop_rtp_mirror sps size = %d", h264.sps_size);
|
||||
h264.sequence_parameter_set = malloc(h264.sps_size);
|
||||
memcpy(h264.sequence_parameter_set, payload + 8, h264.sps_size);
|
||||
|
||||
char *str = utils_data_to_string(h264.sequence_parameter_set,h264.sps_size,16);
|
||||
short sps_size = byteutils_get_short_be(payload,6);
|
||||
unsigned char *sequence_parameter_set = payload + 8;
|
||||
short pps_size = byteutils_get_short_be(payload, sps_size + 9);
|
||||
unsigned char *picture_parameter_set = payload + sps_size + 11;
|
||||
int remainder_size = payload_size - sps_size - pps_size - 11;
|
||||
char *str = utils_data_to_string(sequence_parameter_set,sps_size,16);
|
||||
logger_log(raop_rtp_mirror->logger, LOGGER_DEBUG, "raop_rtp_mirror sps size = %d", sps_size);
|
||||
logger_log(raop_rtp_mirror->logger, LOGGER_DEBUG, "raop_rtp_mirror h264 Sequence Parameter Set:\n%s", str);
|
||||
free(str);
|
||||
|
||||
h264.number_of_pps = payload[h264.sps_size + 8];
|
||||
h264.pps_size = (short) (((payload[h264.sps_size + 9] & 2040) + payload[h264.sps_size + 10]) & 255);
|
||||
h264.picture_parameter_set = malloc(h264.pps_size);
|
||||
logger_log(raop_rtp_mirror->logger, LOGGER_DEBUG, "raop_rtp_mirror pps size = %d", h264.pps_size);
|
||||
memcpy(h264.picture_parameter_set, payload + h264.sps_size + 11, h264.pps_size);
|
||||
|
||||
str = utils_data_to_string(h264.picture_parameter_set,h264.pps_size,16);
|
||||
str = utils_data_to_string(picture_parameter_set,pps_size,16);
|
||||
logger_log(raop_rtp_mirror->logger, LOGGER_DEBUG, "raop_rtp_mirror pps size = %d", pps_size);
|
||||
logger_log(raop_rtp_mirror->logger, LOGGER_DEBUG, "raop_rtp_mirror h264 Picture Parameter Set:\n%s", str);
|
||||
free(str);
|
||||
|
||||
if (h264.sps_size + h264.pps_size < 102400) {
|
||||
// Copy the sps and pps into a buffer to hand to the decoder
|
||||
raop_rtp_mirror->sps_pps_len = (h264.sps_size + h264.pps_size) + 8;
|
||||
if (raop_rtp_mirror->sps_pps) {
|
||||
free(raop_rtp_mirror->sps_pps);
|
||||
raop_rtp_mirror->sps_pps = NULL;
|
||||
}
|
||||
raop_rtp_mirror->sps_pps = (unsigned char*) malloc(raop_rtp_mirror->sps_pps_len);
|
||||
assert(raop_rtp_mirror->sps_pps);
|
||||
raop_rtp_mirror->sps_pps[0] = 0;
|
||||
raop_rtp_mirror->sps_pps[1] = 0;
|
||||
raop_rtp_mirror->sps_pps[2] = 0;
|
||||
raop_rtp_mirror->sps_pps[3] = 1;
|
||||
memcpy(raop_rtp_mirror->sps_pps + 4, h264.sequence_parameter_set, h264.sps_size);
|
||||
raop_rtp_mirror->sps_pps[h264.sps_size + 4] = 0;
|
||||
raop_rtp_mirror->sps_pps[h264.sps_size + 5] = 0;
|
||||
raop_rtp_mirror->sps_pps[h264.sps_size + 6] = 0;
|
||||
raop_rtp_mirror->sps_pps[h264.sps_size + 7] = 1;
|
||||
memcpy(raop_rtp_mirror->sps_pps + h264.sps_size + 8, h264.picture_parameter_set, h264.pps_size);
|
||||
|
||||
#ifdef DUMP_H264
|
||||
fwrite(raop_rtp_mirror->sps_pps, raop_rtp_mirror->sps_pps_len, 1, file);
|
||||
#endif
|
||||
|
||||
if (remainder_size > 0) {
|
||||
str = utils_data_to_string (picture_parameter_set + pps_size, remainder_size, 16);
|
||||
logger_log(raop_rtp_mirror->logger, LOGGER_DEBUG, "remainder size = %d", remainder_size);
|
||||
logger_log(raop_rtp_mirror->logger, LOGGER_DEBUG, "remainder of sps+pps packet:\n%s", str);
|
||||
free(str);
|
||||
} else if (remainder_size < 0) {
|
||||
logger_log(raop_rtp_mirror->logger, LOGGER_ERR, " pps_sps error: packet remainder size = %d < 0", remainder_size);
|
||||
}
|
||||
free(h264.picture_parameter_set);
|
||||
free(h264.sequence_parameter_set);
|
||||
|
||||
// Copy the sps and pps into a buffer to prepend to the next NAL unit.
|
||||
if (sps_pps) {
|
||||
free(sps_pps);
|
||||
}
|
||||
sps_pps_len = sps_size + pps_size + 8;
|
||||
sps_pps = (unsigned char*) malloc(sps_pps_len);
|
||||
assert(sps_pps);
|
||||
sps_pps[0] = 0;
|
||||
sps_pps[1] = 0;
|
||||
sps_pps[2] = 0;
|
||||
sps_pps[3] = 1;
|
||||
memcpy(sps_pps + 4, sequence_parameter_set, sps_size);
|
||||
sps_pps[sps_size + 4] = 0;
|
||||
sps_pps[sps_size + 5] = 0;
|
||||
sps_pps[sps_size + 6] = 0;
|
||||
sps_pps[sps_size + 7] = 1;
|
||||
memcpy(sps_pps + sps_size + 8, payload + sps_size + 11, pps_size);
|
||||
#ifdef DUMP_H264
|
||||
fwrite(sps_pps, sps_pps_len, 1, file);
|
||||
#endif
|
||||
// h264codec_t h264;
|
||||
// h264.version = payload[0];
|
||||
// h264.profile_high = payload[1];
|
||||
// h264.compatibility = payload[2];
|
||||
// h264.level = payload[3];
|
||||
// h264.reserved_6_and_nal = payload[4];
|
||||
// h264.reserved_3_and_sps = payload[5];
|
||||
// h264.sps_size = sps_size;
|
||||
// h264.sequence_parameter_set = malloc(h264.sps_size);
|
||||
// memcpy(h264.sequence_parameter_set, sequence_parameter_set, sps_size);
|
||||
// h264.number_of_pps = payload[h264.sps_size + 8];
|
||||
// h264.pps_size = pps_size;
|
||||
// h264.picture_parameter_set = malloc(h264.pps_size);
|
||||
// memcpy(h264.picture_parameter_set, picture_parameter_set, pps_size);
|
||||
|
||||
break;
|
||||
case 0x05:
|
||||
logger_log(raop_rtp_mirror->logger, LOGGER_DEBUG, "\nReceived video streaming performance info packet from client");
|
||||
@@ -600,9 +609,6 @@ void raop_rtp_mirror_destroy(raop_rtp_mirror_t *raop_rtp_mirror) {
|
||||
raop_rtp_mirror_stop(raop_rtp_mirror);
|
||||
MUTEX_DESTROY(raop_rtp_mirror->run_mutex);
|
||||
mirror_buffer_destroy(raop_rtp_mirror->buffer);
|
||||
if (raop_rtp_mirror->sps_pps) {
|
||||
free(raop_rtp_mirror->sps_pps);
|
||||
}
|
||||
free(raop_rtp_mirror);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user