1 // 2 // This header exposes the public streaming API for client usage 3 // 4 5 #pragma once 6 7 #include <stdint.h> 8 9 #ifdef __cplusplus 10 extern "C" { 11 #endif 12 13 // Enable this definition during debugging to enable assertions 14 //#define LC_DEBUG 15 16 // Values for the 'streamingRemotely' field below 17 #define STREAM_CFG_LOCAL 0 18 #define STREAM_CFG_REMOTE 1 19 #define STREAM_CFG_AUTO 2 20 21 // Values for the 'colorSpace' field below. 22 // Rec. 2020 is only supported with HEVC video streams. 23 #define COLORSPACE_REC_601 0 24 #define COLORSPACE_REC_709 1 25 #define COLORSPACE_REC_2020 2 26 27 // Values for the 'colorRange' field below 28 #define COLOR_RANGE_LIMITED 0 29 #define COLOR_RANGE_FULL 1 30 31 typedef struct _STREAM_CONFIGURATION { 32 // Dimensions in pixels of the desired video stream 33 int width; 34 int height; 35 36 // FPS of the desired video stream 37 int fps; 38 39 // Bitrate of the desired video stream (audio adds another ~1 Mbps) 40 int bitrate; 41 42 // Max video packet size in bytes (use 1024 if unsure). If STREAM_CFG_AUTO 43 // determines the stream is remote (see below), it will cap this value at 44 // 1024 to avoid MTU-related issues like packet loss and fragmentation. 45 int packetSize; 46 47 // Determines whether to enable remote (over the Internet) 48 // streaming optimizations. If unsure, set to STREAM_CFG_AUTO. 49 // STREAM_CFG_AUTO uses a heuristic (whether the target address is 50 // in the RFC 1918 address blocks) to decide whether the stream 51 // is remote or not. 52 int streamingRemotely; 53 54 // Specifies the channel configuration of the audio stream. 55 // See AUDIO_CONFIGURATION_XXX constants below. 56 int audioConfiguration; 57 58 // Specifies that the client can accept an H.265 video stream 59 // if the server is able to provide one. 60 int supportsHevc; 61 62 // Specifies that the client is requesting an HDR H.265 video stream. 63 // 64 // This should only be set if: 65 // 1) The client decoder supports HEVC Main10 profile (supportsHevc must be set too) 66 // 2) The server has support for HDR as indicated by ServerCodecModeSupport in /serverinfo 67 // 3) The app supports HDR as indicated by IsHdrSupported in /applist 68 int enableHdr; 69 70 // Specifies the percentage that the specified bitrate will be adjusted 71 // when an HEVC stream will be delivered. This allows clients to opt to 72 // reduce bandwidth when HEVC is chosen as the video codec rather than 73 // (or in addition to) improving image quality. 74 int hevcBitratePercentageMultiplier; 75 76 // If specified, the client's display refresh rate x 100. For example, 77 // 59.94 Hz would be specified as 5994. This is used by recent versions 78 // of GFE for enhanced frame pacing. 79 int clientRefreshRateX100; 80 81 // If specified, sets the encoder colorspace to the provided COLORSPACE_* 82 // option (listed above). If not set, the encoder will default to Rec 601. 83 int colorSpace; 84 85 // If specified, sets the encoder color range to the provided COLOR_RANGE_* 86 // option (listed above). If not set, the encoder will default to Limited. 87 int colorRange; 88 89 // AES encryption data for the remote input stream. This must be 90 // the same as what was passed as rikey and rikeyid 91 // in /launch and /resume requests. 92 char remoteInputAesKey[16]; 93 char remoteInputAesIv[16]; 94 } STREAM_CONFIGURATION, *PSTREAM_CONFIGURATION; 95 96 // Use this function to zero the stream configuration when allocated on the stack or heap 97 void LiInitializeStreamConfiguration(PSTREAM_CONFIGURATION streamConfig); 98 99 // These identify codec configuration data in the buffer lists 100 // of frames identified as IDR frames. 101 #define BUFFER_TYPE_PICDATA 0x00 102 #define BUFFER_TYPE_SPS 0x01 103 #define BUFFER_TYPE_PPS 0x02 104 #define BUFFER_TYPE_VPS 0x03 105 106 typedef struct _LENTRY { 107 // Pointer to the next entry or NULL if this is the last entry 108 struct _LENTRY* next; 109 110 // Pointer to data (never NULL) 111 char* data; 112 113 // Size of data in bytes (never <= 0) 114 int length; 115 116 // Buffer type (listed above) 117 int bufferType; 118 } LENTRY, *PLENTRY; 119 120 // This is a standard frame which references the IDR frame and 121 // previous P-frames. 122 #define FRAME_TYPE_PFRAME 0x00 123 124 // Indicates this frame contains SPS, PPS, and VPS (if applicable) 125 // as the first buffers in the list. Each NALU will appear as a separate 126 // buffer in the buffer list. The I-frame data follows immediately 127 // after the codec configuration NALUs. 128 #define FRAME_TYPE_IDR 0x01 129 130 // A decode unit describes a buffer chain of video data from multiple packets 131 typedef struct _DECODE_UNIT { 132 // Frame number 133 int frameNumber; 134 135 // Frame type 136 int frameType; 137 138 // Receive time of first buffer. This value uses an implementation-defined epoch. 139 // To compute actual latency values, use LiGetMillis() to get a timestamp that 140 // shares the same epoch as this value. 141 unsigned long long receiveTimeMs; 142 143 // Presentation time in milliseconds with the epoch at the first captured frame. 144 // This can be used to aid frame pacing or to drop old frames that were queued too 145 // long prior to display. 146 unsigned int presentationTimeMs; 147 148 // Length of the entire buffer chain in bytes 149 int fullLength; 150 151 // Head of the buffer chain (never NULL) 152 PLENTRY bufferList; 153 } DECODE_UNIT, *PDECODE_UNIT; 154 155 // Specifies that the audio stream should be encoded in stereo (default) 156 #define AUDIO_CONFIGURATION_STEREO 0 157 158 // Specifies that the audio stream should be in 5.1 surround sound if the PC is able 159 #define AUDIO_CONFIGURATION_51_SURROUND 1 160 161 // Passed to DecoderRendererSetup to indicate that the following video stream will be 162 // in H.264 High Profile. 163 #define VIDEO_FORMAT_H264 0x0001 164 165 // Passed to DecoderRendererSetup to indicate that the following video stream will be 166 // in H.265 Main profile. This will only be passed if supportsHevc is true. 167 #define VIDEO_FORMAT_H265 0x0100 168 169 // Passed to DecoderRendererSetup to indicate that the following video stream will be 170 // in H.265 Main10 (HDR10) profile. This will only be passed if enableHdr is true. 171 #define VIDEO_FORMAT_H265_MAIN10 0x0200 172 173 // Masks for clients to use to match video codecs without profile-specific details. 174 #define VIDEO_FORMAT_MASK_H264 0x00FF 175 #define VIDEO_FORMAT_MASK_H265 0xFF00 176 177 // If set in the renderer capabilities field, this flag will cause audio/video data to 178 // be submitted directly from the receive thread. This should only be specified if the 179 // renderer is non-blocking. This flag is valid on both audio and video renderers. 180 #define CAPABILITY_DIRECT_SUBMIT 0x1 181 182 // If set in the video renderer capabilities field, this flag specifies that the renderer 183 // supports reference frame invalidation for AVC/H.264 streams. This flag is only valid on video renderers. 184 // If using this feature, the bitstream may not be patched (changing num_ref_frames or max_dec_frame_buffering) 185 // to avoid video corruption on packet loss. 186 #define CAPABILITY_REFERENCE_FRAME_INVALIDATION_AVC 0x2 187 188 // If set in the video renderer capabilities field, this flag specifies that the renderer 189 // supports reference frame invalidation for HEVC/H.265 streams. This flag is only valid on video renderers. 190 #define CAPABILITY_REFERENCE_FRAME_INVALIDATION_HEVC 0x4 191 192 // If set in the audio renderer capabilities field, this flag will cause the RTSP negotiation 193 // to never request the "high quality" audio preset. If unset, high quality audio will be 194 // used with video streams above 15 Mbps. 195 #define CAPABILITY_SLOW_OPUS_DECODER 0x8 196 197 // If set in the audio renderer capabilities field, this indicates that audio packets 198 // may contain more or less than 5 ms of audio. This requires that audio renderers read the 199 // samplesPerFrame field in OPUS_MULTISTREAM_CONFIGURATION to calculate the correct decoded 200 // buffer size rather than just assuming it will always be 240. 201 #define CAPABILITY_SUPPORTS_ARBITRARY_AUDIO_DURATION 0x10 202 203 // If set in the video renderer capabilities field, this macro specifies that the renderer 204 // supports slicing to increase decoding performance. The parameter specifies the desired 205 // number of slices per frame. This capability is only valid on video renderers. 206 #define CAPABILITY_SLICES_PER_FRAME(x) (((unsigned char)(x)) << 24) 207 208 // This callback is invoked to provide details about the video stream and allow configuration of the decoder. 209 // Returns 0 on success, non-zero on failure. 210 typedef int(*DecoderRendererSetup)(int videoFormat, int width, int height, int redrawRate, void* context, int drFlags); 211 212 // This callback notifies the decoder that the stream is starting. No frames can be submitted before this callback returns. 213 typedef void(*DecoderRendererStart)(void); 214 215 // This callback notifies the decoder that the stream is stopping. Frames may still be submitted but they may be safely discarded. 216 typedef void(*DecoderRendererStop)(void); 217 218 // This callback performs the teardown of the video decoder. No more frames will be submitted when this callback is invoked. 219 typedef void(*DecoderRendererCleanup)(void); 220 221 222 // This callback provides Annex B formatted elementary stream data to the 223 // decoder. If the decoder is unable to process the submitted data for some reason, 224 // it must return DR_NEED_IDR to generate a keyframe. 225 #define DR_OK 0 226 #define DR_NEED_IDR -1 227 typedef int(*DecoderRendererSubmitDecodeUnit)(PDECODE_UNIT decodeUnit); 228 229 typedef struct _DECODER_RENDERER_CALLBACKS { 230 DecoderRendererSetup setup; 231 DecoderRendererStart start; 232 DecoderRendererStop stop; 233 DecoderRendererCleanup cleanup; 234 DecoderRendererSubmitDecodeUnit submitDecodeUnit; 235 int capabilities; 236 } DECODER_RENDERER_CALLBACKS, *PDECODER_RENDERER_CALLBACKS; 237 238 // Use this function to zero the video callbacks when allocated on the stack or heap 239 void LiInitializeVideoCallbacks(PDECODER_RENDERER_CALLBACKS drCallbacks); 240 241 // This structure provides the Opus multistream decoder parameters required to successfully 242 // decode the audio stream being sent from the computer. See opus_multistream_decoder_init docs 243 // for details about these fields. 244 // 245 // The supplied mapping array is indexed according to the following output channel order: 246 // 0 - Front Left 247 // 1 - Front Right 248 // 2 - Center 249 // 3 - LFE 250 // 4 - Surround Left 251 // 5 - Surround Right 252 // 253 // If the mapping order does not match the channel order of the audio renderer, you may swap 254 // the values in the mismatched indices until the mapping array matches the desired channel order. 255 typedef struct _OPUS_MULTISTREAM_CONFIGURATION { 256 int sampleRate; 257 int channelCount; 258 int streams; 259 int coupledStreams; 260 int samplesPerFrame; 261 unsigned char mapping[6]; 262 } OPUS_MULTISTREAM_CONFIGURATION, *POPUS_MULTISTREAM_CONFIGURATION; 263 264 // This callback initializes the audio renderer. The audio configuration parameter 265 // provides the negotiated audio configuration. This may differ from the one 266 // specified in the stream configuration. Returns 0 on success, non-zero on failure. 267 typedef int(*AudioRendererInit)(int audioConfiguration, const POPUS_MULTISTREAM_CONFIGURATION opusConfig, void* context, int arFlags); 268 269 // This callback notifies the decoder that the stream is starting. No audio can be submitted before this callback returns. 270 typedef void(*AudioRendererStart)(void); 271 272 // This callback notifies the decoder that the stream is stopping. Audio samples may still be submitted but they may be safely discarded. 273 typedef void(*AudioRendererStop)(void); 274 275 // This callback performs the final teardown of the audio decoder. No additional audio will be submitted when this callback is invoked. 276 typedef void(*AudioRendererCleanup)(void); 277 278 // This callback provides Opus audio data to be decoded and played. sampleLength is in bytes. 279 typedef void(*AudioRendererDecodeAndPlaySample)(char* sampleData, int sampleLength); 280 281 typedef struct _AUDIO_RENDERER_CALLBACKS { 282 AudioRendererInit init; 283 AudioRendererStart start; 284 AudioRendererStop stop; 285 AudioRendererCleanup cleanup; 286 AudioRendererDecodeAndPlaySample decodeAndPlaySample; 287 int capabilities; 288 } AUDIO_RENDERER_CALLBACKS, *PAUDIO_RENDERER_CALLBACKS; 289 290 // Use this function to zero the audio callbacks when allocated on the stack or heap 291 void LiInitializeAudioCallbacks(PAUDIO_RENDERER_CALLBACKS arCallbacks); 292 293 // Subject to change in future releases 294 // Use LiGetStageName() for stable stage names 295 #define STAGE_NONE 0 296 #define STAGE_PLATFORM_INIT 1 297 #define STAGE_NAME_RESOLUTION 2 298 #define STAGE_RTSP_HANDSHAKE 3 299 #define STAGE_CONTROL_STREAM_INIT 4 300 #define STAGE_VIDEO_STREAM_INIT 5 301 #define STAGE_AUDIO_STREAM_INIT 6 302 #define STAGE_INPUT_STREAM_INIT 7 303 #define STAGE_CONTROL_STREAM_START 8 304 #define STAGE_VIDEO_STREAM_START 9 305 #define STAGE_AUDIO_STREAM_START 10 306 #define STAGE_INPUT_STREAM_START 11 307 #define STAGE_MAX 12 308 309 // This callback is invoked to indicate that a stage of initialization is about to begin 310 typedef void(*ConnListenerStageStarting)(int stage); 311 312 // This callback is invoked to indicate that a stage of initialization has completed 313 typedef void(*ConnListenerStageComplete)(int stage); 314 315 // This callback is invoked to indicate that a stage of initialization has failed. 316 // ConnListenerConnectionTerminated() will not be invoked because the connection was 317 // not yet fully established. LiInterruptConnection() and LiStopConnection() may 318 // result in this callback being invoked, but it is not guaranteed. 319 typedef void(*ConnListenerStageFailed)(int stage, int errorCode); 320 321 // This callback is invoked after the connection is successfully established 322 typedef void(*ConnListenerConnectionStarted)(void); 323 324 // This callback is invoked when a connection is terminated after establishment. 325 // The errorCode will be 0 if the termination was reported to be intentional 326 // from the server (for example, the user closed the game). If errorCode is 327 // non-zero, it means the termination was probably unexpected (loss of network, 328 // crash, or similar conditions). This will not be invoked as a result of a call 329 // to LiStopConnection() or LiInterruptConnection(). 330 typedef void(*ConnListenerConnectionTerminated)(int errorCode); 331 332 // This callback is invoked to log debug message 333 typedef void(*ConnListenerLogMessage)(const char* format, ...); 334 335 // This callback is invoked to rumble a gamepad. The rumble effect values 336 // set in this callback are expected to persist until a future call sets a 337 // different haptic effect or turns off the motors by passing 0 for both 338 // motors. It is possible to receive rumble events for gamepads that aren't 339 // physically present, so your callback should handle this possibility. 340 typedef void(*ConnListenerRumble)(unsigned short controllerNumber, unsigned short lowFreqMotor, unsigned short highFreqMotor); 341 342 // This callback is used to notify the client of a connection status change. 343 // Consider displaying an overlay for the user to notify them why their stream 344 // is not performing as expected. 345 #define CONN_STATUS_OKAY 0 346 #define CONN_STATUS_POOR 1 347 typedef void(*ConnListenerConnectionStatusUpdate)(int connectionStatus); 348 349 typedef struct _CONNECTION_LISTENER_CALLBACKS { 350 ConnListenerStageStarting stageStarting; 351 ConnListenerStageComplete stageComplete; 352 ConnListenerStageFailed stageFailed; 353 ConnListenerConnectionStarted connectionStarted; 354 ConnListenerConnectionTerminated connectionTerminated; 355 ConnListenerLogMessage logMessage; 356 ConnListenerRumble rumble; 357 ConnListenerConnectionStatusUpdate connectionStatusUpdate; 358 } CONNECTION_LISTENER_CALLBACKS, *PCONNECTION_LISTENER_CALLBACKS; 359 360 // Use this function to zero the connection callbacks when allocated on the stack or heap 361 void LiInitializeConnectionCallbacks(PCONNECTION_LISTENER_CALLBACKS clCallbacks); 362 363 364 typedef struct _SERVER_INFORMATION { 365 // Server host name or IP address in text form 366 const char* address; 367 368 // Text inside 'appversion' tag in /serverinfo 369 const char* serverInfoAppVersion; 370 371 // Text inside 'GfeVersion' tag in /serverinfo (if present) 372 const char* serverInfoGfeVersion; 373 } SERVER_INFORMATION, *PSERVER_INFORMATION; 374 375 // Use this function to zero the server information when allocated on the stack or heap 376 void LiInitializeServerInformation(PSERVER_INFORMATION serverInfo); 377 378 // This function begins streaming. 379 // 380 // Callbacks are all optional. Pass NULL for individual callbacks within each struct or pass NULL for the entire struct 381 // to use the defaults for all callbacks. 382 // 383 // This function is not thread-safe. 384 // 385 int LiStartConnection(PSERVER_INFORMATION serverInfo, PSTREAM_CONFIGURATION streamConfig, PCONNECTION_LISTENER_CALLBACKS clCallbacks, 386 PDECODER_RENDERER_CALLBACKS drCallbacks, PAUDIO_RENDERER_CALLBACKS arCallbacks, void* renderContext, int drFlags, 387 void* audioContext, int arFlags); 388 389 // This function stops streaming. This function is not thread-safe. 390 void LiStopConnection(void); 391 392 // This function interrupts a pending LiStartConnection() call. This interruption happens asynchronously 393 // so it is not safe to start another connection before the first LiStartConnection() call returns. 394 void LiInterruptConnection(void); 395 396 // Use to get a user-visible string to display initialization progress 397 // from the integer passed to the ConnListenerStageXXX callbacks 398 const char* LiGetStageName(int stage); 399 400 // This function queues a mouse move event to be sent to the remote server. 401 int LiSendMouseMoveEvent(short deltaX, short deltaY); 402 403 // This function queues a mouse button event to be sent to the remote server. 404 #define BUTTON_ACTION_PRESS 0x07 405 #define BUTTON_ACTION_RELEASE 0x08 406 #define BUTTON_LEFT 0x01 407 #define BUTTON_MIDDLE 0x02 408 #define BUTTON_RIGHT 0x03 409 #define BUTTON_X1 0x04 410 #define BUTTON_X2 0x05 411 int LiSendMouseButtonEvent(char action, int button); 412 413 // This function queues a keyboard event to be sent to the remote server. 414 #define KEY_ACTION_DOWN 0x03 415 #define KEY_ACTION_UP 0x04 416 #define MODIFIER_SHIFT 0x01 417 #define MODIFIER_CTRL 0x02 418 #define MODIFIER_ALT 0x04 419 #define MODIFIER_META 0x08 420 int LiSendKeyboardEvent(short keyCode, char keyAction, char modifiers); 421 422 // Button flags 423 #define A_FLAG 0x1000 424 #define B_FLAG 0x2000 425 #define X_FLAG 0x4000 426 #define Y_FLAG 0x8000 427 #define UP_FLAG 0x0001 428 #define DOWN_FLAG 0x0002 429 #define LEFT_FLAG 0x0004 430 #define RIGHT_FLAG 0x0008 431 #define LB_FLAG 0x0100 432 #define RB_FLAG 0x0200 433 #define PLAY_FLAG 0x0010 434 #define BACK_FLAG 0x0020 435 #define LS_CLK_FLAG 0x0040 436 #define RS_CLK_FLAG 0x0080 437 #define SPECIAL_FLAG 0x0400 438 439 // This function queues a controller event to be sent to the remote server. It will 440 // be seen by the computer as the first controller. 441 int LiSendControllerEvent(short buttonFlags, unsigned char leftTrigger, unsigned char rightTrigger, 442 short leftStickX, short leftStickY, short rightStickX, short rightStickY); 443 444 // This function queues a controller event to be sent to the remote server. The controllerNumber 445 // parameter is a zero-based index of which controller this event corresponds to. The largest legal 446 // controller number is 3 (for a total of 4 controllers, the Xinput maximum). On generation 3 servers (GFE 2.1.x), 447 // these will be sent as controller 0 regardless of the controllerNumber parameter. The activeGamepadMask 448 // parameter is a bitfield with bits set for each controller present up to a maximum of 4 (0xF). 449 int LiSendMultiControllerEvent(short controllerNumber, short activeGamepadMask, 450 short buttonFlags, unsigned char leftTrigger, unsigned char rightTrigger, 451 short leftStickX, short leftStickY, short rightStickX, short rightStickY); 452 453 // This function queues a vertical scroll event to the remote server. 454 // The number of "clicks" is multiplied by WHEEL_DELTA (120) before 455 // being sent to the PC. 456 int LiSendScrollEvent(signed char scrollClicks); 457 458 // This function queues a vertical scroll event to the remote server. 459 // Unlike LiSendScrollEvent(), this function can send wheel events 460 // smaller than 120 units for devices that support "high resolution" 461 // scrolling (Apple Trackpads, Microsoft Precision Touchpads, etc.). 462 int LiSendHighResScrollEvent(short scrollAmount); 463 464 // This function returns a time in milliseconds with an implementation-defined epoch. 465 // NOTE: This will be populated from gettimeofday() if !HAVE_CLOCK_GETTIME and 466 // populated from clock_gettime(CLOCK_MONOTONIC) if HAVE_CLOCK_GETTIME. 467 uint64_t LiGetMillis(void); 468 469 // This is a simplistic STUN function that can assist clients in getting the WAN address 470 // for machines they find using mDNS over IPv4. This can be used to pre-populate the external 471 // address for streaming after GFE stopped sending it a while back. wanAddr is returned in 472 // network byte order. 473 int LiFindExternalAddressIP4(const char* stunServer, unsigned short stunPort, unsigned int* wanAddr); 474 475 // Returns the number of queued video frames ready for delivery. Only relevant 476 // if CAPABILITY_DIRECT_SUBMIT is not set for the video renderer. 477 int LiGetPendingVideoFrames(void); 478 479 // Returns the number of queued audio frames ready for delivery. Only relevant 480 // if CAPABILITY_DIRECT_SUBMIT is not set for the audio renderer. For most uses, 481 // LiGetPendingAudioDuration() is probably a better option than this function. 482 int LiGetPendingAudioFrames(void); 483 484 // Similar to LiGetPendingAudioFrames() except it returns the pending audio in 485 // milliseconds rather than frames, which allows callers to be agnostic of the 486 // negotiated audio frame duration. 487 int LiGetPendingAudioDuration(void); 488 489 #ifdef __cplusplus 490 } 491 #endif 492