fixed M1 video problem

This commit is contained in:
fduncanh
2022-04-01 13:09:20 -04:00
parent e61cd8cf7a
commit 695da77f56
4 changed files with 137 additions and 127 deletions

View File

@@ -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; dont try to use it on FreeBSD unless you need it.</p></li>
</ul>
<h3 id="building-openssl-1.1.1-from-source.">Building OpenSSL &gt;= 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 &gt;= 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 &gt;= 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 dont 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 dont 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>

View File

@@ -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.

View File

@@ -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.

View File

@@ -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);
}
}