Skip to content

design for addition of video streaming to UxPlay

fduncanh edited this page Jun 8, 2024 · 7 revisions

towards a UxPlay that supports video streaming.

  • a working model (in C++) is provided here Code from this will not be used, but it provides an open-source model that demonstrates how the protocols work, and allows them to be observed while working.

In UxPlay:

  1. httpd.c handles client connection requests, and accepts or rejects them. Each time it acceps a new connection, it call conn_init in raop.c. This returns a pointer to a new instance of the structure conn_raop_s. This knows about the port the request came in on and the local and remote ip addresses used. conn_raop_s will be give a new entry , an enum session_type_e session_type, which will take three values: SESSION_TYPE_UNKNOWN, SESSION_TYPE_RAOP and SESSION_TYPE_CASTING On creation, session type will be SESSION_TYPE_UNKNOWN. The struct conn_raop_t also contains a pointer to a struct paring_session_t pairing which contains information about whether secure client-server paring has been set up on the connection.

  2. In current UxPlay, only two connections are set up this way (1) the initial TCP connection that handles mirror and adio setup, and (2) an UDP connection for NTP time signals. The first of these will become SESSION_TYPE_RAOP, and the the second will remain SESSION_TYPE_UNKNOWN. The session type will be determined the first time a TCP connection request is received from the client in raop.c conn_req. In previous UxPlay with only mirror and audio support, the requests have a CSeq sequence number in their request header. Allowing them to be set to SESSION_TYPE_RAOP. (The UDP second (NTP timing) connection never receives any TCP conn_req requests, so its session type will remain SESSION_TYPE_UNKNOWN.)

  3. Older UxPlay rejects any TCP messages without a CSeq sequence number in the header. The messages with a CSeq are all RTSP/1.0 messages. When the rejection was removed, it was found that messages without CSeq come from a third connection (TCP) that related to video streaming. These are accepted if the AirPlay FEATURES bit 0 "AirPlay video supported" is switched on. (This was switched off in its predecessor RPiPlay). Another Features bit is bit 5, support HLS, which is used in video streaming.

  4. The TCP protocol in SESSION_TYPE_CASTING sessions is mainly HTTP/1.1, with RTSP/1.0 used for authentication. In SESSION_TYPE_RAOP, it is entirely RTSP/1.0

  5. When a SESSION_TYPE_CASTING session starts, the first HTTP request and RTSP pair_setup and pair_verify is GET server_info, to which a plist with server details is replied. Then the is a request POST reverse, asking for the HTTP connnection to be reversed.

  6. A POST play HTTP request follows, supplying a uuid and "Content Location" uri for the video. Next client request is a GET playback info, which requires a plist with playback info to be returned. This seems to require a playback_info struct to be attached to the conn_raop_s struct associated with the connection, to provide the data. We don't yet understand how the reverse HTTP connection works.

(apsdk:) ap_casting_media_data_store

functions defined

  • void set_store_root(uint16_t port) : called to set the TCP port (local or remote?)

  • bool request_media_data( string uri, string sessionid)

  • string process_media_data(string uri,string data) (

  • string query_media_data (string path) (

internal (protected)

  • app_id get_appi_id (string uri ) distinguished youtube and netflix HLS (mlhls or nfhls)

  • void add_media_data (string uri, string data)

  • string adjust primary_uri (string uri) convert mlhls to http, convert localhost to localhost:port

  • string extrac_uri_path(string uri_

  • string adjust_primary_media_data( string data)

  • string adjust_secondary_media_data (string data)

  • string adjust_mlhls_data(string data) for youtube

  • string adjust_nfhls_data( string data) for netflix

  • get (c++ class element), also constructor, destructor

  • void set_store_root (uint16_t port) sets host_ equal to localhost:port

  • bool request_media_data( string primary_uri, string session_id). what this does is:

#ifdef PERSISTANT_STREAM_DATA calls create_session_folder session_id)

gets app_id;

if it is not youtube or netflix type, then return false, otherwise

sets app_id_; sets session_id_;sets primary_uri_ by adjusting primary_uri, and then "send_fcup_request(primary_uri)" and return true.

  • string process_media_data( string uri, string data) what this does is:

if uri is the primary uri:

#include <hlsparser/hlsparse.h>
master_t master_playlist   (is this defined in the hlsparser code?)
if (HLS_OK hlsparse_master_init(&master_playlist) {
 if (hlsparse_master(....., &master_playlist)

iterates over uri's in uri_stack
for each one, calls send_fcup_request(next_uri)
 etc

This puts stuff int the string "media_data" which it returns.

will the returned output be put into media_data_?

  • string query_media_data ( string path)

looks for path in media_data, need to find definition of media_data structure

  • reset

destroys all data in media_data_

associated variables (put into a struct?)

  1. app_id_ (enum, distinguishes yout ube from netflix)

  2. request_id sequential increases: 0, 1, 2... as hls data is received.

  3. session_id (apple's one)

  4. primary uri

  5. (std stack??) uri_stack_ (? what is this)

  6. host_

  7. media_data_

  8. (mutex) mtx_