Add modifications for V9 of the nqptp interface.

This commit is contained in:
Mike Brady
2023-01-19 14:32:32 +00:00
parent 17c39797c6
commit 6eb70eee70
3 changed files with 33 additions and 17 deletions
+26 -16
View File
@@ -22,26 +22,36 @@
#define NQPTP_INTERFACE_NAME "/nqptp"
#define NQPTP_SHM_STRUCTURES_VERSION 8
#define NQPTP_SHM_STRUCTURES_VERSION 9
#define NQPTP_CONTROL_PORT 9000
// The control port expects a UDP packet with the first space-delimited string
// being the name of the shared memory interface (SMI) to be used.
// This allows client applications to have a dedicated named SMI interface with
// a timing peer list independent of other clients.
// The name given must be a valid SMI name and must contain no spaces.
// If the named SMI interface doesn't exist it will be created by NQPTP.
// The SMI name should be delimited by a space and followed by a command letter.
// At present, the only command is "T", which must followed by nothing or by
// a space and a space-delimited list of IPv4 or IPv6 numbers,
// the whole not to exceed 4096 characters in total.
// The control port expects a UDP packet with the first character being a command letter
// and the rest being any arguments, the whole not to exceed 4096 characters.
// The "T" command, must followed by nothing or by
// a space and a space-delimited list of IPv4 or IPv6 numbers.
// The IPs, if provided, will become the new list of timing peers, replacing any
// previous list. If the master clock of the new list is the same as that of the old list,
// the master clock is retained without resynchronisation; this means that non-master
// devices can be added and removed without disturbing the SMI's existing master clock.
// previous list. The first IP number is the clock that NQPTP will listen to.
// The remaining IP address are the addresses of all the timing peers. The timing peers
// are not used in this version of NQPTP.
// If no timing list is provided, the existing timing list is deleted.
// (In future version of NQPTP the SMI interface may also be deleted at this point.)
// SMI interfaces are not currently deleted or garbage collected.
// The "B" command is a message that the client -- which generates the clock --
// is about to start playing.
// NQPTP uses it to determine that the clock is active and will not sleep.
// The "E" command signifies that the client has stopped playing and that
// the clock may shortly sleep.
// The "P" command signifies that SPS has paused play (buffered audio only).
// The clock seems to stay running in this state.
// When the clock is active, it is assumed that any decreases in the offset
// between the local and remote clocks are due to delays in the network.
// NQPTP smooths the offset by clamping any decreases to a small value.
// In this way, it can follow clock drift but ignore network delays.
// When the clock is inactive, it can stop running. This causes the offset to decrease.
// NQPTP clock smoothing would treat this as a network delay, causing true sync to be lost.
// To avoid this, when the clock goes from inactive to active,
// NQPTP resets clock smoothing to the new offset.
#include <inttypes.h>
#include <pthread.h>
+3
View File
@@ -3606,6 +3606,9 @@ int player_stop(rtsp_conn_info *conn) {
// debuglev = 3;
debug(3, "player_stop");
if (conn->player_thread) {
#ifdef CONFIG_AIRPLAY_2
ptp_send_control_message_string("E"); // signify play is "E"nding
#endif
debug(3, "player_thread cancel...");
pthread_cancel(*conn->player_thread);
debug(3, "player_thread join...");
+4 -1
View File
@@ -2022,6 +2022,7 @@ void handle_setrateanchori(rtsp_conn_info *conn, rtsp_message *req, rtsp_message
pthread_cleanup_push(mutex_unlock, &conn->flush_mutex);
conn->ap2_rate = rate;
if ((rate & 1) != 0) {
ptp_send_control_message_string("B"); // signify play is "B"eginning or resuming
debug(2, "Connection %d: Start playing, with anchor clock %" PRIx64 ".",
conn->connection_number, conn->networkTimeTimelineID);
activity_monitor_signify_activity(1);
@@ -2031,7 +2032,8 @@ void handle_setrateanchori(rtsp_conn_info *conn, rtsp_message *req, rtsp_message
#endif
conn->ap2_play_enabled = 1;
} else {
debug(2, "Connection %d: Stop playing.", conn->connection_number);
ptp_send_control_message_string("P"); // signify play is "P"ausing
debug(2, "Connection %d: Pause playing.", conn->connection_number);
conn->ap2_play_enabled = 0;
activity_monitor_signify_activity(0);
reset_anchor_info(conn);
@@ -2955,6 +2957,7 @@ void handle_setup_2(rtsp_conn_info *conn, rtsp_message *req, rtsp_message *resp)
// if it's a full service PTP stream, we get groupUUID, groupContainsGroupLeader and
// timingPeerList
if (conn->airplay_stream_category == ptp_stream) {
ptp_send_control_message_string("B"); // signify play is "B"eginning
if (ptp_shm_interface_open() !=
0) // it should be open already, but just in case it isn't...
die("Can not access the NQPTP service. Has it stopped running?");