add options to dump video or audio to file

This commit is contained in:
fduncanh
2022-03-28 13:03:29 -04:00
parent 7c8636aa4f
commit aec4a07346
5 changed files with 272 additions and 12 deletions

View File

@@ -1,10 +1,10 @@
<h1 id="uxplay-1.48-airplayairplay-mirror-server-for-linux-macos-and-unix.">UxPlay 1.48: AirPlay/AirPlay-Mirror server for Linux, macOS, and Unix.</h1>
<h1 id="uxplay-1.49-airplayairplay-mirror-server-for-linux-macos-and-unix.">UxPlay 1.49: AirPlay/AirPlay-Mirror server for Linux, macOS, and Unix.</h1>
<h3 id="now-developed-at-github-site-httpsgithub.comfdh2uxplay-where-user-issues-should-be-posted.">Now developed at GitHub site <a href="https://github.com/FDH2/UxPlay">https://github.com/FDH2/UxPlay</a> (where user issues should be posted).</h3>
<p>Highlights:</p>
<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 macOS clients.</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>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>
@@ -101,6 +101,9 @@
<p><strong>-reset n</strong> sets a limit of n consective timeout failures of the client to respond to ntp requests from the server (these are sent every 3 seconds to check if the client is still present). After n failures, the client will be presumed to be offline, and the connection will be reset to allow a new connection. The default value of n is 10; the value n = 0 means “no limit” on timeouts.</p>
<p><strong>-nc</strong> maintains previous UxPlay &lt; 1.45 behavior that does <strong>not close</strong> the video window when the the client sends the “Stop Mirroring” signal. <em>This option is currently used by default in macOS, as the window created in macOS by GStreamer does not terminate correctly (it causes a segfault) if it is still open when the GStreamer pipeline is closed.</em></p>
<p><strong>-t <em>timeout</em></strong> will cause the server to relaunch (without stopping uxplay) if no connections have been present during the previous <em>timeout</em> seconds. You may wish to use this if the Server is not visible to new Clients that were inactive when the Server was launched, and an idle Bonjour registration eventually becomes unavailable for new connections (this is a workaround for what may be due to a problem with your DNS-SD or Avahi setup). <em>This option is currently disabled in macOS, for the same reason that requires the -nc option.</em></p>
<p><strong>-vdmp</strong> Dumps h264 video to file videodump.h264. -vdmp n dumps not more than n NAL units to videodump.x.h264; x= 1,2,… increases each time a SPS/PPS NAL unit arrives. To change the name <em>videodump</em>, use -vdmp [n] <em>filename</em>.</p>
<p><strong>-admp</strong> Dumps audio to file audiodump.x.aac (AAC-ELD format audio), audiodump.x.alac (ALAC format audio) or audiodump.x.aud (other-format audio), where x = 1,2,3… increases each time the audio format changes. -admp <em>n</em> restricts the number of packets dumped to a file to <em>n</em> or less. To change the name <em>audiodump</em>, use -admp [n] <em>filename</em>.</p>
<p><strong>-d</strong> Enable debug output. Note: this does not show GStreamer error or debug messages. To see GStreamer error error and warning messages, set the environment variable GST_DEBUG with “export GST_DEBUG=2” before running uxplay. To see GStreamer debug messages, set GST_DEBUG=4; increase this to see even more of the GStreamer inner workings.</p>
<h1 id="troubleshooting">Troubleshooting</h1>
<p>Note: <code>uxplay</code> is run from a terminal command line, and informational messages are written to the terminal.</p>
<h3 id="problems-in-compiling-uxplay.">0. Problems in compiling UxPlay.</h3>
@@ -113,6 +116,8 @@
<h3 id="problems-after-the-client-server-connection-has-been-made">3. Problems <em>after</em> the client-server connection has been made:</h3>
<p>If you do <em>not</em> see the message <code>raop_rtp_mirror starting mirroring</code>, something went wrong before the client-server negotiations were finished. For such problems, use “uxplay -d” (debug log option) to see what is happening: it will show how far the connection process gets before the failure occurs. You can compare your debug output to that from a successful start of UxPlay in the <a href="https://github.com/FDH2/UxPlay/wiki">UxPlay Wiki</a>.</p>
<p><strong>If UxPlay reports that mirroring started, but you get no video or audio, the problem is probably from a GStreamer plugin that doesnt work on your system</strong> (by default, GStreamer uses the “autovideosink” and “autoaudiosink” algorithms to guess what are the “best” plugins to use on your system).</p>
<p><strong>M1 (Apple Silicon) Macs stream video with h264 profile High at level 4.2, as opposed to High at level 4.1 (streamed by Intel Macs). Currently, this is not being correctly recognized by GStreamer, and a video window fails to open when the client is a M1 Mac. Audio streaming is unaffected. </strong> See <a href="https://github.com/FDH2/UxPlay/issues/73">here</a> for efforts to fix this.</p>
<p><strong>Raspberry Pi</strong> devices (-rpi option) only work with hardware GPU decoding if the Video4Linux2 plugin in GStreamer v1.20.x or earlier has been patched (see the UxPlay <a href="https://github.com/FDH2/UxPlay/wiki/Gstreamer-Video4Linux2-plugin-patches">Wiki</a> for patches). This may be fixed in the future when GStreamer-1.22 is released, or by backport patches in distributions such as Raspberry Pi OS (Bullseye).</p>
<p>Sometimes “autovideosink” may select the OpenGL renderer “glimagesink” which may not work correctly on your system. Try the options “-vs ximagesink” or “-vs xvimagesink” to see if using one of these fixes the problem.</p>
<p>Other reported problems are connected to the GStreamer VAAPI plugin (for hardware-accelerated Intel graphics, but not NVIDIA graphics). Use the option “-avdec” to force software h264 video decoding: this should prevent autovideosink from selecting the vaapisink videosink. Alternatively, find out if the gstreamer1.0-vaapi plugin is installed, and if so, uninstall it. (If this does not fix the problem, you can reinstall it.)</p>
<p>There are some reports of other GStreamer problems with hardware-accelerated Intel HD graphics. One user (on Debian) solved this with “sudo apt install intel-media-va-driver-non-free”. This is a driver for 8th (or later) generation "*-lake" Intel chips, that seems to be related to VAAPI accelerated graphics.</p>
@@ -130,6 +135,7 @@
<p>This triggers an unending stream of error messages, and means that the audio decryption key (also used in video decryption) was not correctly extracted from data sent by the client. This should not happen for iOS 9.3 or later clients. However, if a client uses the same older version of the protocol that is used by the Windows-based AirPlay client emulator <em>AirMyPC</em>, the protocol can be switched to the older version by the setting <code>OLD_PROTOCOL_CLIENT_USER_AGENT_LIST</code> in lib/global.h. UxPlay reports the clients “User Agent” string when it connects. If some other client also fails to decrypt all audio and video, try adding its “User Agent” string in place of “xxx” in the entry “AirMyPC/2.0;xxx” in global.h and rebuild uxplay.</p>
<p>Note that Uxplay declares itself to be an AppleTV3,2 with a sourceVersion 220.68; this can also be changed in global.h. It had been thought that it was necessary for UxPlay to claim to be an older 32 bit AppleTV model that cannot run modern 64bit tvOS, in order for the client to use a “legacy” protocol for pairing with the server (see the <em>“Notes on AirPlay protocol versions”</em> at the end of this README). However, UxPlay still works if it declares itself as an AppleTV6,2 with sourceVersion 380.20.1 (an AppleTV 4K 1st gen, introduced 2017, running tvOS 12.2.1), so it is unclear what setting prompts the client to use the “legacy” protocol needed by UxPlay.</p>
<h1 id="changelog">ChangeLog</h1>
<p>1.49 2022-03-28 Addded options for dumping video and/or audio to file, for debugging, etc. h264 PPS/SPS NALUs are shown with -d.</p>
<p>1.48 2022-03-11 Made the GStreamer video pipeline fully configurable, for use with hardware h264 decoding. Support for Raspberry Pi.</p>
<p>1.47 2022-02-05 Added -FPSdata option to display (in the terminal) regular reports sent by the client about video streaming performance. Internal cleanups of processing of video packets received from the client. Added -reset n option to reset the connection after n ntp timeouts (also reset after “connection reset by peer” error in video stream).</p>
<p>1.46 2022-01-20 Restore pre-1.44 behavior (1.44 may have broken hardware acceleration): once again use decodebin in the video pipeline; introduce new option “-avdec” to force software h264 decoding by libav h264, if needed (to prevent selection of vaapisink by autovideosink). Update llhttp to v6.0.6. UxPlay now reports itself as AppleTV3,2. Restrict connections to one client at a time (second client must now wait for first client to disconnect).</p>
@@ -164,6 +170,7 @@
<li><p>Added suppport for the older AirPlay protocol used by third-party Windows-based AirPlay mirror emulators such as AirMyPC.</p></li>
<li><p>Made the video pipeline fully configurable with options -vp, -vd, -vc, for accelerated hardware support (e.g. NVIDIA).</p></li>
<li><p>Added Raspberry Pi support (accelerated hardware decoding) with -rpi option.</p></li>
<li><p>Added otions to dump audio and/or video to file.</p></li>
</ol>
<h1 id="disclaimer">Disclaimer</h1>
<p>All the resources in this repository are written using only freely available information from the internet. The code and related resources are meant for educational purposes only. It is the responsibility of the user to make sure all local laws are adhered to.</p>

View File

@@ -1,4 +1,4 @@
# UxPlay 1.48: AirPlay/AirPlay-Mirror server for Linux, macOS, and Unix.
# UxPlay 1.49: AirPlay/AirPlay-Mirror server for Linux, macOS, and Unix.
### Now developed at GitHub site [https://github.com/FDH2/UxPlay](https://github.com/FDH2/UxPlay) (where user issues should be posted).
@@ -9,7 +9,8 @@ Highlights:
* Support for both AirPlay Mirror and AirPlay Audio-only (Apple 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 macOS clients.
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)) .
* 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.
* Uses GStreamer, with options to select different output "videosinks" and "audiosinks".
@@ -415,6 +416,18 @@ Also: image transforms that had been added to RPiPlay have been ported to UxPlay
may be due to a problem with your DNS-SD or Avahi setup). _This option is currently disabled in
macOS, for the same reason that requires the -nc option._
**-vdmp** Dumps h264 video to file videodump.h264. -vdmp n dumps not more than n NAL units to
videodump.x.h264; x= 1,2,... increases each time a SPS/PPS NAL unit arrives. To change the name
_videodump_, use -vdmp [n] _filename_.
**-admp** Dumps audio to file audiodump.x.aac (AAC-ELD format audio), audiodump.x.alac (ALAC format audio) or audiodump.x.aud
(other-format audio), where x = 1,2,3... increases each time the audio format changes. -admp _n_ restricts the number of
packets dumped to a file to _n_ or less. To change the name _audiodump_, use -admp [n] _filename_.
**-d** Enable debug output. Note: this does not show GStreamer error or debug messages. To see GStreamer error
error and warning messages, set the environment variable GST_DEBUG with "export GST_DEBUG=2" before running uxplay.
To see GStreamer debug messages, set GST_DEBUG=4; increase this to see even more of the GStreamer inner workings.
# Troubleshooting
Note: ```uxplay``` is run from a terminal command line, and informational messages are written to the terminal.
@@ -465,6 +478,16 @@ GStreamer plugin that doesn't work on your system** (by default,
GStreamer uses the "autovideosink" and "autoaudiosink" algorithms
to guess what are the "best" plugins to use on your system).
**M1 (Apple Silicon) Macs stream video with h264 profile High at level 4.2, as opposed to High at level 4.1
(streamed by Intel Macs).
Currently, this is not being correctly recognized by GStreamer, and a video window fails to open when the client is a M1 Mac.
Audio streaming is unaffected. **
See [here]( https://github.com/FDH2/UxPlay/issues/73) for efforts to fix this.
**Raspberry Pi** devices (-rpi option) only work with hardware GPU decoding if the Video4Linux2 plugin in GStreamer v1.20.x or earlier has been patched
(see the UxPlay [Wiki](https://github.com/FDH2/UxPlay/wiki/Gstreamer-Video4Linux2-plugin-patches) for patches).
This may be fixed in the future when GStreamer-1.22 is released, or by backport patches in distributions such as Raspberry Pi OS (Bullseye).
Sometimes "autovideosink" may select the OpenGL renderer "glimagesink" which
may not work correctly on your system. Try the options "-vs ximagesink" or
"-vs xvimagesink" to see if using one of these fixes the problem.
@@ -553,6 +576,8 @@ tvOS 12.2.1), so it is unclear what setting prompts the client
to use the "legacy" protocol needed by UxPlay.
# ChangeLog
1.49 2022-03-28 Addded options for dumping video and/or audio to file, for debugging, etc. h264 PPS/SPS NALU's are shown with -d.
1.48 2022-03-11 Made the GStreamer video pipeline fully configurable, for use with hardware h264 decoding. Support for Raspberry Pi.
1.47 2022-02-05 Added -FPSdata option to display (in the terminal) regular reports sent by the client about video streaming
@@ -682,6 +707,8 @@ is compiled.) On macOS, Avahi is not used.
15. Added Raspberry Pi support (accelerated hardware decoding) with -rpi option.
16. Added otions to dump audio and/or video to file.
# Disclaimer
All the resources in this repository are written using only freely available information from the internet. The code and related resources are meant for educational purposes only. It is the responsibility of the user to make sure all local laws are adhered to.

View File

@@ -1,4 +1,4 @@
UxPlay 1.48: AirPlay/AirPlay-Mirror server for Linux, macOS, and Unix.
UxPlay 1.49: AirPlay/AirPlay-Mirror server for Linux, macOS, and Unix.
======================================================================
### Now developed at GitHub site <https://github.com/FDH2/UxPlay> (where user issues should be posted).
@@ -11,8 +11,10 @@ Highlights:
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 macOS
clients.
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)) .
- 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.
@@ -539,6 +541,23 @@ connections (this is a workaround for what may be due to a problem with
your DNS-SD or Avahi setup). *This option is currently disabled in
macOS, for the same reason that requires the -nc option.*
**-vdmp** Dumps h264 video to file videodump.h264. -vdmp n dumps not
more than n NAL units to videodump.x.h264; x= 1,2,... increases each
time a SPS/PPS NAL unit arrives. To change the name *videodump*, use
-vdmp \[n\] *filename*.
**-admp** Dumps audio to file audiodump.x.aac (AAC-ELD format audio),
audiodump.x.alac (ALAC format audio) or audiodump.x.aud (other-format
audio), where x = 1,2,3... increases each time the audio format changes.
-admp *n* restricts the number of packets dumped to a file to *n* or
less. To change the name *audiodump*, use -admp \[n\] *filename*.
**-d** Enable debug output. Note: this does not show GStreamer error or
debug messages. To see GStreamer error error and warning messages, set
the environment variable GST\_DEBUG with "export GST\_DEBUG=2" before
running uxplay. To see GStreamer debug messages, set GST\_DEBUG=4;
increase this to see even more of the GStreamer inner workings.
Troubleshooting
===============
@@ -606,6 +625,21 @@ on your system** (by default, GStreamer uses the "autovideosink" and
"autoaudiosink" algorithms to guess what are the "best" plugins to use
on your system).
**M1 (Apple Silicon) Macs stream video with h264 profile High at level
4.2, as opposed to High at level 4.1 (streamed by Intel Macs).
Currently, this is not being correctly recognized by GStreamer, and a
video window fails to open when the client is a M1 Mac. Audio streaming
is unaffected. ** See [here](https://github.com/FDH2/UxPlay/issues/73)
for efforts to fix this.
**Raspberry Pi** devices (-rpi option) only work with hardware GPU
decoding if the Video4Linux2 plugin in GStreamer v1.20.x or earlier has
been patched (see the UxPlay
[Wiki](https://github.com/FDH2/UxPlay/wiki/Gstreamer-Video4Linux2-plugin-patches)
for patches). This may be fixed in the future when GStreamer-1.22 is
released, or by backport patches in distributions such as Raspberry Pi
OS (Bullseye).
Sometimes "autovideosink" may select the OpenGL renderer "glimagesink"
which may not work correctly on your system. Try the options "-vs
ximagesink" or "-vs xvimagesink" to see if using one of these fixes the
@@ -727,6 +761,9 @@ the "legacy" protocol needed by UxPlay.
ChangeLog
=========
1.49 2022-03-28 Addded options for dumping video and/or audio to file,
for debugging, etc. h264 PPS/SPS NALU's are shown with -d.
1.48 2022-03-11 Made the GStreamer video pipeline fully configurable,
for use with hardware h264 decoding. Support for Raspberry Pi.
@@ -890,6 +927,8 @@ Improvements
15. Added Raspberry Pi support (accelerated hardware decoding) with -rpi
option.
16. Added otions to dump audio and/or video to file.
Disclaimer
==========

View File

@@ -1,11 +1,11 @@
.TH UXPLAY "1" "February 2022" "1.48" "User Commands"
.TH UXPLAY "1" "March 2022" "1.49" "User Commands"
.SH NAME
uxplay \- start AirPlay server
.SH SYNOPSIS
.B uxplay
[\fI\,-n name\/\fR] [\fI\,-s wxh\/\fR] [\fI\,-p \/\fR[\fI\,n\/\fR]] [more \fI OPTIONS \/\fR ...]
.SH DESCRIPTION
UxPlay 1.48: An open\-source AirPlay mirroring server based on RPiPlay
UxPlay 1.49: An open\-source AirPlay mirroring server based on RPiPlay
.SH OPTIONS
.TP
.B
@@ -75,6 +75,24 @@ UxPlay 1.48: An open\-source AirPlay mirroring server based on RPiPlay
.TP
\fB\-FPSdata\fR Show video-streaming performance reports sent by client.
.TP
\fB\-vdmp\fR [n] Dump h264 video output to "fn.h264"; fn="videodump", change
.IP
with "-vdmp [n] filename". If [n] is given, file fn.x.h264
.IP
x=1,2,.. opens whenever a new SPS/PPS NAL arrives, and <=n
.IP
NAL units are dumped.
.PP
.TP
\fB\-admp\fR [n] Dump audio output to "fn.x.fmt", fmt ={aac, alac, aud}, x
.IP
=1,2,..; fn="audiodump"; change with "-admp [n] filename".
.IP
x increases when audio format changes. If n is given, <= n
.IP
audio packets are dumped. "aud"= unknown format.
.PP
.TP
\fB\-d\fR Enable debug logging
.TP
\fB\-v\fR or \fB\-h\fR Displays this help and version information

View File

@@ -44,7 +44,7 @@
#include "renderers/video_renderer.h"
#include "renderers/audio_renderer.h"
#define VERSION "1.48"
#define VERSION "1.49"
#define DEFAULT_NAME "UxPlay"
#define DEFAULT_DEBUG_LOG false
@@ -82,7 +82,99 @@ static std::string video_decoder = "decodebin";
static std::string video_converter = "videoconvert";
static bool show_client_FPS_data = false;
static unsigned int max_ntp_timeouts = NTP_TIMEOUT_LIMIT;
static FILE *video_dumpfile = NULL;
static std::string video_dumpfile_name = "videodump";
static int video_dump_limit = 0;
static int video_dumpfile_count = 0;
static int video_dump_count = 0;
static bool dump_video = false;
static unsigned char mark[] = { 0x00, 0x00, 0x00, 0x01 };
static FILE *audio_dumpfile = NULL;
static std::string audio_dumpfile_name = "audiodump";
static int audio_dump_limit = 0;
static int audio_dumpfile_count = 0;
static int audio_dump_count = 0;
static bool dump_audio = false;
static unsigned char audio_type = 0x0;
static unsigned char previous_audio_type = 0x0;
void dump_audio_to_file(unsigned char *data, int datalen, unsigned char type) {
if (!audio_dumpfile && audio_type != previous_audio_type) {
char suffix[20];
std::string fn = audio_dumpfile_name;
previous_audio_type = audio_type;
audio_dumpfile_count++;
audio_dump_count = 0;
/* type 0x20 is lossless ALAC, type 0x80 is compressed AAC-ELD, type 0x00 is "other" */
if (audio_type == 0x20) {
snprintf(suffix, sizeof(suffix), ".%d.alac", audio_dumpfile_count);
} else if (audio_type == 0x80) {
snprintf(suffix, sizeof(suffix), ".%d.aac", audio_dumpfile_count);
} else {
snprintf(suffix, sizeof(suffix), ".%d.aud", audio_dumpfile_count);
}
fn.append(suffix);
audio_dumpfile = fopen(fn.c_str(),"w");
if (audio_dumpfile == NULL) {
LOGE("could not open file %s for dumping audio frames",fn.c_str());
}
}
if (audio_dumpfile) {
fwrite(data, 1, datalen, audio_dumpfile);
if (audio_dump_limit) {
audio_dump_count++;
if (audio_dump_count == audio_dump_limit) {
fclose(audio_dumpfile);
audio_dumpfile = NULL;
}
}
}
}
void dump_video_to_file(unsigned char *data, int datalen, int type) {
/* type 5 NAL's are precedded by a PPS and SPS */
if (type == 5 && video_dumpfile && video_dump_limit) {
}
if (video_dump_limit == 0) {
if (!video_dumpfile) {
std::string fn = video_dumpfile_name;
fn.append(".h264");
video_dumpfile = fopen (fn.c_str(),"w");
if (video_dumpfile == NULL) {
LOGE("could not open file %s for dumping h264 frames",fn.c_str());
}
}
} else if (type == 5) {
char suffix[20];
std::string fn = video_dumpfile_name;
video_dumpfile_count++;
snprintf(suffix, sizeof(suffix), ".%d.h264", video_dumpfile_count);
fn.append(suffix);
if (video_dumpfile) {
fwrite(mark, 1, sizeof(mark), video_dumpfile);
fclose(video_dumpfile);
}
video_dumpfile = fopen (fn.c_str(),"w");
if (video_dumpfile == NULL) {
LOGE("could not open file %s for dumping h264 frames",fn.c_str());
}
}
if (video_dumpfile) {
fwrite(data, 1, datalen, video_dumpfile);
if (video_dump_limit) {
video_dump_count++;
if (video_dump_count == video_dump_limit) {
fwrite(mark, 1, sizeof(mark), video_dumpfile);
fclose(video_dumpfile);
video_dumpfile = NULL;
}
}
}
}
static gboolean connection_callback (gpointer loop){
if (!connections_stopped) {
counter = 0;
@@ -246,6 +338,14 @@ static void print_info (char *name) {
printf("-reset n Reset after 3n seconds client silence (default %d, 0=never)\n", NTP_TIMEOUT_LIMIT);
printf("-nc do Not Close video window when client stops mirroring\n");
printf("-FPSdata Show video-streaming performance reports sent by client.\n");
printf("-vdmp [n] Dump h264 video output to \"fn.h264\"; fn=\"videodump\",change\n");
printf(" with \"-vdmp [n] filename\". If [n] is given, file fn.x.h264\n");
printf(" x=1,2,.. opens whenever a new SPS/PPS NAL arrives, and <=n\n");
printf(" NAL units are dumped.\n");
printf("-admp [n] Dump audio output to \"fn.x.fmt\", fmt ={aac, alac, aud}, x\n");
printf(" =1,2,..; fn=\"audiodump\"; change with \"-admp [n] filename\".\n");
printf(" x increases when audio format changes. If n is given, <= n\n");
printf(" audio packets are dumped. \"aud\"= unknown format.\n");
printf("-d Enable debug logging\n");
printf("-v or -h Displays this help and version information\n");
}
@@ -505,7 +605,45 @@ int main (int argc, char *argv[]) {
if (!get_value(argv[++i], &max_ntp_timeouts)) {
fprintf(stderr, "invalid \"-reset %s\"; -reset n must have n >= 0, default n = %d\n", argv[i], NTP_TIMEOUT_LIMIT);
exit(1);
}
}
} else if (arg == "-vdmp") {
dump_video = true;
if (option_has_value(i, argc, arg, argv[i+1])) {
unsigned int n = 0;
if (get_value (argv[++i], &n)) {
if (n == 0) {
fprintf(stderr, "invalid \"-vdmp 0 %s\"; -vdmp n needs a non-zero value of n\n");
exit(1);
}
video_dump_limit = n;
if (option_has_value(i, argc, arg, argv[i+1])) {
video_dumpfile_name.erase();
video_dumpfile_name.append(argv[++i]);
}
} else {
video_dumpfile_name.erase();
video_dumpfile_name.append(argv[i]);
}
}
} else if (arg == "-admp") {
dump_audio = true;
if (option_has_value(i, argc, arg, argv[i+1])) {
unsigned int n = 0;
if (get_value (argv[++i], &n)) {
if (n == 0) {
fprintf(stderr, "invalid \"-admp 0 %s\"; -admp n needs a non-zero value of n\n");
exit(1);
}
audio_dump_limit = n;
if (option_has_value(i, argc, arg, argv[i+1])) {
audio_dumpfile_name.erase();
audio_dumpfile_name.append(argv[++i]);
}
} else {
audio_dumpfile_name.erase();
audio_dumpfile_name.append(argv[i]);
}
}
} else {
LOGE("unknown option %s, stopping\n",argv[i]);
exit(1);
@@ -610,6 +748,13 @@ int main (int argc, char *argv[]) {
}
logger_destroy(render_logger);
render_logger = NULL;
if(audio_dumpfile) {
fclose(audio_dumpfile);
}
if (video_dumpfile) {
fwrite(mark, 1, sizeof(mark), video_dumpfile);
fclose(video_dumpfile);
}
}
// Server callbacks
@@ -649,15 +794,21 @@ extern "C" void conn_teardown(void *cls, bool *teardown_96, bool *teardown_110)
}
extern "C" void audio_process (void *cls, raop_ntp_t *ntp, aac_decode_struct *data) {
if (dump_audio) {
dump_audio_to_file(data->data, data->data_len, (data->data)[0] & 0xf0);
}
if (use_audio) {
audio_renderer_render_buffer(ntp, data->data, data->data_len, data->pts);
}
}
extern "C" void video_process (void *cls, raop_ntp_t *ntp, h264_decode_struct *data) {
if (dump_video) {
dump_video_to_file(data->data, data->data_len, data->frame_type);
}
if (use_video) {
video_renderer_render_buffer(ntp, data->data, data->data_len, data->pts, data->frame_type);
}
}
}
extern "C" void audio_flush (void *cls) {
@@ -679,7 +830,25 @@ extern "C" void audio_set_volume (void *cls, float volume) {
}
extern "C" void audio_get_format (void *cls, unsigned char *ct, unsigned short *spf, bool *usingScreen, bool *isMedia, uint64_t *audioFormat) {
unsigned char type;
LOGI("ct=%d spf=%d usingScreen=%d isMedia=%d audioFormat=0x%lx",*ct, *spf, *usingScreen, *isMedia, (unsigned long) *audioFormat);
switch (*ct) {
case 2:
type = 0x20;
break;
case 8:
type = 0x80;
break;
default:
type = 0x10;
break;
}
if (audio_dumpfile && type != audio_type) {
fclose(audio_dumpfile);
audio_dumpfile = NULL;
}
audio_type = type;
if (use_audio) {
audio_renderer_start(ct);
}